uatomic/x86: Remove redundant memory barriers
[urcu.git] / tests / benchmark / test_rwlock_timing.c
CommitLineData
ce29b371
MJ
1// SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2//
3// SPDX-License-Identifier: GPL-2.0-or-later
4
20bf310a 5/*
20bf310a 6 * Userspace RCU library - test program
20bf310a
MD
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>
20bf310a 17#include <pthread.h>
94b343fd
PM
18#include <errno.h>
19
ec4e58a3 20#include <urcu/arch.h>
01477510 21#include <urcu/assert.h>
20bf310a 22
94df6318 23#include "thread-id.h"
20bf310a 24
ec4e58a3 25#include <urcu.h>
20bf310a
MD
26
27struct test_array {
28 int a;
29};
30
89a6a9ce
MJ
31/*
32 * static rwlock initializer is broken on Cygwin. Use runtime
33 * initialization.
34 */
35pthread_rwlock_t lock;
20bf310a
MD
36
37static 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
102d1d23
MD
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)
20bf310a 46
2c9689fe
MD
47static int num_read;
48static int num_write;
20bf310a 49
2c9689fe
MD
50#define NR_READ num_read
51#define NR_WRITE num_write
52
3fa18286
MD
53static caa_cycles_t __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *reader_time;
54static caa_cycles_t __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *writer_time;
20bf310a 55
61c3fb60 56static
20bf310a
MD
57void *thr_reader(void *arg)
58{
83e334d0
MJ
59 unsigned int i, j;
60 int ret;
3fa18286 61 caa_cycles_t time1, time2;
20bf310a 62
94df6318
MD
63 printf("thread_begin %s, tid %lu\n",
64 "reader", urcu_get_thread_id());
20bf310a
MD
65 sleep(2);
66
06f22bdb 67 time1 = caa_get_cycles();
20bf310a
MD
68 for (i = 0; i < OUTER_READ_LOOP; i++) {
69 for (j = 0; j < INNER_READ_LOOP; j++) {
89a6a9ce
MJ
70 ret = pthread_rwlock_rdlock(&lock);
71 if (ret) {
72 fprintf(stderr, "reader pthread_rwlock_rdlock: %s\n", strerror(ret));
73 abort();
74 }
75
01477510 76 urcu_posix_assert(test_array.a == 8);
89a6a9ce
MJ
77
78 ret = pthread_rwlock_unlock(&lock);
79 if (ret) {
80 fprintf(stderr, "reader pthread_rwlock_unlock: %s\n", strerror(ret));
81 abort();
82 }
20bf310a
MD
83 }
84 }
06f22bdb 85 time2 = caa_get_cycles();
20bf310a
MD
86
87 reader_time[(unsigned long)arg] = time2 - time1;
88
89 sleep(2);
94df6318
MD
90 printf("thread_end %s, tid %lu\n",
91 "reader", urcu_get_thread_id());
20bf310a
MD
92 return ((void*)1);
93
94}
95
61c3fb60 96static
20bf310a
MD
97void *thr_writer(void *arg)
98{
83e334d0
MJ
99 unsigned int i, j;
100 int ret;
3fa18286 101 caa_cycles_t time1, time2;
20bf310a 102
94df6318
MD
103 printf("thread_begin %s, tid %lu\n",
104 "writer", urcu_get_thread_id());
20bf310a
MD
105 sleep(2);
106
102d1d23
MD
107 for (i = 0; i < OUTER_WRITE_LOOP; i++) {
108 for (j = 0; j < INNER_WRITE_LOOP; j++) {
06f22bdb 109 time1 = caa_get_cycles();
89a6a9ce
MJ
110 ret = pthread_rwlock_wrlock(&lock);
111 if (ret) {
112 fprintf(stderr, "writer pthread_rwlock_wrlock: %s\n", strerror(ret));
113 abort();
114 }
115
102d1d23 116 test_array.a = 8;
89a6a9ce
MJ
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
06f22bdb 124 time2 = caa_get_cycles();
102d1d23
MD
125 writer_time[(unsigned long)arg] += time2 - time1;
126 usleep(1);
127 }
20bf310a
MD
128 }
129
94df6318
MD
130 printf("thread_end %s, tid %lu\n",
131 "writer", urcu_get_thread_id());
20bf310a
MD
132 return ((void*)2);
133}
134
2c9689fe 135int main(int argc, char **argv)
20bf310a
MD
136{
137 int err;
2c9689fe 138 pthread_t *tid_reader, *tid_writer;
20bf310a
MD
139 void *tret;
140 int i;
3fa18286
MD
141 caa_cycles_t tot_rtime = 0;
142 caa_cycles_t tot_wtime = 0;
20bf310a 143
2c9689fe
MD
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
89a6a9ce
MJ
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
9aa14175
MD
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));
2c9689fe 161
94df6318
MD
162 printf("thread %-6s, tid %lu\n",
163 "main", urcu_get_thread_id());
20bf310a
MD
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++) {
102d1d23
MD
172 err = pthread_create(&tid_writer[i], NULL, thr_writer,
173 (void *)(long)i);
20bf310a
MD
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);
102d1d23 184 tot_rtime += reader_time[i];
20bf310a
MD
185 }
186 for (i = 0; i < NR_WRITE; i++) {
187 err = pthread_join(tid_writer[i], &tret);
188 if (err != 0)
189 exit(1);
102d1d23 190 tot_wtime += writer_time[i];
20bf310a
MD
191 }
192 printf("Time per read : %g cycles\n",
102d1d23
MD
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));
20bf310a 196
89a6a9ce
MJ
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 }
2c9689fe
MD
202 free(reader_time);
203 free(writer_time);
204 free(tid_reader);
205 free(tid_writer);
206
20bf310a
MD
207 return 0;
208}
This page took 0.055916 seconds and 4 git commands to generate.