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 }