struct rcu_head {
struct rcu_head *next;
void (*func)(struct rcu_head *head);
};
struct rcu_synchronize {
struct rcu_head head;
struct completion completion;
};
struct completion {
unsigned int done;
wait_queue_head_t wait;
};
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;
static inline void rcu_read_lock(void) {
// 禁止抢占
// __rcu_read_lock();
preempt_disable();
// __acquire(RCU);
// rcu_read_acquire();
}
static inline void rcu_read_unlock(void) {
// rcu_read_release();
// __release(RCU);
// __rcu_read_unlock();
// 开启抢占
preempt_enable();
}
static inline void synchronize_rcu(void) {
// synchronize_sched();
struct rcu_synchronize rcu;
// if (rcu_blocking_is_gp())
// if (num_online_cpus() == 1)
if (cpumask_weight(cpu_online_mask) == 1)
return;
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);
}