11 typedef struct thread_tag {
12 int thread_num;
13 pthread_t thread_id;
14 int updates;
15 int reads;
16 int interval;
17 } thread_t;
18
19 /*
20 * Read/write lock and shared data.
21 */
22 typedef struct data_tag {
23 rwlock_t lock;
24 int data;
25 int updates;
26 } data_t;
27
28 thread_t threads[THREADS];
29 data_t data[DATASIZE];
30
31 /*
32 * Thread start routine that uses read/write locks.
33 */
34 void *thread_routine (void *arg)
35 {
36 thread_t *self = (thread_t*)arg;
37 int repeats = 0;
38 int iteration;
39 int element = 0;
40 int status;
41
42 for (iteration = 0; iteration < ITERATIONS; iteration++) {
43 /*
44 * Each "self->interval" iterations, perform an
45 * update operation (write lock instead of read
46 * lock).
47 */
48 if ((iteration % self->interval) == 0) {
49 status = rwl_writelock (&data[element].lock);
50 if (status != 0)
51 err_abort (status, "Write lock");
52 data[element].data = self->thread_num;
53 data[element].updates++;
54 self->updates++;
55 status = rwl_writeunlock(&data[element].lock);
56 if (status != 0)
57 err_abort (status, "Write unlock");
58 } else {
59 /*
60 * Look at the current data element to see whether
61 * the current thread last updated it. Count the
62 * times, to report later.
63 */
64 status = rwl_readlock (&data[element].lock);
65 if (status != 0)
66 err_abort (status, "Read lock");
67 self->reads++;
68 if (data[element].data == self->thread_num)
69 repeats++;
70 status = rwl_readunlock (&data[element].lock);
71 if (status != 0)
72 err_abort (status, "Read unlock");
73 }
74 element++;
75 if (element >= DATASIZE)
76 element = 0;
77 }
78
79 if (repeats > 0)
80 printf (
81 "Thread %d found unchanged elements %d times\n",
82 self->thread_num, repeats);
83 return NULL;
84 }
85
86 int main (int argc, char *argv[])
87 {
88 int count;
89 int data_count;
90 int status;
91 unsigned int seed = 1;
92 int thread_updates = 0;
93 int data_updates = 0;
94
95 #ifdef sun
96 /*
97 * On Solaris 2.5, threads are not timesliced. To ensure
98 * that our threads can run concurrently, we need to
99 * increase the concurrency level to THREADS.
100 */
101 DPRINTF (("Setting concurrency level to %d\n", THREADS));
102 thr_setconcurrency (THREADS);
103 #endif
104
105 /*
106 * Initialize the shared data.
107 */
108 for (data_count = 0; data_count < DATASIZE; data_count++) {
109 data[data_count].data = 0;
110 data[data_count].updates = 0;
111 status = rwl_init (&data[data_count].lock);
112 if (status != 0)
113 err_abort (status, "Init rw lock");
114 }
115
116 /*