- File:
-
- 1 edited
-
libcfa/src/concurrency/ready_queue.cfa (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/ready_queue.cfa
rd3ba775 rc993b15 17 17 // #define __CFA_DEBUG_PRINT_READY_QUEUE__ 18 18 19 // #define USE_MPSC 19 20 20 21 #define USE_RELAXED_FIFO … … 255 256 /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count ); 256 257 258 // write timestamp 259 thrd->link.ts = rdtscl(); 260 257 261 bool local; 258 262 int preferred = external ? -1 : kernelTLS().this_processor->rdq.id; … … 273 277 #endif 274 278 279 #if defined(USE_MPSC) 280 // mpsc always succeeds 281 } while( false ); 282 #else 275 283 // If we can't lock it retry 276 284 } while( !__atomic_try_acquire( &lanes.data[i].lock ) ); 285 #endif 277 286 278 287 // Actually push it 279 288 push(lanes.data[i], thrd); 280 289 290 #if !defined(USE_MPSC) 281 291 // Unlock and return 282 292 __atomic_unlock( &lanes.data[i].lock ); 293 #endif 283 294 284 295 // Mark the current index in the tls rng instance as having an item … … 339 350 __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr); 340 351 341 // #define USE_PREFERRED342 #if !defined(USE_PREFERRED)343 352 const bool external = (!kernelTLS().this_processor) || (cltr != kernelTLS().this_processor->cltr); 344 353 /* paranoid */ verify(external || kernelTLS().this_processor->rdq.id < lanes.count ); 345 #else 346 unsigned preferred = thrd->preferred; 347 const bool external = (!kernelTLS().this_processor) || preferred == -1u || thrd->curr_cluster != cltr; 348 /* paranoid */ verifyf(external || preferred < lanes.count, "Invalid preferred queue %u for %u lanes", preferred, lanes.count ); 349 350 unsigned r = preferred % READYQ_SHARD_FACTOR; 351 const unsigned start = preferred - r; 352 #endif 354 355 // write timestamp 356 thrd->link.ts = rdtscl(); 353 357 354 358 // Try to pick a lane and lock it … … 364 368 } 365 369 else { 366 #if !defined(USE_PREFERRED)367 370 processor * proc = kernelTLS().this_processor; 368 371 unsigned r = proc->rdq.its++; 369 372 i = proc->rdq.id + (r % READYQ_SHARD_FACTOR); 373 } 374 375 376 #if defined(USE_MPSC) 377 // mpsc always succeeds 378 } while( false ); 370 379 #else 371 i = start + (r++ % READYQ_SHARD_FACTOR);372 #endif373 }374 380 // If we can't lock it retry 375 381 } while( !__atomic_try_acquire( &lanes.data[i].lock ) ); 382 #endif 376 383 377 384 // Actually push it 378 385 push(lanes.data[i], thrd); 379 386 387 #if !defined(USE_MPSC) 380 388 // Unlock and return 381 389 __atomic_unlock( &lanes.data[i].lock ); 390 #endif 382 391 383 392 #if !defined(__CFA_NO_STATISTICS__) … … 483 492 lanes.tscs[w].tv = thrd->link.ts; 484 493 #endif 485 486 thrd->preferred = w;487 494 488 495 // return the popped thread … … 512 519 // Check that all the intrusive queues in the data structure are still consistent 513 520 static void check( __ready_queue_t & q ) with (q) { 514 #if defined(__CFA_WITH_VERIFY__) 521 #if defined(__CFA_WITH_VERIFY__) && !defined(USE_MPSC) 515 522 { 516 523 for( idx ; lanes.count ) { … … 518 525 assert(!lanes.data[idx].lock); 519 526 520 if(is_empty(sl)) { 521 assert( sl.anchor.next == 0p ); 522 assert( sl.anchor.ts == 0 ); 523 assert( mock_head(sl) == sl.prev ); 524 } else { 525 assert( sl.anchor.next != 0p ); 526 assert( sl.anchor.ts != 0 ); 527 assert( mock_head(sl) != sl.prev ); 528 } 527 assert(head(sl)->link.prev == 0p ); 528 assert(head(sl)->link.next->link.prev == head(sl) ); 529 assert(tail(sl)->link.next == 0p ); 530 assert(tail(sl)->link.prev->link.next == tail(sl) ); 531 532 if(is_empty(sl)) { 533 assert(tail(sl)->link.prev == head(sl)); 534 assert(head(sl)->link.next == tail(sl)); 535 } else { 536 assert(tail(sl)->link.prev != head(sl)); 537 assert(head(sl)->link.next != tail(sl)); 538 } 529 539 } 530 540 } … … 547 557 // fixes the list so that the pointers back to anchors aren't left dangling 548 558 static inline void fix(__intrusive_lane_t & ll) { 549 if(is_empty(ll)) { 550 verify(ll.anchor.next == 0p); 551 ll.prev = mock_head(ll); 552 } 559 #if !defined(USE_MPSC) 560 // if the list is not empty then follow he pointer and fix its reverse 561 if(!is_empty(ll)) { 562 head(ll)->link.next->link.prev = head(ll); 563 tail(ll)->link.prev->link.next = tail(ll); 564 } 565 // Otherwise just reset the list 566 else { 567 verify(tail(ll)->link.next == 0p); 568 tail(ll)->link.prev = head(ll); 569 head(ll)->link.next = tail(ll); 570 verify(head(ll)->link.prev == 0p); 571 } 572 #endif 553 573 } 554 574
Note:
See TracChangeset
for help on using the changeset viewer.