Clarification of lock() and unlock() in Dynamic Flow-Graph Reconfiguration

Hello All,

I am having some difficulties implementing a cognitive receiver program
that
involves dynamically reconfiguring the USRP between sensing the spectrum
and
acting as a receiver based on the results of the spectrum sensing. The
program I am developing is mostly based on the usrp_spectrum_sense.py
for
the sensing part and benchmark_rx.py for the receiving part. The
specifications for our platform are at the end of the e-mail.

The general logic of my program is to run one flow graph which is
connected
in the same way as in the usrp_spectrum_sense program. After obtaining
the
results from the spectrum sensing, I wish to reconfigure the flow graph
to
connect the USRP to receive and demodulate a user-defined number of
packets
just as in the benchmark_rx program whenever we deem the spectrum to be
free, after which we could revert to the configuration in the first flow
graph and continue until the program is terminated.

Here is some code of the most relevant parts of the program:

#################################################################

CODE :

class my_top_block():
def init(self, frame_count):

self.tb = gr.top_block()
self.u =
usrp.source_c(fusb_block_size=options.fusb_block_size,

fusb_nblocks=options.fusb_nblocks)

self.tb.connect(self.u, s2v, fft, c2mag, stats)

def set_freq(self, target_freq):
return self.u.tune(0, self.subdev, target_freq)

def set_next_freq(self):

      target_freq = self.next_freq
      min_center_freq = self.min_center_freq
      max_center_freq = self.max_center_freq
      power_norm = self.power_norm
      frame_count = self.frame_count

      if (target_freq == self.prev_freq + self.freq_step):
       main_loop(self)
      .....

     if self.next_freq > self.max_center_freq:
         self.next_freq = self.min_center_freq
         self.prev_freq = self.min_center_freq - self.freq_step
         self.finished_sensing = True

    """
    Make a decision on reception mode or sleep mode based on the 

value
of avg_frame_power
“”"

    if target_freq == self.min_center_freq and self.finished_sensing 

==
True:

        print "The average power for previous frame %d :" 

%frame_count,
self.avg_frame_power
frame_count += 1
self.finished_sensing = False

        if (self.avg_frame_power > 50):
          print "Sensing Mode : USRP in Sleep"
          self.stats.sleep_mode(True,1000)   # THIS IS OUR 

MODIFICATION
WE USE IN gr_bin_statistics_f.cc
#
IN
PLACE OF USING time.sleep(); WE KNOW THIS WORKS
#
WITH NO PROBLEMS

        else:
          print "Receiver Mode : USRP to Switch to Receiving Packets 

"
self.tb.stop()
self.tb.lock() # THIS IS
WHERE WE WANT TO RECONFIGURE TO RECEIVE
#
PACKETS

          self.rx_path =

receive_path(self.tb,self.u,self.demodulator,self.options,self.samples_per_symbol,

self.decim,self.rx_subdev_spec,self.rx_freq,self.subdev)

         self.tb.unlock()     # THIS IS WHERE THE PROGRAM FREEZES

      return target_freq

class receive_path(my_top_block):
def
init(self,tb,u,demodulator,options,samples_per_symbol,decim,rx_subdev_spec,rx_freq,subdev):

self.tb.connect(self.u,self.channel_filter, self.probe)
self.tb.connect(self.channel_filter, self._demodulator)
self.tb.connect(self._demodulator, self.correlator,
self.framer_sink)
#self._watcher = _queue_watcher_thread(self._rcvd_pktq,
rx_callback)

def main_loop(tb):

 .... # THIS IS WHERE WE CALCULATE THE avg_frame_power AND PRINT 

RESULTS
TO OUTPUT FILES

if name == ‘main’:

frame_count = 1
my_tb = my_top_block(frame_count)                # start executing 

flow
graph in another thread…

try:
my_tb.tb.run()


except KeyboardInterrupt:
    pass

#################################################################

Since I have been unable to switch from the sensing path to the
receiving
path with no errors, I haven’t begun to deal
with switching back from the receiving path to the sensing path yet. I
know
that the program is freezing at the unlock() statement, since I have
debugged the program at execution time line-by-line using the standard
pdb
Python debugger.

From viewing the version 3.2.2 API
documentationhttp://gnuradio.org/doc/doxygen/index.htmlfor the
gr_top_block class, there is a note saying that “the lock() and
unlock() methods should not be called from a flowgraph thread or the
program
will be become deadlocked”. I was wondering if someone could clarify
what
exactly is meant by this statement. I take this to mean that the locking
and
unlocking cannot be performed from within that same instance of the
gr_top_block, or else the unlock() will continually wait for the already
executing thread to stop, which will never happen since this thread is
needed to be run to maintain the initial my_top_block instance. Is this
what
is meant by the documentation for the gr_top_block class? Also, can
anyone
recommend a general method to circumvent this problem if we are doing
things
the wrong way?

Thank you very much for your help.

Setup Specifications: GNU Radio version 3.2.2 running on Ubuntu 9.04,
USRP 1
with RFX2400 daughterboard

Quick Question…
Is there a reason you do not want to use time.sleep(). Just curious?

Hi Venkat,

A couple of things to try:
Try removing the tb.stop() call, lock will stop the flowgraph anyway.
You may need to ‘disconnect’ (essentially undo all the connect calls)
the
path before recreating it. In the first instance try the
disconnect_all() method,
but from memory that had some issues so you could try calling disconnect
for
each block which was connected.

It has been awhile since I battled with the locking system of GNU Radio
so I
am a little rusty, hopefully it helps!

Kieran

On Sun, Aug 29, 2010 at 07:27:21PM -0500, Venkat V. wrote:

in the same way as in the usrp_spectrum_sense program. After obtaining the
#################################################################

CODE :

        else:
          print "Receiver Mode : USRP to Switch to Receiving Packets "
          self.tb.stop()

Don’t call stop. Just call lock.

Hey,

We have tried just about every different combination of
start,stop,wait,lock, and unlock possible …

Whenever we remove the stop() call, we get an error that we do not
receive
whenever the stop() call is in place. With the stop() call removed, the
program gives us the following error at the unlock() statement:

             *terminate called after throwing an instance of

‘boost::thread_interrupted’*
Aborted

This error does not come up if we remove the stop() statement, but the
program freezes at the unlock instead. Any clues to solving the boost
error
or what this actually means??

From viewing the version 3.2.2 API
documentationhttp://gnuradio.org/doc/doxygen/index.htmlfor the
gr_top_block class, there is a note saying that “the lock() and
unlock() methods should not be called from a flowgraph thread or the
program
will be become deadlocked”. In my program the lock() and unlock() are
being
called from the same top_block() which is instantiated when the program
is
started. Could this be the cause of freezing once we get to the unlock
statement?

Once again thanks for your help. I was extremely surprised at how
quickly
you guys responded :slight_smile:

A couple of things to try:
Try removing the tb.stop() call, lock will stop the flowgraph anyway.
You may need to ‘disconnect’ (essentially undo all the connect calls) the
path before recreating it. In the first instance try >the disconnect_all()
method, but from memory that had some issues so you could try calling
disconnect for each block which was connected.

Hi,

I am stuck with the exact same problem of locking/unlocking in runtime.
I see that the transmit chain works for some iterations after the
renconfiguration (assuming packets being sent) and thereafter hangs.

Any help will be appreciated.

Thanks!

Venkat V. wrote in post #936951:

Hey,

We have tried just about every different combination of
start,stop,wait,lock, and unlock possible …

Whenever we remove the stop() call, we get an error that we do not
receive
whenever the stop() call is in place. With the stop() call removed, the
program gives us the following error at the unlock() statement:

             *terminate called after throwing an instance of

‘boost::thread_interrupted’*
Aborted

This error does not come up if we remove the stop() statement, but the
program freezes at the unlock instead. Any clues to solving the boost
error
or what this actually means??

From viewing the version 3.2.2 API
documentationhttp://gnuradio.org/doc/doxygen/index.htmlfor the
gr_top_block class, there is a note saying that “the lock() and
unlock() methods should not be called from a flowgraph thread or the
program
will be become deadlocked”. In my program the lock() and unlock() are
being
called from the same top_block() which is instantiated when the program
is
started. Could this be the cause of freezing once we get to the unlock
statement?

Once again thanks for your help. I was extremely surprised at how
quickly
you guys responded :slight_smile:

A couple of things to try:
Try removing the tb.stop() call, lock will stop the flowgraph anyway.
You may need to ‘disconnect’ (essentially undo all the connect calls) the
path before recreating it. In the first instance try >the disconnect_all()
method, but from memory that had some issues so you could try calling
disconnect for each block which was connected.