discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Thread Safety


From: Krzysztof Kamieniecki
Subject: Re: [Discuss-gnuradio] Thread Safety
Date: Mon, 28 Feb 2005 02:09:02 -0500
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.5) Gecko/20041217



Eric Blossom wrote:

On Mon, Feb 28, 2005 at 12:14:55AM -0500, Krzysztof Kamieniecki wrote:

The two projects that I am working on right now require some repeated manipulation of various blocks in the flow graph while data is being processed. I would prefer not to have to stop the flow graph to change values. I have some ideas about how to do this but I was wondering if there is a preferred light-weight method.
--
Krzysztof Kamieniecki
callsign:KB1KLB
mailto:address@hidden


Hi Krys,

There are a couple of techniques that should work.  One of them works
now, the other is a bit down the line.

The one that works now is based on this observation:

  There will never be more than a single thread executing the work
  method for a given instance at any time.

Depending on what kind of a parameter you're trying to change, it may
work just to have the set_foo method set a value and a flag that is
checked at the top of the work method.  To have it be rock solid, you
should probably use a mutex to protect the set/get.  See
omnithread.h and use omni_mutex to create one.  See also
omni_mutex_lock for a handy helper.  Under 2.6 (NPTL) the non-blocking
path through a mutex is really quite fast.  It's all in user space.

I was thinking about something slightly more complicated, with a set of shadow data members that would be protected by the mutex, and copied to the normal data members at the top of the work method when the flag is triggered. That way the mutex would only be used if the flag is set. Something like this.

//called by external thread i.e. Python
void
freq_set(float value)
{
  //lock critical section
  Lock lock(d_shadow_crit_sec);

  //set shadow data
  d_freq_shadow = value;

  //signal flow graph thread
  d_shadow_flag = true;
}


//called by flow_graph thread

void
update_values()
{
  //lock critical section
  Lock lock(d_shadow_crit_sec);

  //clear new data flag
  d_shadow_flag = false;

  //read shadow data
  d_freq = d_freq_shadow;
}


int
work(...)
{
  if(d_shadow_flag)
    update_values();
  ...
}

The second way is currently under development.  This is a message
based interface that uses thread safe message queues and messages.
You would just send a message to your block with the relevant
arguments (change parameter X to Y).  The message would then be
dispatched and acted on in a thread safe manner.  The idea is that the
queues and message ought to able to be used from C++ and python, and
if used from C++ don't incur any python overhead.  I envision adding a
gr_msg_queue to each block, as well as a message receiver method.  The
scheduler would dequeue messages and call the message receiver method
on the block's behalf in a way the was consistent with ensuring
thread-safety.

> Eric

I had noticed the development in CVS. Having a gr_msg_queue in each block may cause some problems for me down the line unless there is a way to guarantee that the messages are processed in a specific order, but it's something that I could work around.

Do or could the messages have a timestamp indicating when they should be 
performed?


--
Krzysztof Kamieniecki
callsign:KB1KLB
mailto:address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]