| [6e1e2d0] | 1 | // sequential equivalent swap
 | 
|---|
 | 2 | void swap( uint victim_idx, uint my_idx  ) {
 | 
|---|
 | 3 |     // Step 0:
 | 
|---|
| [601bd9e] | 4 |     work_queue * my_queue = request_queues[my_idx];
 | 
|---|
| [6e1e2d0] | 5 |     work_queue * vic_queue = request_queues[victim_idx];
 | 
|---|
 | 6 |     // Step 2:
 | 
|---|
 | 7 |     request_queues[my_idx] = 0p;
 | 
|---|
 | 8 |     // Step 3:
 | 
|---|
 | 9 |     request_queues[victim_idx] = my_queue;
 | 
|---|
 | 10 |     // Step 4:
 | 
|---|
 | 11 |     request_queues[my_idx] = vic_queue;
 | 
|---|
| [601bd9e] | 12 | }
 | 
|---|
 | 13 | 
 | 
|---|
 | 14 | // This routine is atomic
 | 
|---|
 | 15 | bool CAS( work_queue ** ptr, work_queue ** old, work_queue * new ) {
 | 
|---|
 | 16 |     if ( *ptr != *old )
 | 
|---|
 | 17 |         return false;
 | 
|---|
 | 18 |     *ptr = new;
 | 
|---|
 | 19 |     return true;
 | 
|---|
 | 20 | }
 | 
|---|
 | 21 | 
 | 
|---|
 | 22 | bool try_swap_queues( worker & this, uint victim_idx, uint my_idx ) with(this) {
 | 
|---|
| [6e1e2d0] | 23 |     // Step 0:
 | 
|---|
 | 24 |     // request_queues is the shared array of all sharded queues
 | 
|---|
| [601bd9e] | 25 |     work_queue * my_queue = request_queues[my_idx];
 | 
|---|
 | 26 |     work_queue * vic_queue = request_queues[victim_idx];
 | 
|---|
 | 27 | 
 | 
|---|
| [6e1e2d0] | 28 |     // Step 1:
 | 
|---|
| [601bd9e] | 29 |     // If either queue is 0p then they are in the process of being stolen
 | 
|---|
 | 30 |     // 0p is CForAll's equivalent of C++'s nullptr
 | 
|---|
| [6e1e2d0] | 31 |     if ( vic_queue == 0p ) return false;
 | 
|---|
| [601bd9e] | 32 | 
 | 
|---|
| [6e1e2d0] | 33 |     // Step 2:
 | 
|---|
 | 34 |     // Try to set thief's queue ptr to be 0p.
 | 
|---|
 | 35 |     // If this CAS fails someone stole thief's queue so return false
 | 
|---|
| [601bd9e] | 36 |     if ( !CAS( &request_queues[my_idx], &my_queue, 0p ) )
 | 
|---|
 | 37 |         return false;
 | 
|---|
| [6e1e2d0] | 38 |     
 | 
|---|
 | 39 |     // Step 3:
 | 
|---|
 | 40 |     // Try to set victim queue ptr to be thief's queue ptr.
 | 
|---|
 | 41 |     // If it fails someone stole the other queue, so fix up then return false
 | 
|---|
| [601bd9e] | 42 |     if ( !CAS( &request_queues[victim_idx], &vic_queue, my_queue ) ) {
 | 
|---|
 | 43 |         request_queues[my_idx] = my_queue; // reset queue ptr back to prev val
 | 
|---|
 | 44 |         return false;
 | 
|---|
 | 45 |     }
 | 
|---|
 | 46 | 
 | 
|---|
| [6e1e2d0] | 47 |     // Step 4:
 | 
|---|
| [601bd9e] | 48 |     // Successfully swapped.
 | 
|---|
| [6e1e2d0] | 49 |     // Thief's ptr is 0p so no one will touch it
 | 
|---|
 | 50 |     // Write back without CAS is safe
 | 
|---|
| [601bd9e] | 51 |     request_queues[my_idx] = vic_queue;
 | 
|---|
 | 52 |     return true;
 | 
|---|
 | 53 | }
 | 
|---|