uatomic/x86: Remove redundant memory barriers
[urcu.git] / tests / benchmark / test_rwlock_timing.c
1 // SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 //
3 // SPDX-License-Identifier: GPL-2.0-or-later
4
5 /*
6 * Userspace RCU library - test program
7 */
8
9 #include <stdio.h>
10 #include <pthread.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
16 #include <stdio.h>
17 #include <pthread.h>
18 #include <errno.h>
19
20 #include <urcu/arch.h>
21 #include <urcu/assert.h>
22
23 #include "thread-id.h"
24
25 #include <urcu.h>
26
27 struct test_array {
28 int a;
29 };
30
31 /*
32 * static rwlock initializer is broken on Cygwin. Use runtime
33 * initialization.
34 */
35 pthread_rwlock_t lock;
36
37 static struct test_array test_array = { 8 };
38
39 #define OUTER_READ_LOOP 200U
40 #define INNER_READ_LOOP 100000U
41 #define READ_LOOP ((unsigned long long)OUTER_READ_LOOP * INNER_READ_LOOP)
42
43 #define OUTER_WRITE_LOOP 10U
44 #define INNER_WRITE_LOOP 200U
45 #define WRITE_LOOP ((unsigned long long)OUTER_WRITE_LOOP * INNER_WRITE_LOOP)
46
47 static int num_read;
48 static int num_write;
49
50 #define NR_READ num_read
51 #define NR_WRITE num_write
52
53 static caa_cycles_t __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *reader_time;
54 static caa_cycles_t __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *writer_time;
55
56 static
57 void *thr_reader(void *arg)
58 {
59 unsigned int i, j;
60 int ret;
61 caa_cycles_t time1, time2;
62
63 printf("thread_begin %s, tid %lu\n",
64 "reader", urcu_get_thread_id());
65 sleep(2);
66
67 time1 = caa_get_cycles();
68 for (i = 0; i < OUTER_READ_LOOP; i++) {
69 for (j = 0; j < INNER_READ_LOOP; j++) {
70 ret = pthread_rwlock_rdlock(&lock);
71 if (ret) {
72 fprintf(stderr, "reader pthread_rwlock_rdlock: %s\n", strerror(ret));
73 abort();
74 }
75
76 urcu_posix_assert(test_array.a == 8);
77
78 ret = pthread_rwlock_unlock(&lock);
79 if (ret) {
80 fprintf(stderr, "reader pthread_rwlock_unlock: %s\n", strerror(ret));
81 abort();
82 }
83 }
84 }
85 time2 = caa_get_cycles();
86
87 reader_time[(unsigned long)arg] = time2 - time1;
88
89 sleep(2);
90 printf("thread_end %s, tid %lu\n",
91 "reader", urcu_get_thread_id());
92 return ((void*)1);
93
94 }
95
96 static
97 void *thr_writer(void *arg)
98 {
99 unsigned int i, j;
100 int ret;
101 caa_cycles_t time1, time2;
102
103 printf("thread_begin %s, tid %lu\n",
104 "writer", urcu_get_thread_id());
105 sleep(2);
106
107 for (i = 0; i < OUTER_WRITE_LOOP; i++) {
108 for (j = 0; j < INNER_WRITE_LOOP; j++) {
109 time1 = caa_get_cycles();
110 ret = pthread_rwlock_wrlock(&lock);
111 if (ret) {
112 fprintf(stderr, "writer pthread_rwlock_wrlock: %s\n", strerror(ret));
113 abort();
114 }
115
116 test_array.a = 8;
117
118 ret = pthread_rwlock_unlock(&lock);
119 if (ret) {
120 fprintf(stderr, "writer pthread_rwlock_unlock: %s\n", strerror(ret));
121 abort();
122 }
123
124 time2 = caa_get_cycles();
125 writer_time[(unsigned long)arg] += time2 - time1;
126 usleep(1);
127 }
128 }
129
130 printf("thread_end %s, tid %lu\n",
131 "writer", urcu_get_thread_id());
132 return ((void*)2);
133 }
134
135 int main(int argc, char **argv)
136 {
137 int err;
138 pthread_t *tid_reader, *tid_writer;
139 void *tret;
140 int i;
141 caa_cycles_t tot_rtime = 0;
142 caa_cycles_t tot_wtime = 0;
143
144 if (argc < 2) {
145 printf("Usage : %s nr_readers nr_writers\n", argv[0]);
146 exit(-1);
147 }
148 num_read = atoi(argv[1]);
149 num_write = atoi(argv[2]);
150
151 err = pthread_rwlock_init(&lock, NULL);
152 if (err != 0) {
153 fprintf(stderr, "pthread_rwlock_init: (%d) %s\n", err, strerror(err));
154 exit(1);
155 }
156
157 reader_time = calloc(num_read, sizeof(*reader_time));
158 writer_time = calloc(num_write, sizeof(*writer_time));
159 tid_reader = calloc(num_read, sizeof(*tid_reader));
160 tid_writer = calloc(num_write, sizeof(*tid_writer));
161
162 printf("thread %-6s, tid %lu\n",
163 "main", urcu_get_thread_id());
164
165 for (i = 0; i < NR_READ; i++) {
166 err = pthread_create(&tid_reader[i], NULL, thr_reader,
167 (void *)(long)i);
168 if (err != 0)
169 exit(1);
170 }
171 for (i = 0; i < NR_WRITE; i++) {
172 err = pthread_create(&tid_writer[i], NULL, thr_writer,
173 (void *)(long)i);
174 if (err != 0)
175 exit(1);
176 }
177
178 sleep(10);
179
180 for (i = 0; i < NR_READ; i++) {
181 err = pthread_join(tid_reader[i], &tret);
182 if (err != 0)
183 exit(1);
184 tot_rtime += reader_time[i];
185 }
186 for (i = 0; i < NR_WRITE; i++) {
187 err = pthread_join(tid_writer[i], &tret);
188 if (err != 0)
189 exit(1);
190 tot_wtime += writer_time[i];
191 }
192 printf("Time per read : %g cycles\n",
193 (double)tot_rtime / ((double)NR_READ * (double)READ_LOOP));
194 printf("Time per write : %g cycles\n",
195 (double)tot_wtime / ((double)NR_WRITE * (double)WRITE_LOOP));
196
197 err = pthread_rwlock_destroy(&lock);
198 if (err != 0) {
199 fprintf(stderr, "pthread_rwlock_destroy: (%d) %s\n", err, strerror(err));
200 exit(1);
201 }
202 free(reader_time);
203 free(writer_time);
204 free(tid_reader);
205 free(tid_writer);
206
207 return 0;
208 }
This page took 0.033888 seconds and 5 git commands to generate.