Changeset 7417

Show
Ignore:
Timestamp:
01/13/08 13:41:11
Author:
michaelld
Message:

Merged OSX fixes for 10.5 (backwards compatible with 10.4 if not
earlier) for USRP legacy fast-usb code from r7358 branch into trunk:

Fixed DEBUG commands in all files.
Fixed flow control between originating and spawned threads.
Fixed WritePipeAsync? buffer write size.
Added in debugging comments to fusb code, to better track async flow.

NOT YET updated for MacOS X 10.5-specific IOKit code, but everything
seems to work just fine as is.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gnuradio/trunk/usrp/host/lib/legacy/circular_buffer.h

    r6152 r7417  
    2727#include <stdexcept> 
    2828 
     29#ifndef DO_DEBUG 
    2930#define DO_DEBUG 0 
     31#endif 
    3032 
    3133#if DO_DEBUG 
     
    8385                    "doWriteBlock = %s, doFullRead = %s\n", d_bufLen_I, 
    8486                    (d_doWriteBlock ? "true" : "false"), 
    85                     (d_doFullRead ? "true" : "false"))); 
     87                    (d_doFullRead ? "true" : "false"));); 
    8688  }; 
    8789 
     
    151153    DEBUG (fprintf (stderr, "enqueue: buf = %X, bufLen = %ld, #av_wr = %ld, " 
    152154                    "#av_rd = %ld.\n", (unsigned int)buf, bufLen_I, 
    153                     d_n_avail_write_I, d_n_avail_read_I)); 
     155                    d_n_avail_write_I, d_n_avail_read_I);); 
    154156    if (bufLen_I > d_bufLen_I) { 
    155157      fprintf (stderr, "cannot add buffer longer (%ld" 
     
    174176      if (d_doWriteBlock) { 
    175177        while (bufLen_I > d_n_avail_write_I) { 
    176           DEBUG (fprintf (stderr, "enqueue: #len > #a, waiting.\n")); 
     178          DEBUG (fprintf (stderr, "enqueue: #len > #a, waiting.\n");); 
    177179          // wait will automatically unlock() the internal mutex 
    178180          d_writeBlock->wait (); 
     
    180182          if (d_doAbort) { 
    181183            d_internal->unlock (); 
    182             DEBUG (fprintf (stderr, "enqueue: #len > #a, aborting.\n")); 
     184            DEBUG (fprintf (stderr, "enqueue: #len > #a, aborting.\n");); 
    183185            return (2); 
    184186          } 
    185           DEBUG (fprintf (stderr, "enqueue: #len > #a, done waiting.\n")); 
     187          DEBUG (fprintf (stderr, "enqueue: #len > #a, done waiting.\n");); 
    186188        } 
    187189      } else { 
    188190        d_n_avail_read_I = d_bufLen_I - bufLen_I; 
    189191        d_n_avail_write_I = bufLen_I; 
    190         DEBUG (fprintf (stderr, "circular_buffer::enqueue: overflow\n")); 
     192        DEBUG (fprintf (stderr, "circular_buffer::enqueue: overflow\n");); 
    191193        retval = -1; 
    192194      } 
     
    234236    DEBUG (fprintf (stderr, "dequeue: buf = %X, *bufLen = %ld, #av_wr = %ld, " 
    235237                    "#av_rd = %ld.\n", (unsigned int)buf, *bufLen_I, 
    236                     d_n_avail_write_I, d_n_avail_read_I)); 
     238                    d_n_avail_write_I, d_n_avail_read_I);); 
    237239    if (!bufLen_I) 
    238240      throw std::runtime_error ("circular_buffer::dequeue(): " 
     
    258260    if (d_doFullRead) { 
    259261      while (d_n_avail_read_I < l_bufLen_I) { 
    260         DEBUG (fprintf (stderr, "dequeue: #a < #len, waiting.\n")); 
     262        DEBUG (fprintf (stderr, "dequeue: #a < #len, waiting.\n");); 
    261263        // wait will automatically unlock() the internal mutex 
    262264        d_readBlock->wait (); 
     
    264266        if (d_doAbort) { 
    265267          d_internal->unlock (); 
    266           DEBUG (fprintf (stderr, "dequeue: #a < #len, aborting.\n")); 
     268          DEBUG (fprintf (stderr, "dequeue: #a < #len, aborting.\n");); 
    267269          return (2); 
    268270        } 
    269         DEBUG (fprintf (stderr, "dequeue: #a < #len, done waiting.\n")); 
     271        DEBUG (fprintf (stderr, "dequeue: #a < #len, done waiting.\n");); 
    270272     } 
    271273    } else { 
    272274      while (d_n_avail_read_I == 0) { 
    273         DEBUG (fprintf (stderr, "dequeue: #a == 0, waiting.\n")); 
     275        DEBUG (fprintf (stderr, "dequeue: #a == 0, waiting.\n");); 
    274276        // wait will automatically unlock() the internal mutex 
    275277        d_readBlock->wait (); 
     
    277279        if (d_doAbort) { 
    278280          d_internal->unlock (); 
    279           DEBUG (fprintf (stderr, "dequeue: #a == 0, aborting.\n")); 
     281          DEBUG (fprintf (stderr, "dequeue: #a == 0, aborting.\n");); 
    280282          return (2); 
    281283        } 
    282         DEBUG (fprintf (stderr, "dequeue: #a == 0, done waiting.\n")); 
     284        DEBUG (fprintf (stderr, "dequeue: #a == 0, done waiting.\n");); 
    283285      } 
    284286    } 
  • gnuradio/trunk/usrp/host/lib/legacy/circular_linked_list.h

    r6152 r7417  
    2828 
    2929#define __INLINE__ inline 
     30 
     31#ifndef DO_DEBUG 
    3032#define DO_DEBUG 0 
     33#endif 
    3134 
    3235#if DO_DEBUG 
     
    169172// find an available node 
    170173    s_node_ptr l_node = d_available;  
    171     DEBUG (fprintf (stderr, "w ")); 
     174    DEBUG (fprintf (stderr, "w ");); 
    172175    while (! l_node) { 
    173       DEBUG (fprintf (stderr, "x\n")); 
     176      DEBUG (fprintf (stderr, "x\n");); 
    174177      // the ioBlock condition will automatically unlock() d_internal 
    175178      d_ioBlock->wait (); 
    176179      // and lock() is here 
    177       DEBUG (fprintf (stderr, "y\n")); 
     180      DEBUG (fprintf (stderr, "y\n");); 
    178181      l_node = d_available; 
    179182    } 
    180183    DEBUG (fprintf (stderr, "::f_n_a_n: #u = %ld, node = %p\n", 
    181                     num_used(), l_node)); 
     184                    num_used(), l_node);); 
    182185// remove this one from the current available list 
    183186    if (num_available () == 1) { 
     
    202205    d_internal->lock (); 
    203206    DEBUG (fprintf (stderr, "::m_n_a: #u = %ld, node = %p\n", 
    204                     num_used(), l_node)); 
     207                    num_used(), l_node);); 
    205208// remove this node from the inUse list 
    206209    if (num_used () == 1) { 
     
    217220    d_n_used--; 
    218221 
    219     DEBUG (fprintf (stderr, "s%ld ", d_n_used)); 
     222    DEBUG (fprintf (stderr, "s%ld ", d_n_used);); 
    220223// signal the condition when new data arrives 
    221224    d_ioBlock->signal (); 
    222     DEBUG (fprintf (stderr, "t ")); 
     225    DEBUG (fprintf (stderr, "t ");); 
    223226 
    224227// unlock the mutex for thread safety 
  • gnuradio/trunk/usrp/host/lib/legacy/fusb_darwin.cc

    r6152 r7417  
    2828// but rather Darwin's pthreads 
    2929#define _USE_OMNI_THREADS_ 
     30#define DO_DEBUG 0 
    3031 
    3132#include <usb.h> 
     
    191192             number, interval, maxPacketSize); 
    192193 
    193 // set global start boolean 
     194  // set global start boolean 
    194195  d_started = true; 
    195196 
    196 // create the run thread, which allows OSX to process I/O separately 
     197  // lock the runBlock mutex, before creating the run thread. 
     198  // this guarantees that we can control execution between these 2 threads 
     199  d_runBlock->mutex ()->lock (); 
     200 
     201  // create the run thread, which allows OSX to process I/O separately 
    197202  d_runThread = new mld_thread (run_thread, this); 
    198203 
    199 // wait until the threads are -really- going 
     204  // wait until the run thread (and possibky read thread) are -really- 
     205  // going; this will unlock the mutex before waiting for a signal () 
    200206  d_runBlock->wait (); 
    201207 
     
    211217{ 
    212218  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg); 
     219 
     220  // lock the run thread running mutex; if ::stop() is called, it will 
     221  // first abort() the pipe then wait for the run thread to finish, 
     222  // via a lock() on this mutex 
    213223  mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning; 
    214224  l_runThreadRunning->lock (); 
     
    216226  mld_mutex_ptr l_readRunning = This->d_readRunning; 
    217227  mld_condition_ptr l_readBlock = This->d_readBlock; 
     228  mld_mutex_ptr l_readBlock_mutex = l_readBlock->mutex (); 
    218229 
    219230  bool l_input_p = This->d_input_p; 
     
    238249 
    239250  if (l_input_p) { 
     251    // lock the readBlock mutex, before creating the read thread. 
     252    // this guarantees that we can control execution between these 2 threads 
     253    l_readBlock_mutex->lock (); 
     254    // create the read thread, which just issues all of the starting 
     255    // async read commands, then returns 
    240256    l_rwThread = new mld_thread (read_thread, arg); 
    241 // wait until the the rwThread is -really- going 
     257    // wait until the the read thread is -really- going; this will 
     258    // unlock the read block mutex before waiting for a signal () 
    242259    l_readBlock->wait (); 
    243260  } 
    244261 
    245 // now signal the run condition to release and finish ::start() 
     262  // now signal the run condition to release and finish ::start(). 
     263 
     264  // lock the runBlock mutex first; this will force waiting until the 
     265  // ->wait() command is issued in ::start() 
     266  mld_mutex_ptr l_run_block_mutex = This->d_runBlock->mutex (); 
     267  l_run_block_mutex->lock (); 
     268 
     269  // now that the lock is in place, signal the parent thread that 
     270  // things are running 
    246271  This->d_runBlock->signal (); 
    247272 
    248 // run the loop 
     273  // release the run_block mutex, just in case 
     274  l_run_block_mutex->unlock (); 
     275 
     276  // run the loop 
    249277  CFRunLoopRun (); 
    250278 
    251279  if (l_input_p) { 
    252 // wait for read_thread () to finish 
     280    // wait for read_thread () to finish, if needed 
    253281    l_readRunning->lock (); 
    254282    l_readRunning->unlock (); 
    255283  } 
    256284 
    257 // remove run loop stuff 
     285  // remove run loop stuff 
    258286  CFRunLoopRemoveSource (CFRunLoopGetCurrent (), 
    259287                         l_cfSource, kCFRunLoopDefaultMode); 
     
    263291             l_input_p ? "read" : "write"); 
    264292 
     293  // release the run thread running mutex 
    265294  l_runThreadRunning->unlock (); 
    266295} 
     
    274303  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg); 
    275304 
     305  // before doing anything else, lock the read running mutex.  this 
     306  // mutex does flow control between this thread and the run_thread 
    276307  mld_mutex_ptr l_readRunning = This->d_readRunning; 
    277308  l_readRunning->lock (); 
    278309 
    279 // signal the read condition from run_thread() to continue 
     310  // signal the read condition from run_thread() to continue 
     311 
     312  // lock the readBlock mutex first; this will force waiting until the 
     313  // ->wait() command is issued in ::run_thread() 
    280314  mld_condition_ptr l_readBlock = This->d_readBlock; 
     315  mld_mutex_ptr l_read_block_mutex = l_readBlock->mutex (); 
     316  l_read_block_mutex->lock (); 
     317 
     318  // now that the lock is in place, signal the parent thread that 
     319  // things are running here 
    281320  l_readBlock->signal (); 
    282321 
     322  // release the run_block mutex, just in case 
     323  l_read_block_mutex->unlock (); 
     324 
     325  // queue up all of the available read requests 
    283326  s_queue_ptr l_queue = This->d_queue; 
    284327  l_queue->iterate_start (); 
     
    292335    fprintf (stderr, "fusb_ephandle_darwin::read_thread: finished.\n"); 
    293336 
     337  // release the read running mutex, to let the parent thread knows 
     338  // that this thread is finished 
    294339  l_readRunning->unlock (); 
    295340} 
     
    298343fusb_ephandle_darwin::read_issue (s_both_ptr l_both) 
    299344{ 
    300   if ((! l_both) || (! d_started)) 
     345  if ((! l_both) || (! d_started)) { 
     346    if (usb_debug > 4) 
     347      fprintf (stderr, "fusb_ephandle_darwin::read_issue: Doing nothing; " 
     348               "l_both is %X; started is %s\n", (unsigned int) l_both, 
     349               d_started ? "TRUE" : "FALSE"); 
    301350    return; 
     351  } 
    302352 
    303353// set the node and buffer from the input "both" 
     
    329379                          d_transferType == kUSBInterrupt ? "" : "TO", 
    330380                          darwin_error_str (result)); 
     381  else if (usb_debug > 4) 
     382    fprintf (stderr, "fusb_ephandle_darwin::read_issue: " 
     383             "Queued %X (%ld Bytes)\n", (unsigned int) l_both, bufLen); 
    331384} 
    332385 
     
    348401             "Expected %ld bytes; read %ld.\n", 
    349402             l_i_size, l_size); 
     403  else if (usb_debug > 4) 
     404    fprintf (stderr, "fusb_ephandle_darwin::read_completed: " 
     405             "Read %X (%ld bytes)\n", 
     406             (unsigned int) l_both, l_size); 
    350407 
    351408// add this read to the transfer buffer 
     
    379436  UInt32 l_nbytes = (UInt32) nbytes; 
    380437 
    381   if (! d_started) return (0); 
     438  if (! d_started) { 
     439    if (usb_debug) 
     440      fprintf (stderr, "fusb_ephandle_darwin::write: Not yet started.\n"); 
     441 
     442    return (0); 
     443  } 
    382444 
    383445  while (l_nbytes != 0) { 
     
    401463/* This is an interrupt pipe ... can't specify a timeout. */ 
    402464      result = d_interface->WritePipeAsync 
    403         (d_interfaceRef, d_pipeRef, v_buffer, l_nbytes, 
     465        (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes, 
    404466         (IOAsyncCallback1) write_completed, (void*) l_both); 
    405467    else 
    406468      result = d_interface->WritePipeAsyncTO 
    407         (d_interfaceRef, d_pipeRef, v_buffer, l_nbytes, 0, USB_TIMEOUT, 
     469        (d_interfaceRef, d_pipeRef, v_buffer, t_nbytes, 0, USB_TIMEOUT, 
    408470         (IOAsyncCallback1) write_completed, (void*) l_both); 
    409471 
     
    414476                     d_transferType == kUSBInterrupt ? "" : "TO", 
    415477                     darwin_error_str (result)); 
     478    else if (usb_debug > 4) { 
     479      fprintf (stderr, "fusb_ephandle_darwin::write_thread: " 
     480               "Queued %X (%ld Bytes)\n", (unsigned int) l_both, t_nbytes); 
     481    } 
    416482    l_nbytes -= t_nbytes; 
    417483  } 
     
    437503             "Expected %ld bytes written; wrote %ld.\n", 
    438504             l_i_size, l_size); 
     505  else if (usb_debug > 4) 
     506    fprintf (stderr, "fusb_ephandle_darwin::write_completed: " 
     507             "Wrote %X (%ld Bytes)\n", (unsigned int) l_both, l_size); 
    439508 
    440509// set buffer's # data to 0 
  • gnuradio/trunk/usrp/host/lib/legacy/mld_threads.h

    r6152 r7417  
    3838 
    3939#define __INLINE__ inline 
     40 
     41#ifndef DO_DEBUG 
    4042#define DO_DEBUG 0 
     43#endif 
    4144 
    4245#if DO_DEBUG 
     
    183186 
    184187  __INLINE__ void signal () { 
    185     DEBUG (fprintf (stderr, "a ")); 
     188    DEBUG (fprintf (stderr, "a ");); 
    186189 
    187190#ifdef _USE_OMNI_THREADS_ 
     
    194197    } 
    195198#endif 
    196     DEBUG (fprintf (stderr, "b ")); 
     199    DEBUG (fprintf (stderr, "b ");); 
    197200  }; 
    198201 
    199202  __INLINE__ void wait () { 
    200     DEBUG (fprintf (stderr, "c ")); 
     203    DEBUG (fprintf (stderr, "c ");); 
    201204#ifdef _USE_OMNI_THREADS_ 
    202205    d_condition->wait (); 
     
    208211    } 
    209212#endif 
    210     DEBUG (printf (stderr, "d ")); 
     213    DEBUG (fprintf (stderr, "d ");); 
    211214  }; 
    212215};