Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
comparison BlockingQueue.c @ 4:8abcca1590b8
Tested and working on full VMS test
| author | Me |
|---|---|
| date | Wed, 30 Jun 2010 14:34:56 -0700 |
| parents | 81f6687d52d1 |
| children | 174a7c2ca340 |
comparison
equal
deleted
inserted
replaced
| 1:949ad36d2c6c | 2:e022be73344f |
|---|---|
| 20 #define SPINLOCK_TRIES 100000 | 20 #define SPINLOCK_TRIES 100000 |
| 21 | 21 |
| 22 //=========================================================================== | 22 //=========================================================================== |
| 23 //Normal pthread Q | 23 //Normal pthread Q |
| 24 | 24 |
| 25 QueueStruc* makeQ() | 25 PThdQueueStruc* makePThdQ() |
| 26 { | 26 { |
| 27 QueueStruc* retQ; | 27 PThdQueueStruc* retQ; |
| 28 int status; | 28 int status; |
| 29 retQ = (QueueStruc *) malloc( sizeof( QueueStruc ) ); | 29 retQ = (PThdQueueStruc *) malloc( sizeof( PThdQueueStruc ) ); |
| 30 | 30 |
| 31 | 31 |
| 32 status = pthread_mutex_init( &retQ->mutex_t, NULL); | 32 status = pthread_mutex_init( &retQ->mutex_t, NULL); |
| 33 if (status < 0) | 33 if (status < 0) |
| 34 { | 34 { |
| 59 retQ -> w_empty = retQ -> w_full = 0; | 59 retQ -> w_empty = retQ -> w_full = 0; |
| 60 | 60 |
| 61 return retQ; | 61 return retQ; |
| 62 } | 62 } |
| 63 | 63 |
| 64 void * readQ( QueueStruc *Q ) | 64 void * readPThdQ( PThdQueueStruc *Q ) |
| 65 { void *ret; | 65 { void *ret; |
| 66 int status, wt; | 66 int status, wt; |
| 67 pthread_mutex_lock( &Q->mutex_t ); | 67 pthread_mutex_lock( &Q->mutex_t ); |
| 68 { | 68 { |
| 69 while( Q -> count == 0 ) | 69 while( Q -> count == 0 ) |
| 87 if (wt) pthread_cond_signal( &Q->cond_w_t ); | 87 if (wt) pthread_cond_signal( &Q->cond_w_t ); |
| 88 | 88 |
| 89 return( ret ); | 89 return( ret ); |
| 90 } | 90 } |
| 91 | 91 |
| 92 void writeQ( void * in, QueueStruc* Q ) | 92 void writePThdQ( void * in, PThdQueueStruc* Q ) |
| 93 { | 93 { |
| 94 int status, wt; | 94 int status, wt; |
| 95 pthread_mutex_lock( &Q->mutex_t ); | 95 pthread_mutex_lock( &Q->mutex_t ); |
| 96 { | 96 { |
| 97 while( Q->count >= 1024 ) | 97 while( Q->count >= 1024 ) |
| 150 void **startOfData = Q->startOfData; | 150 void **startOfData = Q->startOfData; |
| 151 void **endOfData = Q->endOfData; | 151 void **endOfData = Q->endOfData; |
| 152 | 152 |
| 153 int success = FALSE; | 153 int success = FALSE; |
| 154 | 154 |
| 155 while( !success ) | 155 while( TRUE ) |
| 156 { success = | 156 { success = |
| 157 __sync_bool_compare_and_swap( &(Q->extractLock), UNLOCKED, LOCKED ); | 157 __sync_bool_compare_and_swap( &(Q->extractLock), UNLOCKED, LOCKED ); |
| 158 //NOTE: checked assy, and it does lock correctly.. | |
| 158 if( success ) | 159 if( success ) |
| 159 { | 160 { |
| 160 void **insertPos = Q->insertPos; | 161 void **insertPos = Q->insertPos; |
| 161 void **extractPos = Q->extractPos; | 162 void **extractPos = Q->extractPos; |
| 162 | 163 |
| 193 void **startOfData = Q->startOfData; | 194 void **startOfData = Q->startOfData; |
| 194 void **endOfData = Q->endOfData; | 195 void **endOfData = Q->endOfData; |
| 195 | 196 |
| 196 int success = FALSE; | 197 int success = FALSE; |
| 197 | 198 |
| 198 while( !success ) | 199 while( TRUE ) |
| 199 { success = | 200 { success = |
| 200 __sync_bool_compare_and_swap( &(Q->insertLock), UNLOCKED, LOCKED ); | 201 __sync_bool_compare_and_swap( &(Q->insertLock), UNLOCKED, LOCKED ); |
| 201 if( success ) | 202 if( success ) |
| 202 { | 203 { |
| 203 void **insertPos = Q->insertPos; | 204 void **insertPos = Q->insertPos; |
| 206 //check if room to insert.. can't use a count variable | 207 //check if room to insert.. can't use a count variable |
| 207 // 'cause both insertor Thd and extractor Thd would write it | 208 // 'cause both insertor Thd and extractor Thd would write it |
| 208 if( extractPos - insertPos != 1 && | 209 if( extractPos - insertPos != 1 && |
| 209 !(insertPos == endOfData && extractPos == startOfData)) | 210 !(insertPos == endOfData && extractPos == startOfData)) |
| 210 { *(Q->insertPos) = in; //insert before move | 211 { *(Q->insertPos) = in; //insert before move |
| 211 if( insertPos == endOfData ) //write new pos exactly once, correctly | 212 if( insertPos == endOfData ) |
| 212 { Q->insertPos = startOfData; | 213 { Q->insertPos = startOfData; |
| 213 } | 214 } |
| 214 else | 215 else |
| 215 { Q->insertPos++; | 216 { Q->insertPos++; |
| 216 } | 217 } |
