#include volatile unsigned long jiffies; struct task_struct { int boost_kthread_status; int rcu_wake_cond_been_called; }; struct task_struct t1; struct task_struct t2; struct rcu_node { void *exp_tasks; void *gp_tasks; void *boost_tasks; unsigned long qsmask; unsigned long boost_time; int boost_kthread_status; struct task_struct *boost_kthread_task; int rcu_initiate_boost_trace_been_called; }; struct rcu_node rn1; struct rcu_node rn2; void rcu_wake_cond(struct task_struct *t, int bks) { t->rcu_wake_cond_been_called = 1; t->boost_kthread_status = bks; } void rcu_initiate_boost_trace(struct rcu_node *rnp) { rnp->rcu_initiate_boost_trace_been_called = 1; } void initialize(char *argv[], struct task_struct *t, struct rcu_node *rnp) { rnp->exp_tasks = argv[0]; rnp->gp_tasks = argv[1]; rnp->boost_tasks = argv[2]; rnp->qsmask = (unsigned long)argv[3]; rnp->boost_time = (unsigned long)argv[4]; rnp->boost_kthread_status = (int)argv[5]; rnp->boost_kthread_task = t; rnp->rcu_initiate_boost_trace_been_called = 0; t->rcu_wake_cond_been_called = 0; } void do_old_if(char *argv[], struct task_struct *t_in, struct rcu_node *rnp) { struct task_struct *t; /* --- Code under test, original. --- */ if (rnp->exp_tasks != NULL || (rnp->gp_tasks != NULL && rnp->boost_tasks == NULL && rnp->qsmask == 0 && ULONG_CMP_GE(jiffies, rnp->boost_time))) { if (rnp->exp_tasks == NULL) rnp->boost_tasks = rnp->gp_tasks; /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ t = rnp->boost_kthread_task; if (t) rcu_wake_cond(t, rnp->boost_kthread_status); } else { rcu_initiate_boost_trace(rnp); /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ } } void do_new_if(char *argv[], struct task_struct *t_in, struct rcu_node *rnp) { struct task_struct *t; /* --- Code under test, new. --- */ if (rnp->exp_tasks == NULL && (rnp->gp_tasks == NULL || rnp->boost_tasks != NULL || rnp->qsmask != 0 && ULONG_CMP_LT(jiffies, rnp->boost_time))) { rcu_initiate_boost_trace(rnp); /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ } else { if (rnp->exp_tasks == NULL) rnp->boost_tasks = rnp->gp_tasks; /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ t = rnp->boost_kthread_task; if (t) rcu_wake_cond(t, rnp->boost_kthread_status); } } void check(void) { assert(rn1.exp_tasks == rn2.exp_tasks); assert(rn1.gp_tasks == rn2.gp_tasks); assert(rn1.boost_tasks == rn2.boost_tasks); assert(rn1.qsmask == rn2.qsmask); assert(rn1.boost_time == rn2.boost_time); assert(rn1.boost_kthread_status == rn2.boost_kthread_status); assert(rn1.rcu_initiate_boost_trace_been_called == rn2.rcu_initiate_boost_trace_been_called); assert(t1.boost_kthread_status == t2.boost_kthread_status); assert(t1.rcu_wake_cond_been_called == t2.rcu_wake_cond_been_called); } int main(int argc, char *argv[]) { initialize(argv, &t1, &rn1); initialize(argv, &t2, &rn2); check(); do_old_if(argv, &t1, &rn1); do_new_if(argv, &t2, &rn2); check(); }