queue.h (1281B)
1 #pragma once 2 3 #include "platform_thread.h" 4 5 template< typename T > 6 struct BlockingQueue { 7 virtual void enqueue( const T & x ) = 0; 8 virtual T * dequeue_acquire() = 0; 9 virtual void dequeue_release() = 0; 10 11 T dequeue() { 12 T t = *dequeue_acquire(); 13 dequeue_release(); 14 return t; 15 } 16 17 }; 18 19 const int ATTEMPTS_BEFORE_YIELD = 128; 20 21 template< typename T > 22 struct NonblockingQueue { 23 virtual bool enqueue( const T & x ) = 0; 24 virtual T * dequeue_acquire() = 0; 25 virtual void dequeue_release() = 0; 26 27 void enqueue_spin( const T & x ) { 28 int attempt = 0; 29 while( !enqueue( x ) ) { 30 if( attempt < ATTEMPTS_BEFORE_YIELD ) { 31 attempt++; 32 } 33 else { 34 thread_yield(); 35 } 36 } 37 } 38 39 bool dequeue( T * x ) { 40 T * t = dequeue_acquire(); 41 if( t == NULL ) return false; 42 *x = *t; 43 dequeue_release(); 44 return true; 45 } 46 }; 47 48 template< typename T > 49 class NonblockingQueueReader { 50 public: 51 NonblockingQueueReader( NonblockingQueue< T > * Q ) { 52 q = Q; 53 } 54 55 bool dequeue( T * x ) { 56 return q->dequeue( x ); 57 } 58 59 private: 60 NonblockingQueue< T > * q; 61 }; 62 63 template< typename T > 64 struct NonblockingQueueWriter { 65 public: 66 NonblockingQueueWriter( NonblockingQueue< T > * Q ) { 67 q = Q; 68 } 69 70 bool enqueue( const T & x ) { 71 return q->dequeue( x ); 72 } 73 74 private: 75 NonblockingQueue< T > * q; 76 };