Skip to content

Commit c70fb67

Browse files
committed
qsbr: Apply editorial changes
1 parent 3e8a096 commit c70fb67

File tree

2 files changed

+33
-36
lines changed

2 files changed

+33
-36
lines changed

qsbr/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
all:
2-
$(CC) -Wall -o main main.c -lpthread
2+
$(CC) -Wall -g -o main main.c -lpthread
33

44
indent:
55
clang-format -i main.c

qsbr/main.c

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
* Note that this interface is asynchronous.
6464
*/
6565

66-
#include <errno.h>
6766
#include <pthread.h>
6867
#include <stdint.h>
6968
#include <stdlib.h>
@@ -93,7 +92,6 @@ qsbr_t *qsbr_create(void)
9392
qsbr_t *qs;
9493
int ret = posix_memalign((void **) &qs, CACHE_LINE_SIZE, sizeof(qsbr_t));
9594
if (ret != 0) {
96-
errno = ret;
9795
return NULL;
9896
}
9997
memset(qs, 0, sizeof(qsbr_t));
@@ -114,17 +112,15 @@ void qsbr_destroy(qsbr_t *qs)
114112
free(qs);
115113
}
116114

117-
/* qsbr_register: register the current thread for QSBR. */
115+
/* qsbr_register: register the current thread for QSBR */
118116
int qsbr_register(qsbr_t *qs)
119117
{
120118
qsbr_tls_t *t = pthread_getspecific(qs->tls_key);
121119
if (unlikely(!t)) {
122-
int ret =
123-
posix_memalign((void **) &t, CACHE_LINE_SIZE, sizeof(qsbr_tls_t));
124-
if (ret != 0) {
125-
errno = ret;
120+
/* posix_memalign() returns zero on success */
121+
if (posix_memalign((void **) &t, CACHE_LINE_SIZE, sizeof(qsbr_tls_t)) !=
122+
0)
126123
return -1;
127-
}
128124
pthread_setspecific(qs->tls_key, t);
129125
}
130126
memset(t, 0, sizeof(qsbr_tls_t));
@@ -193,29 +189,25 @@ bool qsbr_sync(qsbr_t *qs, qsbr_epoch_t target)
193189
#include <stdio.h>
194190
#include <unistd.h>
195191

196-
static unsigned nsec = 10; /* seconds */
197-
198192
static pthread_barrier_t barrier;
199193
static unsigned n_workers;
200194
static volatile bool stop;
201195

202196
typedef struct {
203197
unsigned int *ptr;
204198
bool visible;
205-
char _pad[CACHE_LINE_SIZE - 8 - 4 - 4 - 8];
206-
} data_struct_t;
207-
208-
#define N_DS 4
199+
} __attribute__((__aligned__(CACHE_LINE_SIZE))) data_t;
209200

210201
#define MAGIC 0xDEADBEEF
211-
static unsigned magic_val = MAGIC;
202+
static const unsigned magic_val = MAGIC;
212203

213204
static qsbr_t *qsbr;
214205

215-
static data_struct_t ds[N_DS] __attribute__((__aligned__(CACHE_LINE_SIZE)));
206+
#define N_DATA 4
207+
static data_t data[N_DATA];
216208
static uint64_t destructions;
217209

218-
static void access_obj(data_struct_t *obj)
210+
static void access_obj(data_t *obj)
219211
{
220212
if (atomic_load_explicit(&obj->visible, memory_order_relaxed)) {
221213
atomic_thread_fence(memory_order_acquire);
@@ -224,21 +216,22 @@ static void access_obj(data_struct_t *obj)
224216
}
225217
}
226218

227-
static void mock_insert_obj(data_struct_t *obj)
219+
static void insert_obj(data_t *obj)
228220
{
229-
obj->ptr = &magic_val;
221+
obj->ptr = (unsigned int *) &magic_val;
230222
assert(!obj->visible);
231223
atomic_thread_fence(memory_order_release);
232224
atomic_store_explicit(&obj->visible, true, memory_order_relaxed);
233225
}
234226

235-
static void mock_remove_obj(data_struct_t *obj)
227+
static void remove_obj(data_t *obj)
236228
{
237229
assert(obj->visible);
238-
obj->visible = false;
230+
// obj->visible = false;
231+
atomic_store_explicit(&obj->visible, false, memory_order_relaxed);
239232
}
240233

241-
static void mock_destroy_obj(data_struct_t *obj)
234+
static void destroy_obj(data_t *obj)
242235
{
243236
obj->ptr = NULL;
244237
destructions++;
@@ -248,7 +241,7 @@ static void mock_destroy_obj(data_struct_t *obj)
248241

249242
static void qsbr_writer(unsigned target)
250243
{
251-
data_struct_t *obj = &ds[target];
244+
data_t *obj = &data[target];
252245

253246
if (obj->visible) {
254247
/* The data structure is visible. First, ensure it is no longer
@@ -257,9 +250,9 @@ static void qsbr_writer(unsigned target)
257250
unsigned count = SPINLOCK_BACKOFF_MIN;
258251
qsbr_epoch_t target_epoch;
259252

260-
mock_remove_obj(obj);
253+
remove_obj(obj);
261254

262-
/* QSBR synchronization barrier. */
255+
/* QSBR synchronization barrier */
263256
target_epoch = qsbr_barrier(qsbr);
264257
while (!qsbr_sync(qsbr, target_epoch)) {
265258
SPINLOCK_BACKOFF(count);
@@ -271,12 +264,12 @@ static void qsbr_writer(unsigned target)
271264
}
272265

273266
/* It is safe to "destroy" the object now. */
274-
mock_destroy_obj(obj);
267+
destroy_obj(obj);
275268
} else {
276269
/* Data structure is not globally visible. Set the value and make it
277270
* visible (think of the "insert" semantics).
278271
*/
279-
mock_insert_obj(obj);
272+
insert_obj(obj);
280273
}
281274
}
282275

@@ -285,7 +278,8 @@ static void *qsbr_stress(void *arg)
285278
const unsigned id = (uintptr_t) arg;
286279
unsigned n = 0;
287280

288-
qsbr_register(qsbr);
281+
if (qsbr_register(qsbr) != 0)
282+
abort();
289283

290284
/* There are NCPU threads concurrently reading data and a single writer
291285
* thread (ID 0) modifying data. The writer will modify the pointer used
@@ -294,7 +288,7 @@ static void *qsbr_stress(void *arg)
294288
*/
295289
pthread_barrier_wait(&barrier);
296290
while (!stop) {
297-
n = (n + 1) & (N_DS - 1);
291+
n = (n + 1) & (N_DATA - 1);
298292
if (id == 0) {
299293
qsbr_writer(n);
300294
continue;
@@ -308,7 +302,7 @@ static void *qsbr_stress(void *arg)
308302
* Incorrect reclamation mechanism would lead to the crash in the
309303
* following pointer dereference.
310304
*/
311-
access_obj(&ds[n]);
305+
access_obj(&data[n]);
312306
qsbr_checkpoint(qsbr);
313307
}
314308
pthread_barrier_wait(&barrier);
@@ -325,12 +319,14 @@ static void leave(int sig)
325319

326320
typedef void *(*func_t)(void *);
327321

322+
static unsigned nsec = 10; /* seconds */
323+
328324
static void run_test(func_t func)
329325
{
330326
struct sigaction sigalarm;
331327

332328
n_workers = sysconf(_SC_NPROCESSORS_CONF);
333-
pthread_t *thr = calloc(n_workers, sizeof(pthread_t));
329+
pthread_t *threads = calloc(n_workers, sizeof(pthread_t));
334330
pthread_barrier_init(&barrier, NULL, n_workers);
335331
stop = false;
336332

@@ -339,21 +335,22 @@ static void run_test(func_t func)
339335
int ret = sigaction(SIGALRM, &sigalarm, NULL);
340336
assert(ret == 0);
341337

342-
memset(&ds, 0, sizeof(ds));
338+
memset(&data, 0, sizeof(data));
343339
qsbr = qsbr_create();
344340
destructions = 0;
345341

346342
alarm(nsec); /* Spin the test */
347343

348344
for (unsigned i = 0; i < n_workers; i++) {
349-
if ((errno = pthread_create(&thr[i], NULL, func,
350-
(void *) (uintptr_t) i)) != 0) {
345+
if (pthread_create(&threads[i], NULL, func, (void *) (uintptr_t) i) !=
346+
0) {
351347
exit(EXIT_FAILURE);
352348
}
353349
}
354350
for (unsigned i = 0; i < n_workers; i++)
355-
pthread_join(thr[i], NULL);
351+
pthread_join(threads[i], NULL);
356352
pthread_barrier_destroy(&barrier);
353+
free(threads);
357354
printf("# %" PRIu64 "\n", destructions);
358355

359356
qsbr_destroy(qsbr);

0 commit comments

Comments
 (0)