1 #include <stdio.h> 2 3 volatile unsigned long jiffies; 4 5 struct task_struct { 6 int boost_kthread_status; 7 int rcu_wake_cond_been_called; 8 }; 9 10 struct task_struct t1; 11 struct task_struct t2; 12 13 struct rcu_node { 14 void *exp_tasks; 15 void *gp_tasks; 16 void *boost_tasks; 17 unsigned long qsmask; 18 unsigned long boost_time; 19 int boost_kthread_status; 20 struct task_struct *boost_kthread_task; 21 int rcu_initiate_boost_trace_been_called; 22 }; 23 24 struct rcu_node rn1; 25 struct rcu_node rn2; 26 27 void rcu_wake_cond(struct task_struct *t, int bks) 28 { 29 t->rcu_wake_cond_been_called = 1; 30 t->boost_kthread_status = bks; 31 } 32 33 void rcu_initiate_boost_trace(struct rcu_node *rnp) 34 { 35 rnp->rcu_initiate_boost_trace_been_called = 1; 36 } 37 38 void initialize(char *argv[], struct task_struct *t, struct rcu_node *rnp) 39 { 40 rnp->exp_tasks = argv[0]; 41 rnp->gp_tasks = argv[1]; 42 rnp->boost_tasks = argv[2]; 43 rnp->qsmask = (unsigned long)argv[3]; 44 rnp->boost_time = (unsigned long)argv[4]; 45 rnp->boost_kthread_status = (int)argv[5]; 46 rnp->boost_kthread_task = t; 47 rnp->rcu_initiate_boost_trace_been_called = 0; 48 t->rcu_wake_cond_been_called = 0; 49 } 50 51 void do_old_if(char *argv[], struct task_struct *t_in, struct rcu_node *rnp) 52 { 53 struct task_struct *t; 54 55 /* --- Code under test, original. --- */ 56 if (rnp->exp_tasks != NULL || 57 (rnp->gp_tasks != NULL && 58 rnp->boost_tasks == NULL && 59 rnp->qsmask == 0 && 60 ULONG_CMP_GE(jiffies, rnp->boost_time))) { 61 if (rnp->exp_tasks == NULL) 62 rnp->boost_tasks = rnp->gp_tasks; 63 /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ 64 t = rnp->boost_kthread_task; 65 if (t) 66 rcu_wake_cond(t, rnp->boost_kthread_status); 67 } else { 68 rcu_initiate_boost_trace(rnp); 69 /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ 70 } 71 } 72 73 void do_new_if(char *argv[], struct task_struct *t_in, struct rcu_node *rnp) 74 { 75 struct task_struct *t; 76 77 /* --- Code under test, new. --- */ 78 if (rnp->exp_tasks == NULL && 79 (rnp->gp_tasks == NULL || 80 rnp->boost_tasks != NULL || 81 rnp->qsmask != 0 && 82 ULONG_CMP_LT(jiffies, rnp->boost_time))) { 83 rcu_initiate_boost_trace(rnp); 84 /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ 85 } else { 86 if (rnp->exp_tasks == NULL) 87 rnp->boost_tasks = rnp->gp_tasks; 88 /* raw_spin_unlock_irqrestore(&rnp->lock, flags); */ 89 t = rnp->boost_kthread_task; 90 if (t) 91 rcu_wake_cond(t, rnp->boost_kthread_status); 92 } 93 } 94 95 void check(void) 96 { 97 assert(rn1.exp_tasks == rn2.exp_tasks); 98 assert(rn1.gp_tasks == rn2.gp_tasks); 99 assert(rn1.boost_tasks == rn2.boost_tasks); 100 assert(rn1.qsmask == rn2.qsmask); 101 assert(rn1.boost_time == rn2.boost_time); 102 assert(rn1.boost_kthread_status == rn2.boost_kthread_status); 103 assert(rn1.rcu_initiate_boost_trace_been_called == 104 rn2.rcu_initiate_boost_trace_been_called); 105 assert(t1.boost_kthread_status == t2.boost_kthread_status); 106 assert(t1.rcu_wake_cond_been_called == t2.rcu_wake_cond_been_called); 107 } 108 109 int main(int argc, char *argv[]) 110 { 111 initialize(argv, &t1, &rn1); 112 initialize(argv, &t2, &rn2); 113 check(); 114 115 do_old_if(argv, &t1, &rn1); 116 do_new_if(argv, &t2, &rn2); 117 check(); 118 }