1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "dscr.h"
16
17static unsigned long dscr;
18static unsigned long sequence;
19static unsigned long result[THREADS];
20
21static void *do_test(void *in)
22{
23 unsigned long thread = (unsigned long)in;
24 unsigned long i;
25
26 for (i = 0; i < COUNT; i++) {
27 unsigned long d, cur_dscr, cur_dscr_usr;
28 unsigned long s1, s2;
29
30 s1 = ACCESS_ONCE(sequence);
31 if (s1 & 1)
32 continue;
33 rmb();
34
35 d = dscr;
36 cur_dscr = get_dscr();
37 cur_dscr_usr = get_dscr_usr();
38
39 rmb();
40 s2 = sequence;
41
42 if (s1 != s2)
43 continue;
44
45 if (cur_dscr != d) {
46 fprintf(stderr, "thread %ld kernel DSCR should be %ld "
47 "but is %ld\n", thread, d, cur_dscr);
48 result[thread] = 1;
49 pthread_exit(&result[thread]);
50 }
51
52 if (cur_dscr_usr != d) {
53 fprintf(stderr, "thread %ld user DSCR should be %ld "
54 "but is %ld\n", thread, d, cur_dscr_usr);
55 result[thread] = 1;
56 pthread_exit(&result[thread]);
57 }
58 }
59 result[thread] = 0;
60 pthread_exit(&result[thread]);
61}
62
63int dscr_default(void)
64{
65 pthread_t threads[THREADS];
66 unsigned long i, *status[THREADS];
67 unsigned long orig_dscr_default;
68
69 orig_dscr_default = get_default_dscr();
70
71
72 dscr = 1;
73 set_default_dscr(dscr);
74
75
76 for (i = 0; i < THREADS; i++) {
77 if (pthread_create(&threads[i], NULL, do_test, (void *)i)) {
78 perror("pthread_create() failed");
79 goto fail;
80 }
81 }
82
83 srand(getpid());
84
85
86 for (i = 0; i < COUNT; i++) {
87 double ret = uniform_deviate(rand());
88
89 if (ret < 0.0001) {
90 sequence++;
91 wmb();
92
93 dscr++;
94 if (dscr > DSCR_MAX)
95 dscr = 0;
96
97 set_default_dscr(dscr);
98
99 wmb();
100 sequence++;
101 }
102 }
103
104
105 for (i = 0; i < THREADS; i++) {
106 if (pthread_join(threads[i], (void **)&(status[i]))) {
107 perror("pthread_join() failed");
108 goto fail;
109 }
110
111 if (*status[i]) {
112 printf("%ldth thread failed to join with %ld status\n",
113 i, *status[i]);
114 goto fail;
115 }
116 }
117 set_default_dscr(orig_dscr_default);
118 return 0;
119fail:
120 set_default_dscr(orig_dscr_default);
121 return 1;
122}
123
124int main(int argc, char *argv[])
125{
126 return test_harness(dscr_default, "dscr_default_test");
127}
128