10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

252 APPENDIX E. FORMAL VERIFICATIONsums the pair of counters so as to emulate weakmemory ordering. Lines 2-13 fetch one of the counters,and line 14 fetches the other of the pair andsums them. The atomic block consists of a single doodstatement. This do-od statement (spanning lines3-12)isunusualinthatitcontainstwounconditionalbranches with guards on lines 4 and 8, which causesPromela to non-deterministically choose one of thetwo (but again, the full state-space search causesPromela to eventually make all possible choices ineach applicable situation). The first branch fetchesthe zero-th counter and sets i to 1 (so that line 14will fetch the first counter), while the second branchdoes the opposite, fetching the first counter and settingi to 0 (so that line 14 will fetch the secondcounter).Quick Quiz E.3: <strong>Is</strong> there a more straightforwardway to code the do-od statement?With the sum_unordered macro in place, we cannow proceed to the update-side process shown inFigure. The update-side process repeats indefinitely,with the corresponding do-od loop rangingover lines 7-57. Each pass through the loop firstsnapshots the global readerprogress array into thelocal readerstart array on lines 12-21. This snapshotwill be used for the assertion on line 53. Line23 invokes sum_unordered, and then lines 24-27 reinvokesum_unordered if the fastpath is potentiallyusable.Lines 28-40 execute the slowpath code if need be,with lines 30 and 38 acquiring and releasing theupdate-side lock, lines 31-33 flipping the index, andlines 34-37 waiting for all pre-existing readers tocomplete.Lines 44-56 then compare the current values inthe readerprogress array to those collected inthe readerstart array, forcing an assertion failureshould any readers that started before this updatestill be in progress.Quick Quiz E.4: Why are there atomic blocksat lines 12-21 and lines 44-56, when the operationswithin those atomic blocks have no atomic implementationon any current production microprocessor?Quick Quiz E.5: <strong>Is</strong> the re-summing of the counterson lines 24-27 really necessary???All that remains is the initialization block shownin Figure E.15. This block simply initializes thecounter pair on lines 5-6, spawns the reader processeson lines 7-14, and spawns the updater processeson lines 15-21. This is all done within anatomic block to reduce state space.1 proctype qrcu_updater(byte me)2 {3 int i;4 byte readerstart[N_QRCU_READERS];5 int sum;67 do8 :: 1 ->910 /* Snapshot reader state. */1112 atomic {13 i = 0;14 do15 :: i < N_QRCU_READERS ->16 readerstart[i] = readerprogress[i];17 i++18 :: i >= N_QRCU_READERS ->19 break20 od21 }2223 sum_unordered;24 if25 :: sum sum_unordered26 :: else -> skip27 fi;28 if29 :: sum > 1 ->30 spin_lock(mutex);31 atomic { ctr[!idx]++ }32 idx = !idx;33 atomic { ctr[!idx]-- }34 do35 :: ctr[!idx] > 0 -> skip36 :: ctr[!idx] == 0 -> break37 od;38 spin_unlock(mutex);39 :: else -> skip40 fi;4142 /* Verify reader progress. */4344 atomic {45 i = 0;46 sum = 0;47 do48 :: i < N_QRCU_READERS ->49 sum = sum + (readerstart[i] == 1 &&50 readerprogress[i] == 1);51 i++52 :: i >= N_QRCU_READERS ->53 assert(sum == 0);54 break55 od56 }57 od58 }Figure E.14: QRCU Updater Process

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!