wait_queue.C
上传用户:shtangtang
上传日期:2007-01-04
资源大小:167k
文件大小:2k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #include "thread.h"
  2. #include "thread_lists.h"
  3. #include "wait_queue.h"
  4. #include "shared.h"
  5. #define OFFS(n)         ((n)%__THREAD_QUEUE_MAX)
  6. wait_queue::wait_queue(int p_id)
  7. {
  8.   w_id = p_id;
  9.   init(attributes::process_shared);
  10. }
  11. wait_queue::wait_queue(attributes::scope p_scope)
  12. {
  13.   w_id = shared_mem::share.create_proj( 0 );
  14.   init(attributes::process_shared);
  15. }
  16. wait_queue::wait_queue()
  17. {
  18.   init(attributes::process_private);
  19. }
  20. wait_queue::~wait_queue()
  21. {
  22.   if ( _wq ) {
  23.     while( !empty() )
  24.       wake_up();
  25.     if ( w_scope == attributes::process_private )
  26.       delete _wq;
  27.     else
  28.       shared_mem::share.dealloc( _wq );
  29.     _wq = 0;
  30.   }
  31. }
  32. void wait_queue::init(attributes::scope p_scope)
  33. {
  34.   if ( w_id == -1 )
  35.     w_scope     = attributes::process_private;
  36.   else
  37.     w_scope     = p_scope;
  38.   if ( w_scope == attributes::process_shared ) {
  39.     _wq         = (storage *)shared_mem::share.alloc( sizeof(storage),w_id );
  40.     assert( _wq != (storage *)-1 );
  41.     if ( _wq->w_magic != 0x212611 ) {
  42.       _wq->top     = 0;
  43.       _wq->bottom  = 0;
  44.       _wq->w_magic = 0x212611;
  45.     }
  46.   } else {
  47.     _wq         = new storage;
  48.     _wq->top    = 0;
  49.     _wq->bottom = 0;
  50.   }
  51. }
  52. bool
  53. wait_queue::empty()
  54. {
  55.   return ( _wq->bottom == _wq->top );
  56. }
  57. void
  58. wait_queue::remove(int p_id)
  59. {
  60.   int pos;
  61.   _wq->w_sync.acquire();
  62.   if ( !empty() ) {
  63.     for( pos = _wq->bottom;pos != OFFS(_wq->top-1);pos = OFFS(pos+1) )
  64.       if ( _wq->pid[pos] == p_id ) {
  65. for( ;_wq->bottom != pos;pos = OFFS(pos-1) )
  66.   _wq->pid[pos] = _wq->pid[OFFS(pos-1)];
  67. _wq->bottom = OFFS(_wq->bottom+1);
  68. break;
  69.       }
  70.   }
  71.   _wq->w_sync.release();
  72. }
  73. void
  74. wait_queue::insert(int p_id)
  75. {
  76.   _wq->w_sync.acquire();
  77.   if ( _wq->bottom == OFFS(_wq->top+1) )
  78.     throw;
  79.   _wq->pid[_wq->top] = p_id;
  80.   _wq->top = OFFS(_wq->top+1);
  81.   _wq->w_sync.release();
  82. }
  83. void
  84. wait_queue::suspend_me()
  85. {
  86.   thread_list::iterator i = thread_list::__threads.locate(getpid());
  87.   if ( i == thread_list::__threads.end() )
  88.     return;
  89.   insert(getpid());
  90.   (*i)->suspend_with_cancelation();
  91.   //__sched_yield();
  92.   _wq->w_sync.acquire();
  93.   //we need to synchronize with the wakeup below.  Maybe __sched.yield()?
  94.   _wq->w_sync.release();
  95. }
  96. void
  97. wait_queue::wake_up()
  98. {
  99.   _wq->w_sync.acquire();
  100.   if ( !empty() ) {
  101.     thread_list::__threads.restart(_wq->pid[_wq->bottom]);
  102.     _wq->bottom = OFFS(_wq->bottom+1);
  103.   }
  104.   _wq->w_sync.release();
  105. }