void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array, struct rcu_synchronize *rs_array) { int i; /* Initialize and register callbacks for each flavor specified. */ for (i = 0; i < n; i++) { if (checktiny && (crcu_array[i] == call_rcu || crcu_array[i] == call_rcu_bh)) { might_sleep(); continue; } init_rcu_head_on_stack(&rs_array[i].head); init_completion(&rs_array[i].completion); (crcu_array[i])(&rs_array[i].head, wakeme_after_rcu); } /* Wait for all callbacks to be invoked. */ for (i = 0; i < n; i++) { if (checktiny && (crcu_array[i] == call_rcu || crcu_array[i] == call_rcu_bh)) continue; wait_for_completion(&rs_array[i].completion); destroy_rcu_head_on_stack(&rs_array[i].head); } }
/* * synchronize_srcu - wait for prior SRCU read-side critical-section completion */ void synchronize_srcu(struct srcu_struct *sp) { struct rcu_synchronize rs; init_rcu_head_on_stack(&rs.head); init_completion(&rs.completion); call_srcu(sp, &rs.head, wakeme_after_rcu); wait_for_completion(&rs.completion); destroy_rcu_head_on_stack(&rs.head); }
void wait_rcu_gp(call_rcu_func_t crf) { struct rcu_synchronize rcu; init_rcu_head_on_stack(&rcu.head); init_completion(&rcu.completion); /* Will wake me after RCU finished. */ crf(&rcu.head, wakeme_after_rcu); /* Wait for it. */ wait_for_completion(&rcu.completion); destroy_rcu_head_on_stack(&rcu.head); }
void rcu_barrier_sched(void) { struct rcu_synchronize rcu; init_rcu_head_on_stack(&rcu.head); init_completion(&rcu.completion); /* Will wake me after RCU finished. */ call_rcu_sched(&rcu.head, wakeme_after_rcu); /* Wait for it. */ wait_for_completion(&rcu.completion); destroy_rcu_head_on_stack(&rcu.head); }