Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
comparison BlockingQueue.c @ 7:08f0b4da7610
Works with pin2core.. not sure changes made..
| author | Me |
|---|---|
| date | Wed, 01 Sep 2010 09:16:24 -0700 |
| parents | 174a7c2ca340 |
| children | 62326cc8e6f4 53c614b781ce |
comparison
equal
deleted
inserted
replaced
| 3:084cb48da029 | 4:0686b20358ef |
|---|---|
| 134 { void *out = 0; | 134 { void *out = 0; |
| 135 int tries = 0; | 135 int tries = 0; |
| 136 void **startOfData = Q->startOfData; | 136 void **startOfData = Q->startOfData; |
| 137 void **endOfData = Q->endOfData; | 137 void **endOfData = Q->endOfData; |
| 138 | 138 |
| 139 int success = FALSE; | 139 int gotLock = FALSE; |
| 140 | 140 |
| 141 while( TRUE ) | 141 while( TRUE ) |
| 142 { success = | 142 { //this intrinsic returns true if the lock held "UNLOCKED", in which |
| 143 // case it now holds "LOCKED" -- if it already held "LOCKED", then | |
| 144 // gotLock is FALSE | |
| 145 gotLock = | |
| 143 __sync_bool_compare_and_swap( &(Q->extractLock), UNLOCKED, LOCKED ); | 146 __sync_bool_compare_and_swap( &(Q->extractLock), UNLOCKED, LOCKED ); |
| 144 //NOTE: checked assy, and it does lock correctly.. | 147 //NOTE: checked assy, and it does lock correctly.. |
| 145 if( success ) | 148 if( gotLock ) |
| 146 { | 149 { |
| 147 void **insertPos = Q->insertPos; | 150 void **insertPos = Q->insertPos; |
| 148 void **extractPos = Q->extractPos; | 151 void **extractPos = Q->extractPos; |
| 149 | 152 |
| 150 //if not empty -- extract just below insert when empty | 153 //if not empty -- extract just below insert when empty |
| 160 out = *(Q->extractPos); | 163 out = *(Q->extractPos); |
| 161 Q->extractLock = UNLOCKED; | 164 Q->extractLock = UNLOCKED; |
| 162 return out; | 165 return out; |
| 163 } | 166 } |
| 164 else //Q is empty | 167 else //Q is empty |
| 165 { success = FALSE; | 168 { Q->extractLock = UNLOCKED;//empty, so release lock for others |
| 166 Q->extractLock = UNLOCKED;//have to try again, release for others | |
| 167 } | 169 } |
| 168 } | 170 } |
| 169 //Q is busy or empty | 171 //Q is busy or empty |
| 170 tries++; | 172 tries++; |
| 171 if( tries > SPINLOCK_TRIES ) pthread_yield(); //not reliable | 173 if( tries > SPINLOCK_TRIES ) pthread_yield(); //not reliable |
| 178 //TODO: need to make Q volatile? Want to do this Q in assembly! | 180 //TODO: need to make Q volatile? Want to do this Q in assembly! |
| 179 //Have no idea what GCC's going to do to this code | 181 //Have no idea what GCC's going to do to this code |
| 180 void **startOfData = Q->startOfData; | 182 void **startOfData = Q->startOfData; |
| 181 void **endOfData = Q->endOfData; | 183 void **endOfData = Q->endOfData; |
| 182 | 184 |
| 183 int success = FALSE; | 185 int gotLock = FALSE; |
| 184 | 186 |
| 185 while( TRUE ) | 187 while( TRUE ) |
| 186 { success = | 188 { //this intrinsic returns true if the lock held "UNLOCKED", in which |
| 189 // case it now holds "LOCKED" -- if it already held "LOCKED", then | |
| 190 // gotLock is FALSE | |
| 191 gotLock = | |
| 187 __sync_bool_compare_and_swap( &(Q->insertLock), UNLOCKED, LOCKED ); | 192 __sync_bool_compare_and_swap( &(Q->insertLock), UNLOCKED, LOCKED ); |
| 188 if( success ) | 193 if( gotLock ) |
| 189 { | 194 { |
| 190 void **insertPos = Q->insertPos; | 195 void **insertPos = Q->insertPos; |
| 191 void **extractPos = Q->extractPos; | 196 void **extractPos = Q->extractPos; |
| 192 | 197 |
| 193 //check if room to insert.. can't use a count variable | 198 //check if room to insert.. can't use a count variable |
| 203 } | 208 } |
| 204 Q->insertLock = UNLOCKED; | 209 Q->insertLock = UNLOCKED; |
| 205 return; | 210 return; |
| 206 } | 211 } |
| 207 else //Q is full | 212 else //Q is full |
| 208 { success = FALSE; | 213 { Q->insertLock = UNLOCKED;//full, so release lock for others |
| 209 Q->insertLock = UNLOCKED;//have to try again, release for others | |
| 210 } | 214 } |
| 211 } | 215 } |
| 212 tries++; | 216 tries++; |
| 213 if( tries > SPINLOCK_TRIES ) pthread_yield(); //not reliable | 217 if( tries > SPINLOCK_TRIES ) pthread_yield(); //not reliable |
| 214 } | 218 } |
| 245 retQ->endOfData = &(retQ->startOfData[1023]); | 249 retQ->endOfData = &(retQ->startOfData[1023]); |
| 246 | 250 |
| 247 return retQ; | 251 return retQ; |
| 248 } | 252 } |
| 249 | 253 |
| 254 void | |
| 255 freeSRSWQ( SRSWQueueStruc* Q ) | |
| 256 { | |
| 257 free( Q ); | |
| 258 } | |
| 250 | 259 |
| 251 void* readSRSWQ( SRSWQueueStruc* Q ) | 260 void* readSRSWQ( SRSWQueueStruc* Q ) |
| 252 { void *out = 0; | 261 { void *out = 0; |
| 253 int tries = 0; | 262 int tries = 0; |
| 254 | 263 |
| 281 out = *(Q->extractPos); | 290 out = *(Q->extractPos); |
| 282 return out; | 291 return out; |
| 283 } | 292 } |
| 284 //Q is empty | 293 //Q is empty |
| 285 tries++; | 294 tries++; |
| 286 if( tries > 2 ) return 0; //long enough for writer to finish | 295 if( tries > 10 ) return NULL; //long enough for writer to finish |
| 287 } | 296 } |
| 288 } | 297 } |
| 289 | 298 |
| 290 | 299 |
| 291 void writeSRSWQ( void * in, SRSWQueueStruc* Q ) | 300 void writeSRSWQ( void * in, SRSWQueueStruc* Q ) |
