Skip to content

Instantly share code, notes, and snippets.

@kostikbel
Created October 8, 2021 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kostikbel/a070e7a3d39768f09adcd82630ec2071 to your computer and use it in GitHub Desktop.
Save kostikbel/a070e7a3d39768f09adcd82630ec2071 to your computer and use it in GitHub Desktop.
/* $Id: membar_test.c,v 1.4 2021/10/08 12:33:32 kostik Exp kostik $ */
#include <sys/types.h>
#ifndef OLDSYSTEM
#include <sys/membarrier.h>
#endif
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#ifdef OLDSYSTEM
#define MEMBARRIER_CMD_QUERY 0x00000000
#define MEMBARRIER_CMD_GLOBAL 0x00000001
#define MEMBARRIER_CMD_GLOBAL_EXPEDITED 0x00000002
#define MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED 0x00000004
#define MEMBARRIER_CMD_PRIVATE_EXPEDITED 0x00000008
#define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED 0x00000010
#define MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE 0x00000020
#define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE 0x00000040
int membarrier(int, unsigned, int);
int
membarrier(int cmd __unused, unsigned flags __unused, int cpu_id __unused)
{
errno = ENOSYS;
return (-1);
}
#endif
static const int nrepeats = 1000000;
static void *
test_private_expedited_thr_func(void *arg)
{
atomic_int *done;
done = arg;
while (atomic_load_explicit(done, memory_order_relaxed) == 0)
;
return (NULL);
}
static void
test_private_expedited(const char *title, int cmd_reg, int cmd)
{
int error, ncpus, i;
atomic_int done;
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
if (ncpus == -1)
err(1, "ncpus");
error = membarrier(cmd_reg, 0, 0);
if (error == -1)
err(1, "register priv expedited");
int nthreads = ncpus * 2;
printf("starting %s on %d cpus (%d threads), %d calls\n",
title, ncpus, nthreads, nrepeats);
pthread_t thrs[nthreads];
atomic_store_explicit(&done, 0, memory_order_relaxed);
for (i = 0; i < nthreads; i++) {
error = pthread_create(&thrs[i], NULL,
test_private_expedited_thr_func, &done);
if (error != 0)
errc(1, error, "pthread_create");
}
for (i = 0; i < nrepeats; i++)
membarrier(cmd, 0, 0);
atomic_store_explicit(&done, 1, memory_order_relaxed);
for (i = 0; i < nthreads; i++) {
error = pthread_join(thrs[i], NULL);
if (error != 0)
errc(1, error, "pthread_join");
}
}
int
main(void)
{
int res;
res = membarrier(MEMBARRIER_CMD_QUERY, 0, 0);
if (res == -1)
err(1, "query");
printf("supported commands %#x\n", res);
if ((res & MEMBARRIER_CMD_PRIVATE_EXPEDITED) != 0)
test_private_expedited("private expedited",
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
MEMBARRIER_CMD_PRIVATE_EXPEDITED);
if ((res & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) != 0)
test_private_expedited("private expedited core sync",
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment