source: doc/theses/colby_parsons_MMAth/code/swap_queues.cfa@ 678c540

ADT ast-experimental
Last change on this file since 678c540 was 601bd9e, checked in by caparsons <caparson@…>, 3 years ago

added figures, code examples and more to thesis stuff. wrote many more pages on actors

  • Property mode set to 100644
File size: 2.6 KB
Line 
1// this is a code stub and will not compile
2
3// tries to atomically swap two queues and returns 0p if the swap failed
4// returns ptr to newly owned queue if swap succeeds
5static inline work_queue * try_swap_queues( worker & this, unsigned int victim_idx, unsigned int my_idx ) with(this) {
6 work_queue * my_queue = request_queues[my_idx];
7 work_queue * other_queue = request_queues[victim_idx];
8
9 // if either queue is 0p then they are in the process of being stolen
10 if ( other_queue == 0p || my_queue == 0p ) return 0p;
11
12 // try to set our queue ptr to be 0p. If it fails someone moved our queue so return false
13 if ( !__atomic_compare_exchange_n( &request_queues[my_idx], &my_queue, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) )
14 return 0p;
15
16 // try to set other queue ptr to be our queue ptr. If it fails someone moved the other queue so fix up then return false
17 if ( !__atomic_compare_exchange_n( &request_queues[victim_idx], &other_queue, my_queue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) {
18 /* paranoid */ verify( request_queues[my_idx] == 0p );
19 request_queues[my_idx] = my_queue; // reset my queue ptr back to appropriate val
20 return 0p;
21 }
22
23 // we have successfully swapped and since our queue is 0p no one will touch it so write back new queue ptr non atomically
24 request_queues[my_idx] = other_queue; // last write does not need to be atomic
25 return other_queue;
26}
27
28// This routine is atomic
29bool CAS( work_queue ** ptr, work_queue ** old, work_queue * new ) {
30 if ( *ptr != *old )
31 return false;
32 *ptr = new;
33 return true;
34}
35
36bool try_swap_queues( worker & this, uint victim_idx, uint my_idx ) with(this) {
37 work_queue * my_queue = request_queues[my_idx];
38 work_queue * vic_queue = request_queues[victim_idx];
39
40 // If either queue is 0p then they are in the process of being stolen
41 // 0p is CForAll's equivalent of C++'s nullptr
42 if ( vic_queue == 0p || my_queue == 0p ) return false;
43
44 // Try to set our queue ptr to be 0p.
45 // If this CAS fails someone moved our queue so return false
46 if ( !CAS( &request_queues[my_idx], &my_queue, 0p ) )
47 return false;
48
49 // Try to set other queue ptr to be our queue ptr.
50 // If it fails someone moved the other queue, so fix up then return false
51 if ( !CAS( &request_queues[victim_idx], &vic_queue, my_queue ) ) {
52 request_queues[my_idx] = my_queue; // reset queue ptr back to prev val
53 return false;
54 }
55
56 // Successfully swapped.
57 // Our queue is 0p so no one will touch it so write back without CAS is safe
58 request_queues[my_idx] = vic_queue;
59 return true;
60}
Note: See TracBrowser for help on using the repository browser.