/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
* (C) 2008 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/*
* Uncomment this definition to disable the OPA library and instead use naive
* (non-atomic) operations. This should cause failures.
*/
/*
#define OPA_TEST_NAIVE
*/
#include "opa_test.h"
/*
* Uncomment these lines to disable only memory barriers, while leaving the rest
* of the OPA functions intact.
*/
/*
#ifdef OPA_write_barrier
#undef OPA_write_barrier
#endif
#define OPA_write_barrier() ((void) 0)
#ifdef OPA_read_barrier
#undef OPA_read_barrier
#endif
#define OPA_read_barrier() ((void) 0)
#ifdef OPA_read_write_barrier
#undef OPA_read_write_barrier
#endif
#define OPA_read_write_barrier() ((void) 0)
*/
/* Definitions for test_barriers_linear_array */
#define LINEAR_ARRAY_NITER 4000000
#define LINEAR_ARRAY_LEN 100
typedef struct {
OPA_int_t *shared_array;
int master_thread; /* Whether this is the master thread */
} linear_array_t;
/* Definitions for test_barriers_variables */
#define VARIABLES_NITER 4000000
#define VARIABLES_NVAR 10
typedef struct {
OPA_int_t *v_0;
OPA_int_t *v_1;
OPA_int_t *v_2;
OPA_int_t *v_3;
OPA_int_t *v_4;
OPA_int_t *v_5;
OPA_int_t *v_6;
OPA_int_t *v_7;
OPA_int_t *v_8;
OPA_int_t *v_9;
int master_thread; /* Whether this is the master thread */
} variables_t;
/* Definitions for test_barriers_scattered_array */
#define SCATTERED_ARRAY_SIZE 100000
#define SCATTERED_ARRAY_LOCS {254, 85920, 255, 35529, 75948, 75947, 253, 99999, 11111, 11112}
/*-------------------------------------------------------------------------
* Function: test_barriers_sanity
*
* Purpose: Essentially tests that memory barriers don't interfere with
* normal single threaded operations. If this fails then
* something is *very* wrong.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
* goodell@, December 1, 2011: load-acquire/store-release sanity test
*
*-------------------------------------------------------------------------
*/
static int test_barriers_sanity(void)
{
OPA_int_t a;
int b;
OPA_ptr_t op;
void *p;
struct {
int i;
} obj = {
0xabcdef};
TESTING("memory barrier sanity", 0);
/* Store 0 in a and b */
OPA_store_int(&a, 0);
OPA_write_barrier();
b = 0;
OPA_read_write_barrier();
/* Add INT_MIN */
OPA_add_int(&a, INT_MIN);
OPA_read_write_barrier();
b += INT_MIN;
OPA_read_write_barrier();
/* Increment */
OPA_incr_int(&a);
OPA_read_write_barrier();
b++;
OPA_read_write_barrier();
/* Add INT_MAX */
OPA_add_int(&a, INT_MAX);
OPA_read_write_barrier();
b += INT_MAX;
OPA_read_write_barrier();
/* Decrement */
OPA_decr_int(&a);
OPA_read_write_barrier();
b--;
OPA_read_write_barrier();
/* Load the result, verify it is correct */
if (OPA_load_int(&a) != INT_MIN + 1 + INT_MAX - 1)
TEST_ERROR;
OPA_read_barrier();
if (b != OPA_load_int(&a))
TEST_ERROR;
OPA_read_write_barrier();
/* Barriers are now the opposite of what they were before */
/* Store 0 in a */
OPA_store_int(&a, 0);
OPA_read_barrier();
b = 0;
/* Add INT_MAX */
OPA_add_int(&a, INT_MAX);
b += INT_MAX;
/* Decrement */
OPA_decr_int(&a);
b--;
/* Add INT_MIN */
OPA_add_int(&a, INT_MIN);
b += INT_MIN;
/* Increment */
OPA_incr_int(&a);
b++;
/* Load the result, verify it is correct */
if (OPA_load_int(&a) != INT_MAX - 1 + INT_MIN + 1)
TEST_ERROR;
OPA_write_barrier();
if (b != OPA_load_int(&a))
TEST_ERROR;
/* now provide a quick sanity check that the load-acquire/store-release code
* works (as in, successfully compiles and runs single-threaded, no
* multithreading is checked here) */
OPA_store_int(&a, 5);
b = OPA_load_acquire_int(&a);
if (b != 5)
TEST_ERROR;
OPA_store_release_int(&a, 0);
b = OPA_load_acquire_int(&a);
if (b != 0)
TEST_ERROR;
OPA_store_ptr(&op, &obj);
p = OPA_load_acquire_ptr(&op);
if (p != &obj)
TEST_ERROR;
OPA_store_release_ptr(&op, NULL);
p = OPA_load_acquire_ptr(&op);
if (p != NULL)
TEST_ERROR;
PASSED();
return 0;
error:
return 1;
} /* end test_barriers_sanity() */
#if defined(OPA_HAVE_PTHREAD_H)
/*-------------------------------------------------------------------------
* Function: test_barriers_linear_array_write
*
* Purpose: Helper (write thread) routine for test_barriers_linear_array.
* Writes successive increments to the shared array with memory
* barriers between each increment.
*
* Return: NULL
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void *test_barriers_linear_array_write(void *_udata)
{
linear_array_t *udata = (linear_array_t *) _udata;
OPA_int_t *shared_array = udata->shared_array;
int niter = LINEAR_ARRAY_NITER / LINEAR_ARRAY_LEN / iter_reduction[curr_test];
int i, j;
/* Main loop */
for (i = 0; i < niter; i++)
for (j = 0; j < LINEAR_ARRAY_LEN; j++) {
/* Increment the value in the array */
OPA_incr_int(&shared_array[j]);
/* Write barrier */
OPA_write_barrier();
} /* end for */
/* Exit */
if (udata->master_thread)
return (NULL);
else
pthread_exit(NULL);
} /* end test_barriers_linear_array_write() */
/*-------------------------------------------------------------------------
* Function: test_barriers_linear_array_read
*
* Purpose: Helper (read thread) routine for test_barriers_linear_array.
* Reads successive increments from the shared array in reverse
* order with memory barriers between each read.
*
* Return: Success: NULL
* Failure: non-NULL
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void *test_barriers_linear_array_read(void *_udata)
{
linear_array_t *udata = (linear_array_t *) _udata;
OPA_int_t *shared_array = udata->shared_array;
int read_buffer[LINEAR_ARRAY_LEN];
int niter = LINEAR_ARRAY_NITER / LINEAR_ARRAY_LEN / iter_reduction[curr_test];
int nerrors = 0; /* Number of errors */
int i, j;
/* Main loop */
for (i = 0; i < niter; i++) {
/* Load the values from the array into the read buffer in reverse
* order */
for (j = LINEAR_ARRAY_LEN - 1; j >= 0; j--) {
read_buffer[j] = OPA_load_int(&shared_array[j]);
/* Read barrier */
OPA_read_barrier();
} /* end for */
/* Verify that the values never increase when read back in forward
* order */
for (j = 1; j < LINEAR_ARRAY_LEN; j++)
if (read_buffer[j - 1] < read_buffer[j]) {
printf(" Unexpected load: %d is less than %d\n",
read_buffer[j - 1], read_buffer[j]);
nerrors++;
} /* end if */
} /* end for */
/* Any non-NULL exit value indicates an error, we use (void *) 1 here */
if (udata->master_thread)
return (nerrors ? (void *) 1 : NULL);
else
pthread_exit(nerrors ? (void *) 1 : NULL);
} /* end test_barriers_linear_array_read() */
#endif /* OPA_HAVE_PTHREAD_H */
/*-------------------------------------------------------------------------
* Function: test_barriers_linear_array
*
* Purpose: Tests memory barriers using simultaneous reads and writes to
* a linear array. Launches nthreads threads split into read
* and write threads.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int test_barriers_linear_array(void)
{
#if defined(OPA_HAVE_PTHREAD_H)
pthread_t *threads = NULL; /* Threads */
pthread_attr_t ptattr; /* Thread attributes */
linear_array_t *thread_data = NULL; /* User data structs for each thread */
static OPA_int_t shared_array[LINEAR_ARRAY_LEN]; /* Array to operate on */
void *ret; /* Thread return value */
unsigned nthreads = num_threads[curr_test];
int nerrors = 0; /* number of errors */
int i;
TESTING("memory barriers with linear array", nthreads);
/* Allocate array of threads */
if (NULL == (threads = (pthread_t *) malloc(nthreads * sizeof(pthread_t))))
TEST_ERROR;
/* Allocate array of thread data */
if (NULL == (thread_data = (linear_array_t *) calloc(nthreads, sizeof(linear_array_t))))
TEST_ERROR;
/* Set threads to be joinable */
pthread_attr_init(&ptattr);
pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_JOINABLE);
/* Initialize shared array */
for (i = 0; i < LINEAR_ARRAY_LEN; i++)
OPA_store_int(&shared_array[i], 0);
/* Initialize thread data structs */
for (i = 0; i < nthreads; i++)
thread_data[i].shared_array = shared_array;
thread_data[nthreads - 1].master_thread = 1;
/* Create the threads. */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_create(&threads[i], &ptattr, test_barriers_linear_array_write, &thread_data[i]))
TEST_ERROR;
if (++i < (nthreads - 1))
if (pthread_create(&threads[i], &ptattr, test_barriers_linear_array_read,
&thread_data[i]))
TEST_ERROR;
} /* end for */
if (nthreads % 2) {
if (test_barriers_linear_array_write(&thread_data[(nthreads - 1)]))
nerrors++;
} else if (test_barriers_linear_array_read(&thread_data[(nthreads - 1)]))
nerrors++;
/* Free the attribute */
if (pthread_attr_destroy(&ptattr))
TEST_ERROR;
/* Join the threads */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_join(threads[i], &ret))
TEST_ERROR;
if (ret)
nerrors++;
} /* end for */
/* Check for errors */
if (nerrors)
FAIL_OP_ERROR(printf(" Unexpected return from %d thread%s\n", nerrors,
nerrors == 1 ? "" : "s"));
/* Free memory */
free(threads);
PASSED();
#else /* OPA_HAVE_PTHREAD_H */
TESTING("memory barriers with linear array", 0);
SKIPPED();
puts(" pthread.h not available");
#endif /* OPA_HAVE_PTHREAD_H */
return 0;
#if defined(OPA_HAVE_PTHREAD_H)
error:
if (threads)
free(threads);
return 1;
#endif /* OPA_HAVE_PTHREAD_H */
} /* end test_barriers_linear_array() */
#if defined(OPA_HAVE_PTHREAD_H)
/*-------------------------------------------------------------------------
* Function: test_barriers_variables_write
*
* Purpose: Helper (write thread) routine for test_barriers_variables.
* Writes successive increments to the shared variables with
* memory barriers between each increment.
*
* Return: NULL
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void *test_barriers_variables_write(void *_udata)
{
variables_t *udata = (variables_t *) _udata;
OPA_int_t *v_0, *v_1, *v_2, *v_3, *v_4, *v_5, *v_6, *v_7, *v_8, *v_9;
int niter = VARIABLES_NITER / VARIABLES_NVAR / iter_reduction[curr_test];
int i;
/* Make local copies of the pointers in udata, to maximize the chance of the
* compiler reordering instructions (if the barriers don't work) */
v_0 = udata->v_0;
v_1 = udata->v_1;
v_2 = udata->v_2;
v_3 = udata->v_3;
v_4 = udata->v_4;
v_5 = udata->v_5;
v_6 = udata->v_6;
v_7 = udata->v_7;
v_8 = udata->v_8;
v_9 = udata->v_9;
/* Main loop */
for (i = 0; i < niter; i++) {
/* Incrememnt the variables in forward order */
OPA_incr_int(v_0);
OPA_write_barrier();
OPA_incr_int(v_1);
OPA_write_barrier();
OPA_incr_int(v_2);
OPA_write_barrier();
OPA_incr_int(v_3);
OPA_write_barrier();
OPA_incr_int(v_4);
OPA_write_barrier();
OPA_incr_int(v_5);
OPA_write_barrier();
OPA_incr_int(v_6);
OPA_write_barrier();
OPA_incr_int(v_7);
OPA_write_barrier();
OPA_incr_int(v_8);
OPA_write_barrier();
OPA_incr_int(v_9);
OPA_write_barrier();
} /* end for */
/* Exit */
if (udata->master_thread)
return (NULL);
else
pthread_exit(NULL);
} /* end test_barriers_variables_write() */
/*-------------------------------------------------------------------------
* Function: test_barriers_variables_read
*
* Purpose: Helper (read thread) routine for test_barriers_variables.
* Reads successive increments from the variables in reverse
* order with memory barriers between each read.
*
* Return: Success: NULL
* Failure: non-NULL
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static void *test_barriers_variables_read(void *_udata)
{
variables_t *udata = (variables_t *) _udata;
OPA_int_t *v_0, *v_1, *v_2, *v_3, *v_4, *v_5, *v_6, *v_7, *v_8, *v_9;
int read_buffer[VARIABLES_NVAR];
int niter = VARIABLES_NITER / VARIABLES_NVAR / iter_reduction[curr_test];
int nerrors = 0; /* Number of errors */
int i, j;
/* Make local copies of the pointers in udata, to maximize the chance of the
* compiler reordering instructions (if the barriers don't work) */
v_0 = udata->v_0;
v_1 = udata->v_1;
v_2 = udata->v_2;
v_3 = udata->v_3;
v_4 = udata->v_4;
v_5 = udata->v_5;
v_6 = udata->v_6;
v_7 = udata->v_7;
v_8 = udata->v_8;
v_9 = udata->v_9;
/* Main loop */
for (i = 0; i < niter; i++) {
/* Load the values from the array into the read buffer in reverse
* order*/
read_buffer[9] = OPA_load_int(v_9);
OPA_read_barrier();
read_buffer[8] = OPA_load_int(v_8);
OPA_read_barrier();
read_buffer[7] = OPA_load_int(v_7);
OPA_read_barrier();
read_buffer[6] = OPA_load_int(v_6);
OPA_read_barrier();
read_buffer[5] = OPA_load_int(v_5);
OPA_read_barrier();
read_buffer[4] = OPA_load_int(v_4);
OPA_read_barrier();
read_buffer[3] = OPA_load_int(v_3);
OPA_read_barrier();
read_buffer[2] = OPA_load_int(v_2);
OPA_read_barrier();
read_buffer[1] = OPA_load_int(v_1);
OPA_read_barrier();
read_buffer[0] = OPA_load_int(v_0);
OPA_read_barrier();
/* Verify that the values never increase when read back in forward
* order */
for (j = 1; j < VARIABLES_NVAR; j++)
if (read_buffer[j - 1] < read_buffer[j]) {
printf(" Unexpected load: %d is less than %d\n",
read_buffer[j - 1], read_buffer[j]);
nerrors++;
} /* end if */
} /* end for */
/* Any non-NULL exit value indicates an error, we use (void *) 1 here */
if (udata->master_thread)
return (nerrors ? (void *) 1 : NULL);
else
pthread_exit(nerrors ? (void *) 1 : NULL);
} /* end test_barriers_variables_read() */
#endif /* OPA_HAVE_PTHREAD_H */
/*-------------------------------------------------------------------------
* Function: test_barriers_variables
*
* Purpose: Tests memory barriers using simultaneous reads and writes to
* a linear array. Launches nthreads threads split into read
* and write threads.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int test_barriers_variables(void)
{
#if defined(OPA_HAVE_PTHREAD_H)
pthread_t *threads = NULL; /* Threads */
pthread_attr_t ptattr; /* Thread attributes */
variables_t *thread_data = NULL; /* User data structs for each thread */
OPA_int_t v_0, v_1, v_2, v_3, v_4, v_5, v_6, v_7, v_8, v_9;
void *ret; /* Thread return value */
unsigned nthreads = num_threads[curr_test];
int nerrors = 0; /* number of errors */
int i;
TESTING("memory barriers with local variables", nthreads);
/* Allocate array of threads */
if (NULL == (threads = (pthread_t *) malloc(nthreads * sizeof(pthread_t))))
TEST_ERROR;
/* Allocate array of thread data */
if (NULL == (thread_data = (variables_t *) calloc(nthreads, sizeof(variables_t))))
TEST_ERROR;
/* Set threads to be joinable */
pthread_attr_init(&ptattr);
pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_JOINABLE);
/* Initialize shared variables */
OPA_store_int(&v_0, 0);
OPA_store_int(&v_1, 0);
OPA_store_int(&v_2, 0);
OPA_store_int(&v_3, 0);
OPA_store_int(&v_4, 0);
OPA_store_int(&v_5, 0);
OPA_store_int(&v_6, 0);
OPA_store_int(&v_7, 0);
OPA_store_int(&v_8, 0);
OPA_store_int(&v_9, 0);
/* Initialize thread data structs */
for (i = 0; i < nthreads; i++) {
thread_data[i].v_0 = &v_0;
thread_data[i].v_1 = &v_1;
thread_data[i].v_2 = &v_2;
thread_data[i].v_3 = &v_3;
thread_data[i].v_4 = &v_4;
thread_data[i].v_5 = &v_5;
thread_data[i].v_6 = &v_6;
thread_data[i].v_7 = &v_7;
thread_data[i].v_8 = &v_8;
thread_data[i].v_9 = &v_9;
} /* end for */
thread_data[nthreads - 1].master_thread = 1;
/* Create the threads. */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_create(&threads[i], &ptattr, test_barriers_variables_write, &thread_data[i]))
TEST_ERROR;
if (++i < (nthreads - 1))
if (pthread_create(&threads[i], &ptattr, test_barriers_variables_read, &thread_data[i]))
TEST_ERROR;
} /* end for */
if (nthreads % 2) {
if (test_barriers_variables_write(&thread_data[(nthreads - 1)]))
nerrors++;
} else if (test_barriers_variables_read(&thread_data[(nthreads - 1)]))
nerrors++;
/* Free the attribute */
if (pthread_attr_destroy(&ptattr))
TEST_ERROR;
/* Join the threads */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_join(threads[i], &ret))
TEST_ERROR;
if (ret)
nerrors++;
} /* end for */
/* Check for errors */
if (nerrors)
FAIL_OP_ERROR(printf(" Unexpected return from %d thread%s\n", nerrors,
nerrors == 1 ? "" : "s"));
/* Free memory */
free(threads);
PASSED();
#else /* OPA_HAVE_PTHREAD_H */
TESTING("memory barriers with local variables", 0);
SKIPPED();
puts(" pthread.h not available");
#endif /* OPA_HAVE_PTHREAD_H */
return 0;
#if defined(OPA_HAVE_PTHREAD_H)
error:
if (threads)
free(threads);
return 1;
#endif /* OPA_HAVE_PTHREAD_H */
} /* end test_barriers_variables() */
/*-------------------------------------------------------------------------
* Function: test_barriers_scattered_array
*
* Purpose: Tests memory barriers using simultaneous reads and writes to
* locations scattered in an array. Launches nthreads threads
* split into read and write threads.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int test_barriers_scattered_array(void)
{
#if defined(OPA_HAVE_PTHREAD_H)
pthread_t *threads = NULL; /* Threads */
pthread_attr_t ptattr; /* Thread attributes */
variables_t *thread_data = NULL; /* User data structs for each thread */
static OPA_int_t shared_array[SCATTERED_ARRAY_SIZE];
int shared_locs[VARIABLES_NVAR] = SCATTERED_ARRAY_LOCS;
void *ret; /* Thread return value */
unsigned nthreads = num_threads[curr_test];
int nerrors = 0; /* number of errors */
int i;
TESTING("memory barriers with scattered array", nthreads);
/* Allocate array of threads */
if (NULL == (threads = (pthread_t *) malloc(nthreads * sizeof(pthread_t))))
TEST_ERROR;
/* Allocate array of thread data */
if (NULL == (thread_data = (variables_t *) calloc(nthreads, sizeof(variables_t))))
TEST_ERROR;
/* Set threads to be joinable */
pthread_attr_init(&ptattr);
pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_JOINABLE);
/* Initialize shared variables */
for (i = 0; i < VARIABLES_NVAR; i++)
OPA_store_int(&shared_array[shared_locs[i]], 0);
/* Initialize thread data structs */
for (i = 0; i < nthreads; i++) {
thread_data[i].v_0 = &shared_array[shared_locs[0]];
thread_data[i].v_1 = &shared_array[shared_locs[1]];
thread_data[i].v_2 = &shared_array[shared_locs[2]];
thread_data[i].v_3 = &shared_array[shared_locs[3]];
thread_data[i].v_4 = &shared_array[shared_locs[4]];
thread_data[i].v_5 = &shared_array[shared_locs[5]];
thread_data[i].v_6 = &shared_array[shared_locs[6]];
thread_data[i].v_7 = &shared_array[shared_locs[7]];
thread_data[i].v_8 = &shared_array[shared_locs[8]];
thread_data[i].v_9 = &shared_array[shared_locs[9]];
} /* end for */
thread_data[nthreads - 1].master_thread = 1;
/* Create the threads. We will use the helper routines for
* test_barriers_variables. */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_create(&threads[i], &ptattr, test_barriers_variables_write, &thread_data[i]))
TEST_ERROR;
if (++i < (nthreads - 1))
if (pthread_create(&threads[i], &ptattr, test_barriers_variables_read, &thread_data[i]))
TEST_ERROR;
} /* end for */
if (nthreads % 2) {
if (test_barriers_variables_write(&thread_data[(nthreads - 1)]))
nerrors++;
} else if (test_barriers_variables_read(&thread_data[(nthreads - 1)]))
nerrors++;
/* Free the attribute */
if (pthread_attr_destroy(&ptattr))
TEST_ERROR;
/* Join the threads */
for (i = 0; i < (nthreads - 1); i++) {
if (pthread_join(threads[i], &ret))
TEST_ERROR;
if (ret)
nerrors++;
} /* end for */
/* Check for errors */
if (nerrors)
FAIL_OP_ERROR(printf(" Unexpected return from %d thread%s\n", nerrors,
nerrors == 1 ? "" : "s"));
/* Free memory */
free(threads);
PASSED();
#else /* OPA_HAVE_PTHREAD_H */
TESTING("memory barriers with scattered array", 0);
SKIPPED();
puts(" pthread.h not available");
#endif /* OPA_HAVE_PTHREAD_H */
return 0;
#if defined(OPA_HAVE_PTHREAD_H)
error:
if (threads)
free(threads);
return 1;
#endif /* OPA_HAVE_PTHREAD_H */
} /* end test_barriers_scattered_array() */
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Tests the opa memory barriers
*
* Return: Success: exit(0)
*
* Failure: exit(1)
*
* Programmer: Neil Fortner
* Wednesday, April 1, 2009
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int main(int argc, char **argv)
{
unsigned nerrors = 0;
#if defined(OPA_USE_LOCK_BASED_PRIMITIVES)
OPA_emulation_ipl_t shm_lock;
OPA_Interprocess_lock_init(&shm_lock, 1 /*isLeader */);
#endif
/* Simple tests */
nerrors += test_barriers_sanity();
/* Loop over test configurations */
for (curr_test = 0; curr_test < num_thread_tests; curr_test++) {
/* Don't test with only 1 thread */
if (num_threads[curr_test] == 1)
continue;
/* Threaded tests */
nerrors += test_barriers_linear_array();
nerrors += test_barriers_variables();
nerrors += test_barriers_scattered_array();
} /* end for */
if (nerrors)
goto error;
printf("All barriers tests passed.\n");
return 0;
error:
if (!nerrors)
nerrors = 1;
printf("***** %d BARRIERS TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S");
return 1;
} /* end main() */