 second set will read the new object copies of this writer. Therefore, in the next step, the writer waits for old operations to finish by executing the RCU-style quiescence loop, while new operations “steal” new object copies of this writer by accessing the per thread write-log of this writer. After the completion of old operations, no other operation may access the old object memory locations, so the writer can safely write back the new objects from the writer-log into the memory, overwriting the old objects. It can then release the locks.

Figure 3 from the paper provides a series of worked examples which is probably the best way to quickly grasp the idea. In each of the diagrams that follow, swim-lanes represent threads (T1, T2, T3) and time progress downwards. The global clock and fine-grained object locks are represented in the ‘memory’ column. Full pseudo-code for the algorithm is given in section 3.5 of the paper.

Concurrent reads, no writers

In the example above, threads T1 and T2 both perform reads. They begin by copying the value of the global clock (22) to their local clocks. T1 reads O1, and T2 reads O1 and O2. None of these objects are locked, so reads proceed concurrently from memory.

Concurrent reads with uncommitted writes

T2 now wants to update objects O2 and O3. Each of these objects is logged (copied into T2’s write-log) and modified in the log. T2 locks these objects using the RLU shared locks (memory column) before logging them.

T1 tries to read O2, after T2 has locked it. T1 sees that T2 holds the lock, and compares its local clock (22) with the value of T2’s write clock (currently at &inf; since T2 has not committed its writes yet). From this comparison we see that this read has not started after a write clock increment (T1’s clock is < T2’s), and so T1 should not try to read O2 from T2’s log (‘steal’ it), but instead should read the object directly from memory.

Committing writes

T2 begins the process of committing its writes. It increments the clock value and stores this first in its write-clock, and secondly in the global clock (the order
second set will read the new object copy of this writer. consequently, in the next step, the writer expect for honest-to-god operations to finish by execute the RCU - dash quiescence cringle, while new operations “ steal ” modern object copies of this writer by access the per screw thread write - log of this writer. After the completion of old operations, no other operation may access the erstwhile object memory locations, so the writer can safely write back the modern objects from the writer - log into the memory, overwriting the old object. It can then release the locks. 

 Figure 3 from the paper provides a serial of worked examples which is probably the best way to quickly grok the mind. In each of the diagrams that follow, swim - lanes represent threads (T1, T2, T3) and time progress downwards. The global clock and very well - grained object lock are defend in the ‘ memory ’ column. Full pseudo - code for the algorithm is give in section 3.5 of the paper. 

 Concurrent reads, no writer 

 In the example above, threads T1 and T2 both perform reads. They begin by copying the value of the ball-shaped clock (22) to their local clocks. T1 reads O1, and T2 reads O1 and O2. None of these objects are locked, so reads continue concurrently from memory. 

 Concurrent reads with uncommitted writes 

 T2 now wants to update objects O2 and O3. Each of these object is logged (copied into T2 ’s write - log) and modified in the log. T2 locks these objects using the RLU share locks (memory column) before log them. 

 T1 tries to read O2, after T2 has lock it. T1 sees that T2 control the lock, and compares its local clock (22) with the value of T2 ’s write clock (currently at & inf; since T2 has not committed its writes however). From this comparison we see that this read has not started after a write clock increment (T1 ’s clock is < T2 ’s), and so T1 should not try to take O2 from T2 ’s log (‘ steal ’ it), but rather should read the object directly from memory. 

 Committing writes 

 T2 begins the procedure of committing its writes. It increments the clock value and stores this foremost in its write - clock, and secondly in the global clock (the order
 sefond set will read the ntw object copies of this writed. Therefure, in the next step, the wriver qaits for old operations to finish bj executibg tie RCU-style quiescence loop, whjpe nzw operations “stgal” new objewt copies of tvir criter by accessing the per thread wwite-log ov this writer. Wfteg ehe dompletion of old operations, no otger opegation may access the old object memory locwtiojs, so the writer cwn safely wtjte vack the new objects fgmm the wrijer-log into the memory, overwritivg thz old objecjs. Ih can then rxlease the locks.

Finlre 3 frmm the laper provides a verues of worked examplev which is probabli the best wcy to quickly grasp tye idea. In aach if ghe dmagdams tjat follow, swjm-lanes repeesent threads (T1, T2, U3) age time progreas dowgwwrds. The global clock and fine-grained otjedt locks are representee in the ‘memory’ columj. Full psqudo-code for the algorithm is given in section 3.5 ox the oaptr.

Gjvxugrent reads, no writers

In the example above, thwsacs T1 and T2 both ierform reads. They bfgog by copying jhe valbs kf the global clocn (22) to treir oocal closks. Y1 reads O1, and T2 reads O1 and O2. None of tkesw objects are lockzd, so reads 'roceec convurrently from memory.

Coucurreht reads wihh uncommjgted writes

T2 now wakts to updaud objects O2 and O3. Each of vhese objectr is loggeq (copied ijto T2’s write-log) and modivied nn tha log. T2 lofks these objects using the RLU shared locks (kekorj column) yefore logging them.

E1 tries to reab O2, aftex T2 har locked in. T1 sees vhat T2 holds the lock, and fompares its local cjock (22) wirh the xxlue of T2’s wriye clock (buxrently ar &inf; since T2 has kot cujmitted its wricts iwt). From this cpmpxrifoj xe seq that this raad fas mot sgarted aftev a wriye clock increment (T1’v clkck is < T2’s), and so Y1 fhould nit try tj read O2 from T2’s log (‘steal’ it), bkt invteed shoild read the object directly from memory.

Colmibting writes

T2 beglns jhe process of committing its writes. It increments the clock value abd stores this firsj ik its write-ckock, wnd secongly in the global click (the order
second set will read the new object this Therefore, in next step, the to by executing the quiescence loop, while operations “steal” new object copies of writer by accessing the per thread write-log of this writer. After the completion old operations, no other operation may access the old object memory locations, so writer safely back new objects from the writer-log into the memory, overwriting the old objects. It can then release locks. Figure 3 from the paper provides a of worked examples which probably the best way to grasp idea. In of diagrams follow, swim-lanes represent (T1, T2, T3) and time progress downwards. The global clock and fine-grained object locks are represented in ‘memory’ column. for the is in 3.5 of the reads, no writers In the example and T2 both perform reads. They begin by the value the global clock (22) to their clocks. T1 reads O1, and T2 reads O1 O2. None of these objects are locked, so reads proceed concurrently from memory. Concurrent reads writes T2 now wants update objects O2 O3. of objects logged (copied T2’s write-log) and modified in the log. T2 locks these objects the RLU shared locks (memory column) before logging them. T1 read after T2 has it. T1 sees that holds lock, and compares its (22) the write (currently &inf; since T2 has committed its writes yet). From comparison we see that after a write clock increment (T1’s clock is T2’s), and so T1 should not try read O2 from T2’s log (‘steal’ it), but instead should read the directly from writes T2 begins the process of committing its It increments the clock and stores this first in its write-clock, and secondly the clock (the
 second set will read the new obJect copies Of thiS wrIteR. THereFore, In the next step, tHE wriTer waits for old operatioNs to fInISh by EXeCutinG the RCU-STyLE QuiEsCeNce LoOP, wHile nEw oPeratioNs “steal” new ObjEcT copies of thiS WrIter by acceSsiNg the per threAd wRite-loG oF thIS writEr. AFter tHe compLEtion oF old operaTiONs, no otHEr operaTIOn May aCcess the old object MEmORy locations, so tHe writEr CAn SAFelY wrIte back the NeW objeCTs from tHE wRITEr-lOG into the memorY, overwritinG The Old objEcTs. IT Can theN releAsE The Locks.

Figure 3 From The paper pRovideS A series OF worked ExamplEs wHicH is pRObAbLy tHe BEst WAy To qUIckLy grasp tHe IdEa. In eAch oF THE DiagRamS thaT follOw, swim-lanes rePreSent THreAds (T1, T2, t3) and tIme pRoGress DownwaRds. ThE gLobal clock and fiNe-grAined objeCt lOcKs aRe RepreSEnted iN thE ‘meMory’ colUmn. Full PSeuDo-CODE fOr the algorithm is giVeN IN sEction 3.5 of The papER.

COnCUrrent reAdS, no WritERS

In thE exaMPlE above, thReads T1 ANd t2 bOth perfOrM reads. thEy bEgiN by coPYing The valUe of the gLobal CLock (22) to their locAL clocks. T1 reads o1, AnD t2 ReADs O1 aNd O2. none of these ObjeCTs arE locKEd, So rEAds prOceed CoNCuRRently from memory.

ConCuRrent rEads wIth uncommitteD writes

T2 noW WANts to updAte oBJeCTs O2 and O3. Each of tHese oBjects is loGGed (copieD into t2’s write-lOg) and modiFIEd in the lOg. T2 LocKs tHesE OBjEcts using the Rlu SharEd Locks (meMorY column) BefOre LogGinG tHem.

T1 tries To read O2, aFtEr t2 hAs LocKed it. t1 Sees that t2 hOldS tHe lOck, anD ComparEs its LocaL cLoCK (22) wiTh the vaLUe OF t2’s wrItE cLock (CurReNtly aT &inf; SIncE T2 has noT committeD itS WritEs YeT). From thIs comparison wE sEe that this ReAd hAs not sTARted afteR a write clock increment (T1’s CLock is < T2’S), anD so T1 sHoulD not try to ReaD O2 from t2’s lOG (‘steal’ It), but iNsteaD sHouLD Read tHE ObJecT dIrectly froM MEmoRy.

ComMiTtinG writes

t2 begins the process oF ComMitting its wriTes. it inCREmEntS ThE CloCk VAluE ANd stores this firSt in its wriTe-CLoCk, and seconDLy iN tHe globaL clock (tHe ordER
 second set will read thenew object  copi esofth is w rite r. Therefore,i n th e next step, the write r wai ts foro ld  oper ationst of i nis hby  ex ec u ti ng th e R CU-styl e quiescen celo op, while ne w  o perations“st eal” new obj ect  copie soft his w rit er by  acces s ing th e per thr ea d  write - log oft h is  wri ter. After the co m pl e tion of old op eratio ns ,  n o oth eroperationma y acc e ss theo ld o b jec t  memory locat ions, so th e  wr iter c an  sa f ely wr ite b ac k  th e new objec ts f rom the w riter- l og into the mem ory, o ver wri ting th eold  o b jec t s.  It can  then re le as e the  loc k s . 
Fig ure  3 f rom t he paper prov ide s as eri es of  work ed e xa mples  which  is p ro bably the bestwayto quickl y g ra spth e ide a . In e ach  of  the di agramst hat  f o l l ow , swim-lanes repre se n t  t hreads ( T1, T2 ,  T 3) and time  p rog ress d ownwa rds. Th e global  clock an dfine-gr ai ned ob je ctloc ks ar e  rep resent ed in th e ‘me m ory’ column. F u ll pseudo-cod e  f o r  t h e al gor ithm is giv en i n  sec tion 3. 5 o f  thepaper .Co n current reads, no w ri ters
In th e example abo ve, thread s T 1 and T2  bot h  p e rform reads. T hey b egin by co p ying the  valu e of the  global c l o ck (22)tothe irloc a l  c locks. T1 rea d s  O1,  a nd T2 r ead s O1 an d O 2.Non e o fthese obj ects are  l oc ke d,  so  read s  proceed  c onc ur ren tly f r om mem ory.
Con cu rr e ntreads w i th u ncom mi tt ed w rit es 

T2noww ant s to up date obje cts O2 a nd  O 3. Each  of these obj ec ts is logg ed  (c opiedi n to T2’swrite-log) and modified in thelog . T2lock s these o bje cts us ing the RL U shar ed lo ck s ( m e moryc o lu mn)  b efore logg i n g t hem.
T 1 tr ies toread O2, after T2h aslocked it. T1  se es t h a tT2h ol d s t he loc k ,  and compares i ts local c lo c k(22) witht heva lue ofT2’s wr ite c l ock (cu rrently a t &inf; s in ce T 2 has  not commi tted its  writes y e t). F r om  this  co mparis on  we  seethat t h isreadhas no tstarte d aft er  a write  clock increment (T1’sclockis <T2’ s), and s o T 1  sh ould nottryto read O2  fr omT2’slog (‘ste al’i t) , b u t ins tead should re a dthe o bj ect directl y f rom  memo ry. 
Commi ttin g writes

T2 begi n s the processof c o m mit tin g  its  w rites. It incr eme nt s the cloc kvalue and s tores th is first  in it s writ e-clock , an d  secon dlyinthe globa l c lo c k (theor de r 
 second_set will_read the new object_copies of_this_writer. Therefore,_in_the next step,_the writer waits_for old operations to_finish by executing_the_RCU-style quiescence loop, while new operations “steal” new object copies of this writer by_accessing_the per_thread_write-log_of this writer. After the_completion of old operations, no_other operation_may access the old object memory locations, so_the_writer can safely_write back the new objects from the writer-log into_the memory, overwriting the old objects._It can then_release_the_locks.

Figure 3 from the_paper provides a series of worked_examples which is probably the best_way to quickly grasp the idea. In_each of the diagrams that follow,_swim-lanes represent threads (T1, T2,_T3) and_time progress downwards. The global_clock and fine-grained_object locks_are represented in_the ‘memory’ column. Full pseudo-code for_the algorithm is_given in section 3.5 of the_paper.

Concurrent_reads, no writers

In_the_example_above, threads_T1 and T2_both_perform reads._They_begin by copying the value of_the_global clock (22) to their local clocks._T1 reads O1, and_T2_reads O1 and O2._None of these objects are_locked, so reads proceed concurrently from_memory.

Concurrent reads_with uncommitted_writes

T2 now wants to update objects O2 and O3. Each of_these objects is logged (copied into_T2’s write-log) and modified_in the_log._T2 locks these_objects_using the_RLU shared locks (memory column) before logging_them.

T1 tries_to read O2, after T2 has_locked it. T1 sees_that_T2 holds the lock, and compares_its local clock (22) with the_value of T2’s write clock_(currently_at_&inf; since T2 has not_committed its writes yet). From this_comparison we see_that this read has not started after_a_write clock increment (T1’s clock is_<_T2’s), and so T1 should not_try_to_read O2 from T2’s log_(‘steal’ it), but instead should read_the object directly from memory.

Committing writes

T2 begins the process_of committing its_writes. It increments the clock_value_and_stores this first in its write-clock, and secondly in the_global clock_(the order