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