00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CSQUEUE_H__
00022 #define __CSQUEUE_H__
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define DECLARE_TYPED_QUEUE( NAME, TYPE, DEF_QUEUE_LENGTH ) \
00033 class NAME \
00034 { \
00035 volatile TYPE **Content; \
00036 volatile int qHead, qTail; \
00037 volatile int Length; \
00038 volatile int Spinlock; \
00039 public: \
00040 NAME ( int len = DEF_QUEUE_LENGTH ); \
00041 virtual ~NAME(); \
00042 void Put( TYPE *item ); \
00043 TYPE *Get(); \
00044 void Clear(); \
00045 bool IsEmpty() { return qHead == qTail; } \
00046 private: \
00047 void Resize( int length ); \
00048 inline void Lock() \
00049 { while (Spinlock) {} Spinlock++; } \
00050 inline void Unlock() \
00051 { Spinlock--; } \
00052 };
00053
00054
00055
00056 #define DECLARE_TYPED_QUEUE_BASE( NAME, TYPE, DEF_QUEUE_LENGTH ) \
00057 NAME::NAME ( int len ) : Content(NULL), Length(0), Spinlock(0) \
00058 { \
00059 qHead = qTail = 0; \
00060 Resize( len ); \
00061 } \
00062 NAME::~NAME () \
00063 { \
00064 Clear(); \
00065 if ( Content ) \
00066 delete[] Content; \
00067 } \
00068 void NAME::Put( TYPE *item ) \
00069 { \
00070 again: \
00071 Lock(); \
00072 int newHead = qHead + 1; \
00073 if ( newHead == Length ) \
00074 newHead = 0; \
00075 if ( newHead == qTail ) \
00076 { \
00077 Unlock(); \
00078 Resize( Length + 2 ); \
00079 goto again; \
00080 } \
00081 Content [ qHead ] = item; \
00082 qHead = newHead; \
00083 Unlock(); \
00084 } \
00085 TYPE *NAME::Get() \
00086 { \
00087 if (IsEmpty()) \
00088 return NULL; \
00089 else \
00090 { \
00091 Lock(); \
00092 int oldTail = qTail++; \
00093 if ( qTail == Length ) \
00094 qTail = 0; \
00095 TYPE *item = ( TYPE * ) Content [ oldTail ]; \
00096 Unlock(); \
00097 return item; \
00098 } \
00099 } \
00100 void NAME::Clear() \
00101 { \
00102 TYPE *item; \
00103 while (( item = Get()) != NULL ) \
00104 { delete item; } \
00105 } \
00106 void NAME::Resize ( int len ) \
00107 { \
00108 if ( len <= 0 ) \
00109 len = DEF_QUEUE_LENGTH; \
00110 if ( len == Length ) \
00111 return; \
00112 Lock(); \
00113 volatile TYPE **oldQueue = Content; \
00114 Content = ( volatile TYPE **) new TYPE *[len]; \
00115 int oldHead = qHead, oldTail = qTail; \
00116 qHead = qTail = 0; \
00117 int oldLength = Length; \
00118 Length = len; \
00119 if ( oldQueue ) \
00120 { while (( oldTail != oldHead ) && ( qHead < Length - 1 )) \
00121 { Content [ qHead++ ] = oldQueue [ oldTail++ ]; \
00122 if ( oldTail == oldLength ) \
00123 oldTail = 0; \
00124 } \
00125 } \
00126 delete[] oldQueue; \
00127 Unlock(); \
00128 }
00129
00130 #endif // __CSQUEUE_H__
00131