uatomic/x86: Remove redundant memory barriers
[urcu.git] / tests / benchmark / test_perthreadlock_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
102d1d23 5/*
102d1d23 6 * Per thread locks - test program
102d1d23
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>
102d1d23 17#include <pthread.h>
94b343fd 18#include <errno.h>
833dbdb6 19
ec4e58a3 20#include <urcu/arch.h>
01477510 21#include <urcu/assert.h>
102d1d23 22
94df6318 23#include "thread-id.h"
102d1d23 24
ec4e58a3 25#include <urcu.h>
102d1d23
MD
26
27struct test_array {
28 int a;
29};
30
31static struct test_array test_array = { 8 };
32
33struct per_thread_lock {
34 pthread_mutex_t lock;
06f22bdb 35} __attribute__((aligned(CAA_CACHE_LINE_SIZE))); /* cache-line aligned */
102d1d23
MD
36
37static struct per_thread_lock *per_thread_lock;
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
2c9689fe
MD
47static int num_read;
48static int num_write;
102d1d23 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;
102d1d23 55
61c3fb60 56static
102d1d23
MD
57void *thr_reader(void *arg)
58{
3fa18286 59 caa_cycles_t time1, time2;
102d1d23 60 long tidx = (long)arg;
4104b71f
MD
61 unsigned int i, j;
62 int ret;
102d1d23 63
94df6318
MD
64 printf("thread_begin %s, tid %lu\n",
65 "reader", urcu_get_thread_id());
102d1d23
MD
66 sleep(2);
67
06f22bdb 68 time1 = caa_get_cycles();
102d1d23
MD
69 for (i = 0; i < OUTER_READ_LOOP; i++) {
70 for (j = 0; j < INNER_READ_LOOP; j++) {
4104b71f
MD
71 ret = pthread_mutex_lock(&per_thread_lock[tidx].lock);
72 if (ret) {
73 perror("Error in pthread mutex lock");
74 exit(-1);
75 }
01477510 76 urcu_posix_assert(test_array.a == 8);
4104b71f
MD
77 ret = pthread_mutex_unlock(&per_thread_lock[tidx].lock);
78 if (ret) {
79 perror("Error in pthread mutex unlock");
80 exit(-1);
81 }
102d1d23
MD
82 }
83 }
06f22bdb 84 time2 = caa_get_cycles();
102d1d23
MD
85
86 reader_time[tidx] = time2 - time1;
87
88 sleep(2);
94df6318
MD
89 printf("thread_end %s, tid %lu\n",
90 "reader", urcu_get_thread_id());
102d1d23
MD
91 return ((void*)1);
92
93}
94
61c3fb60 95static
102d1d23
MD
96void *thr_writer(void *arg)
97{
4104b71f 98 caa_cycles_t time1, time2;
83e334d0 99 unsigned int i, j;
102d1d23 100 long tidx;
4104b71f 101 int ret;
102d1d23 102
94df6318
MD
103 printf("thread_begin %s, tid %lu\n",
104 "writer", urcu_get_thread_id());
102d1d23
MD
105 sleep(2);
106
107 for (i = 0; i < OUTER_WRITE_LOOP; i++) {
108 for (j = 0; j < INNER_WRITE_LOOP; j++) {
06f22bdb 109 time1 = caa_get_cycles();
102d1d23 110 for (tidx = 0; tidx < NR_READ; tidx++) {
4104b71f
MD
111 ret = pthread_mutex_lock(&per_thread_lock[tidx].lock);
112 if (ret) {
113 perror("Error in pthread mutex lock");
114 exit(-1);
115 }
102d1d23
MD
116 }
117 test_array.a = 8;
118 for (tidx = NR_READ - 1; tidx >= 0; tidx--) {
4104b71f
MD
119 ret = pthread_mutex_unlock(&per_thread_lock[tidx].lock);
120 if (ret) {
121 perror("Error in pthread mutex unlock");
122 exit(-1);
123 }
102d1d23 124 }
06f22bdb 125 time2 = caa_get_cycles();
102d1d23 126 writer_time[(unsigned long)arg] += time2 - time1;
fc606a74 127 usleep(1);
102d1d23 128 }
102d1d23
MD
129 }
130
94df6318
MD
131 printf("thread_end %s, tid %lu\n",
132 "writer", urcu_get_thread_id());
102d1d23
MD
133 return ((void*)2);
134}
135
2c9689fe 136int main(int argc, char **argv)
102d1d23
MD
137{
138 int err;
2c9689fe 139 pthread_t *tid_reader, *tid_writer;
102d1d23
MD
140 void *tret;
141 int i;
3fa18286
MD
142 caa_cycles_t tot_rtime = 0;
143 caa_cycles_t tot_wtime = 0;
102d1d23 144
2c9689fe
MD
145 if (argc < 2) {
146 printf("Usage : %s nr_readers nr_writers\n", argv[0]);
147 exit(-1);
148 }
149 num_read = atoi(argv[1]);
150 num_write = atoi(argv[2]);
151
9aa14175
MD
152 reader_time = calloc(num_read, sizeof(*reader_time));
153 writer_time = calloc(num_write, sizeof(*writer_time));
154 tid_reader = calloc(num_read, sizeof(*tid_reader));
155 tid_writer = calloc(num_write, sizeof(*tid_writer));
2c9689fe 156
94df6318
MD
157 printf("thread %-6s, tid %lu\n",
158 "main", urcu_get_thread_id());
102d1d23
MD
159
160 per_thread_lock = malloc(sizeof(struct per_thread_lock) * NR_READ);
161
162 for (i = 0; i < NR_READ; i++) {
163 pthread_mutex_init(&per_thread_lock[i].lock, NULL);
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 free(per_thread_lock);
197
2c9689fe
MD
198 free(reader_time);
199 free(writer_time);
200 free(tid_reader);
201 free(tid_writer);
202
102d1d23
MD
203 return 0;
204}
This page took 0.055234 seconds and 4 git commands to generate.