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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

218 APPENDIX D. READ-COPY UPDATE IMPLEMENTATIONS1 static void2 rcu_process_gp_end(struct rcu_state *rsp,3 struct rcu_data *rdp)4 {5 long completed_snap;6 unsigned long flags;78 local_irq_save(flags);9 completed_snap = ACCESS_ONCE(rsp->completed);10 if (rdp->completed != completed_snap) {11 rdp->nxttail[RCU_DONE_TAIL] =12 rdp->nxttail[RCU_WAIT_TAIL];13 rdp->nxttail[RCU_WAIT_TAIL] =14 rdp->nxttail[RCU_NEXT_READY_TAIL];15 rdp->nxttail[RCU_NEXT_READY_TAIL] =16 rdp->nxttail[RCU_NEXT_TAIL];17 rdp->completed = completed_snap;18 }19 local_irq_restore(flags);20 }Figure D.35: Noting End of Old Grace Periods−>next−>func−>nxtlist−>nxttail[RCU_DONE_TAIL]−>nxttail[RCU_WAIT_TAIL]−>nxttail[RCU_NEXT_READY_TAIL]−>nxttail[RCU_NEXT_TAIL]−>next−>func−>next−>func−>next−>func−>next−>func−>next−>func1 static void2 rcu_start_gp(struct rcu_state *rsp, unsigned long flags)3 __releases(rcu_get_root(rsp)->lock)4 {5 struct rcu_data *rdp = rsp->rda[smp_processor_id()];6 struct rcu_node *rnp = rcu_get_root(rsp);7 struct rcu_node *rnp_cur;8 struct rcu_node *rnp_end;910 if (!cpu_needs_another_gp(rsp, rdp)) {11 spin_unlock_irqrestore(&rnp->lock, flags);12 return;13 }14 rsp->gpnum++;15 rsp->signaled = RCU_GP_INIT;16 rsp->jiffies_force_qs = jiffies +17 RCU_JIFFIES_TILL_FORCE_QS;18 rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +19 RCU_JIFFIES_TILL_FORCE_QS;20 record_gp_stall_check_time(rsp);21 dyntick_record_completed(rsp, rsp->completed - 1);22 note_new_gpnum(rsp, rdp);23 rdp->nxttail[RCU_NEXT_READY_TAIL] =24 rdp->nxttail[RCU_NEXT_TAIL];25 rdp->nxttail[RCU_WAIT_TAIL] =26 rdp->nxttail[RCU_NEXT_TAIL];27 if (NUM_RCU_NODES == 1) {28 rnp->qsmask = rnp->qsmaskinit;29 spin_unlock_irqrestore(&rnp->lock, flags);30 return;31 }32 spin_unlock(&rnp->lock);33 spin_lock(&rsp->onofflock);34 rnp_end = rsp->level[NUM_RCU_LVLS - 1];35 rnp_cur = &rsp->node[0];36 for (; rnp_cur < rnp_end; rnp_cur++)37 rnp_cur->qsmask = rnp_cur->qsmaskinit;38 rnp_end = &rsp->node[NUM_RCU_NODES];39 rnp_cur = rsp->level[NUM_RCU_LVLS - 1];40 for (; rnp_cur < rnp_end; rnp_cur++) {41 spin_lock(&rnp_cur->lock);42 rnp_cur->qsmask = rnp_cur->qsmaskinit;43 spin_unlock(&rnp_cur->lock);44 }45 rsp->signaled = RCU_SIGNAL_INIT;46 spin_unlock_irqrestore(&rsp->onofflock, flags);47 }Figure D.37: Starting a Grace PeriodFigure D.36: RCU Callback Listmanaged as a singly linked list with multiple tailpointers, as shown in Figure D.36. This multiple tailpointer layout, spearheaded by Lai Jiangshan, simplifieslist handling [Jia08]. In this figure, the bluebox represents one CPU’s rcu_data structure, withthe six white boxes at the bottom of the diagramrepresenting a list of six RCU callbacks (rcu_headstructures). In this list, the first three callbacks havepassed through their grace period and are thus waitingto be invoked, the fourth callback (the first onthe second line) is waiting for the current grace periodto complete, and the last two are waiting for thenext grace period. The last two tail pointers referencethe last element, so that the final sublist, whichwould comprise callbacks that had not yet been associatedwith a specific grace period, is empty.Lines 8 and 19 of Figure D.35 suppress and reenableinterrupts, respectively. Line 9 picks up asnapshot of the rcu_state structure’s ->completedfield, storing it in the local variable completed_snap. Line 10 checks to see if the current CPU isnot yet aware of the end of a grace period, and if itis not aware, lines 11-16 advance this CPU’s RCUcallbacks by manipulating the tail pointers. Line 17then records the most recently completed grace periodnumber in this CPU’s rcu_data structure inthe ->completed field.D.3.6.3 Starting a Grace PeriodFigure D.37 shows rcu_start_gp(), which starts anew grace period, also releasing the root rcu_nodestructure’s lock, which must be acquired by thecaller.Line4isannotationforthesparseutility, indicat-

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

Saved successfully!

Ooh no, something went wrong!