| [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 | } | 
|---|