* Clean up some problems with the atomic operation interface discovered
during testing. In particular, we can't have a cmpset macro that can deal with pointers without some really evil voodoo. So have a different macro for pointers * Add more detailed testing of the atomics using AM's test framework. More to come... This commit was SVN r4191.
Этот коммит содержится в:
родитель
b80698eff4
Коммит
9f61d1d8a3
@ -1489,5 +1489,7 @@ AC_CONFIG_FILES([
|
|||||||
src/tools/ompid/Makefile
|
src/tools/ompid/Makefile
|
||||||
src/tools/openmpi/Makefile
|
src/tools/openmpi/Makefile
|
||||||
src/tools/wrappers/Makefile
|
src/tools/wrappers/Makefile
|
||||||
|
|
||||||
|
src/asm/test/Makefile
|
||||||
])
|
])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
include $(top_srcdir)/config/Makefile.options
|
include $(top_srcdir)/config/Makefile.options
|
||||||
|
|
||||||
|
SUBDIRS = . test
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# This is a bit complicated. If there is anything in the library,
|
# This is a bit complicated. If there is anything in the library,
|
||||||
@ -57,13 +59,6 @@ EXTRA_DIST = \
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
TESTS = atomic-test
|
|
||||||
check_PROGRAMS = atomic-test
|
|
||||||
atomic_test_SOURCES = atomic-test.c
|
|
||||||
atomic_test_LDADD = libasm.la
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
rm -f atomic-asm.s
|
rm -f atomic-asm.s
|
||||||
|
|
||||||
|
79
src/asm/test/Makefile.am
Обычный файл
79
src/asm/test/Makefile.am
Обычный файл
@ -0,0 +1,79 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
# All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
# All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(top_srcdir)/config/Makefile.options
|
||||||
|
|
||||||
|
noinst_HEADERS = atomic_test.h
|
||||||
|
|
||||||
|
TESTS = \
|
||||||
|
atomic_barrier \
|
||||||
|
atomic_spinlock_serial \
|
||||||
|
atomic_spinlock_2 \
|
||||||
|
atomic_spinlock_5 \
|
||||||
|
atomic_spinlock_8 \
|
||||||
|
atomic_cmpset_32_serial \
|
||||||
|
atomic_cmpset_64_serial \
|
||||||
|
atomic-test
|
||||||
|
|
||||||
|
check_PROGRAMS = \
|
||||||
|
atomic_barrier \
|
||||||
|
atomic_spinlock_serial \
|
||||||
|
atomic_spinlock_2 \
|
||||||
|
atomic_spinlock_5 \
|
||||||
|
atomic_spinlock_8 \
|
||||||
|
atomic_cmpset_32_serial \
|
||||||
|
atomic_cmpset_64_serial \
|
||||||
|
atomic-test
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
atomic_barrier_SOURCES = atomic_barrier.c
|
||||||
|
atomic_barrier_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
atomic_spinlock_serial_SOURCES = \
|
||||||
|
atomic_spinlock_serial.c \
|
||||||
|
atomic_spinlock.c
|
||||||
|
atomic_spinlock_serial_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
atomic_spinlock_2_SOURCES = \
|
||||||
|
atomic_spinlock_2.c \
|
||||||
|
atomic_spinlock.c
|
||||||
|
atomic_spinlock_2_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
atomic_spinlock_5_SOURCES = \
|
||||||
|
atomic_spinlock_5.c \
|
||||||
|
atomic_spinlock.c
|
||||||
|
atomic_spinlock_5_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
atomic_spinlock_8_SOURCES = \
|
||||||
|
atomic_spinlock_8.c \
|
||||||
|
atomic_spinlock.c
|
||||||
|
atomic_spinlock_8_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
atomic_cmpset_32_serial_SOURCES = atomic_cmpset_32_serial.c
|
||||||
|
atomic_cmpset_32_serial_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
atomic_cmpset_64_serial_SOURCES = atomic_cmpset_64_serial.c
|
||||||
|
atomic_cmpset_64_serial_LDADD = ../libasm.la
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
atomic_test_SOURCES = atomic-test.c
|
||||||
|
atomic_test_LDADD = ../libasm.la
|
@ -1,6 +1,20 @@
|
|||||||
#undef OMPI_BUILDING
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
#include "ompi_config.h"
|
#include "ompi_config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
@ -13,102 +27,6 @@
|
|||||||
|
|
||||||
#include "include/sys/atomic.h"
|
#include "include/sys/atomic.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* A testing support library to provide uniform reporting output
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int ompi_n_tests;
|
|
||||||
static int ompi_n_success;
|
|
||||||
static int ompi_n_failures;
|
|
||||||
static char *ompi_description;
|
|
||||||
|
|
||||||
static void test_init(char *a)
|
|
||||||
{
|
|
||||||
/* local variables */
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
/* save the descriptive string */
|
|
||||||
len = strlen(a);
|
|
||||||
ompi_description = (char *) malloc(len + 1);
|
|
||||||
assert(ompi_description);
|
|
||||||
|
|
||||||
strcpy(ompi_description, a);
|
|
||||||
|
|
||||||
/* initialize counters */
|
|
||||||
ompi_n_tests = 0;
|
|
||||||
ompi_n_success = 0;
|
|
||||||
ompi_n_failures = 0;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void test_success(void)
|
|
||||||
{
|
|
||||||
ompi_n_tests++;
|
|
||||||
ompi_n_success++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void test_failure(char *a)
|
|
||||||
{
|
|
||||||
ompi_n_tests++;
|
|
||||||
ompi_n_failures++;
|
|
||||||
|
|
||||||
fprintf(stderr, " Failure : ");
|
|
||||||
fprintf(stderr, a);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int test_verify_int(int expected_result, int test_result)
|
|
||||||
{
|
|
||||||
int return_value;
|
|
||||||
|
|
||||||
return_value = 1;
|
|
||||||
if (expected_result != test_result) {
|
|
||||||
test_failure("Comparison failure");
|
|
||||||
fprintf(stderr, " Expected result: %d\n", expected_result);
|
|
||||||
fprintf(stderr, " Test result: %d\n", test_result);
|
|
||||||
fflush(stderr);
|
|
||||||
return_value = 0;
|
|
||||||
} else {
|
|
||||||
test_success();
|
|
||||||
}
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int test_finalize(void)
|
|
||||||
{
|
|
||||||
int return_value;
|
|
||||||
|
|
||||||
return_value = 1;
|
|
||||||
|
|
||||||
if (ompi_n_tests == ompi_n_success) {
|
|
||||||
fprintf(stderr, "SUPPORT: OMPI Test Passed: %s: (%d tests)\n",
|
|
||||||
ompi_description, ompi_n_tests);
|
|
||||||
fflush(stderr);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr,
|
|
||||||
"SUPPORT: OMPI Test failed: %s (%d of %d failed)\n",
|
|
||||||
ompi_description, ompi_n_failures, ompi_n_tests);
|
|
||||||
fflush(stderr);
|
|
||||||
return_value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* note this is for additional output that does NOT go to STDERR but STDOUT */
|
|
||||||
static void test_comment (char* userstr)
|
|
||||||
{
|
|
||||||
fprintf(stdout, "%s:%s\n", ompi_description, userstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* default options */
|
/* default options */
|
||||||
|
|
||||||
@ -122,7 +40,7 @@ int32_t val32;
|
|||||||
int32_t old32;
|
int32_t old32;
|
||||||
int32_t new32;
|
int32_t new32;
|
||||||
|
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
volatile int64_t vol64;
|
volatile int64_t vol64;
|
||||||
int64_t val64;
|
int64_t val64;
|
||||||
int64_t old64;
|
int64_t old64;
|
||||||
@ -144,7 +62,7 @@ static void help(void)
|
|||||||
printf("Usage: threadtest [flags]\n"
|
printf("Usage: threadtest [flags]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Flags may be any of\n"
|
" Flags may be any of\n"
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
" -l do 64-bit tests\n"
|
" -l do 64-bit tests\n"
|
||||||
#endif
|
#endif
|
||||||
" -r NREPS number of repetitions\n"
|
" -r NREPS number of repetitions\n"
|
||||||
@ -153,7 +71,7 @@ static void help(void)
|
|||||||
" -h print this info\n" "\n"
|
" -h print this info\n" "\n"
|
||||||
" Numbers may be postfixed with 'k' or 'm'\n\n");
|
" Numbers may be postfixed with 'k' or 'm'\n\n");
|
||||||
|
|
||||||
#ifndef ENABLE_64_BIT
|
#ifndef OMPI_HAVE_ATOMIC_MATH_64
|
||||||
printf(" 64-bit tests are not enabled in this build of the tests\n\n");
|
printf(" 64-bit tests are not enabled in this build of the tests\n\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -216,7 +134,7 @@ static void *thread_main(void *arg)
|
|||||||
|
|
||||||
for (i = 0; i < nreps; i++) {
|
for (i = 0; i < nreps; i++) {
|
||||||
ompi_atomic_add_32(&val32, 5);
|
ompi_atomic_add_32(&val32, 5);
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
if (enable_64_bit_tests) {
|
if (enable_64_bit_tests) {
|
||||||
ompi_atomic_add_64(&val64, 5);
|
ompi_atomic_add_64(&val64, 5);
|
||||||
}
|
}
|
||||||
@ -231,20 +149,20 @@ static void *thread_main(void *arg)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
#if HAVE_PTHREAD_H
|
||||||
int tid;
|
int tid;
|
||||||
pthread_t *th;
|
pthread_t *th;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* option processing */
|
/* option processing */
|
||||||
|
|
||||||
test_init("atomic operations");
|
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "hlr:t:v")) != -1) {
|
while ((c = getopt(argc, argv, "hlr:t:v")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
help();
|
help();
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
enable_64_bit_tests = 1;
|
enable_64_bit_tests = 1;
|
||||||
#else
|
#else
|
||||||
usage();
|
usage();
|
||||||
@ -280,144 +198,144 @@ int main(int argc, char *argv[])
|
|||||||
/* -- cmpset 32-bit tests -- */
|
/* -- cmpset 32-bit tests -- */
|
||||||
|
|
||||||
vol32 = 42, old32 = 42, new32 = 50;
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_32(&vol32, old32, new32), 1);
|
assert(ompi_atomic_cmpset_32(&vol32, old32, new32) == 1);
|
||||||
test_verify_int(vol32, new32);
|
assert(vol32 == new32);
|
||||||
|
|
||||||
vol32 = 42, old32 = 420, new32 = 50;
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_32(&vol32, old32, new32), 0);
|
assert(ompi_atomic_cmpset_32(&vol32, old32, new32) == 0);
|
||||||
test_verify_int(vol32, 42);
|
assert(vol32 == 42);
|
||||||
|
|
||||||
vol32 = 42, old32 = 42, new32 = 50;
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq_32(&vol32, old32, new32), 1);
|
assert(ompi_atomic_cmpset_acq_32(&vol32, old32, new32) == 1);
|
||||||
test_verify_int(vol32, new32);
|
assert(vol32 == new32);
|
||||||
|
|
||||||
vol32 = 42, old32 = 420, new32 = 50;
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq_32(&vol32, old32, new32), 0);
|
assert(ompi_atomic_cmpset_acq_32(&vol32, old32, new32) == 0);
|
||||||
test_verify_int(vol32, 42);
|
assert(vol32 == 42);
|
||||||
|
|
||||||
vol32 = 42, old32 = 42, new32 = 50;
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel_32(&vol32, old32, new32), 1);
|
assert(ompi_atomic_cmpset_rel_32(&vol32, old32, new32) == 1);
|
||||||
test_verify_int(vol32, new32);
|
assert(vol32 == new32);
|
||||||
|
|
||||||
vol32 = 42, old32 = 420, new32 = 50;
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel_32(&vol32, old32, new32), 0);
|
assert(ompi_atomic_cmpset_rel_32(&vol32, old32, new32) == 0);
|
||||||
test_verify_int(vol32, 42);
|
assert(vol32 == 42);
|
||||||
|
|
||||||
/* -- cmpset 64-bit tests -- */
|
/* -- cmpset 64-bit tests -- */
|
||||||
|
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
if (enable_64_bit_tests) {
|
if (enable_64_bit_tests) {
|
||||||
verbose("64 bit serial tests\n");
|
verbose("64 bit serial tests\n");
|
||||||
vol64 = 42, old64 = 42, new64 = 50;
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
test_verify_int(1, ompi_atomic_cmpset_64(&vol64, old64, new64));
|
assert(1 == ompi_atomic_cmpset_64(&vol64, old64, new64));
|
||||||
test_verify_int(new64, vol64);
|
assert(new64 == vol64);
|
||||||
|
|
||||||
verbose("64 bit serial test 2\n");
|
verbose("64 bit serial test 2\n");
|
||||||
vol64 = 42, old64 = 420, new64 = 50;
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_64(&vol64, old64, new64), 0);
|
assert(ompi_atomic_cmpset_64(&vol64, old64, new64) == 0);
|
||||||
test_verify_int(vol64, 42);
|
assert(vol64 == 42);
|
||||||
|
|
||||||
vol64 = 42, old64 = 42, new64 = 50;
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq_64(&vol64, old64, new64), 1);
|
assert(ompi_atomic_cmpset_acq_64(&vol64, old64, new64) == 1);
|
||||||
test_verify_int(vol64, new64);
|
assert(vol64 == new64);
|
||||||
|
|
||||||
vol64 = 42, old64 = 420, new64 = 50;
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq_64(&vol64, old64, new64), 0);
|
assert(ompi_atomic_cmpset_acq_64(&vol64, old64, new64) == 0);
|
||||||
test_verify_int(vol64, 42);
|
assert(vol64 == 42);
|
||||||
|
|
||||||
vol64 = 42, old64 = 42, new64 = 50;
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel_64(&vol64, old64, new64), 1);
|
assert(ompi_atomic_cmpset_rel_64(&vol64, old64, new64) == 1);
|
||||||
test_verify_int(vol64, new64);
|
assert(vol64 == new64);
|
||||||
|
|
||||||
vol64 = 42, old64 = 420, new64 = 50;
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel_64(&vol64, old64, new64), 0);
|
assert(ompi_atomic_cmpset_rel_64(&vol64, old64, new64) == 0);
|
||||||
test_verify_int(vol64, 42);
|
assert(vol64 == 42);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* -- cmpset int tests -- */
|
/* -- cmpset int tests -- */
|
||||||
|
|
||||||
volint = 42, oldint = 42, newint = 50;
|
volint = 42, oldint = 42, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset(&volint, oldint, newint), 1);
|
assert(ompi_atomic_cmpset(&volint, oldint, newint) == 1);
|
||||||
test_verify_int(volint, newint);
|
assert(volint ==newint);
|
||||||
|
|
||||||
volint = 42, oldint = 420, newint = 50;
|
volint = 42, oldint = 420, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset(&volint, oldint, newint), 0);
|
assert(ompi_atomic_cmpset(&volint, oldint, newint) == 0);
|
||||||
test_verify_int(volint, 42);
|
assert(volint == 42);
|
||||||
|
|
||||||
volint = 42, oldint = 42, newint = 50;
|
volint = 42, oldint = 42, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq(&volint, oldint, newint), 1);
|
assert(ompi_atomic_cmpset_acq(&volint, oldint, newint) == 1);
|
||||||
test_verify_int(volint, newint);
|
assert(volint == newint);
|
||||||
|
|
||||||
volint = 42, oldint = 420, newint = 50;
|
volint = 42, oldint = 420, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq(&volint, oldint, newint), 0);
|
assert(ompi_atomic_cmpset_acq(&volint, oldint, newint) == 0);
|
||||||
test_verify_int(volint, 42);
|
assert(volint == 42);
|
||||||
|
|
||||||
volint = 42, oldint = 42, newint = 50;
|
volint = 42, oldint = 42, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel(&volint, oldint, newint), 1);
|
assert(ompi_atomic_cmpset_rel(&volint, oldint, newint) == 1);
|
||||||
test_verify_int(volint, newint);
|
assert(volint == newint);
|
||||||
|
|
||||||
volint = 42, oldint = 420, newint = 50;
|
volint = 42, oldint = 420, newint = 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel(&volint, oldint, newint), 0);
|
assert(ompi_atomic_cmpset_rel(&volint, oldint, newint) == 0);
|
||||||
test_verify_int(volint, 42);
|
assert(volint == 42);
|
||||||
|
|
||||||
|
|
||||||
/* -- cmpset ptr tests -- */
|
/* -- cmpset ptr tests -- */
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset(&volptr, oldptr, newptr), 1);
|
assert(ompi_atomic_cmpset_ptr(&volptr, oldptr, newptr) == 1);
|
||||||
test_verify_int(volptr, newptr);
|
assert(volptr == newptr);
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset(&volptr, oldptr, newptr), 0);
|
assert(ompi_atomic_cmpset_ptr(&volptr, oldptr, newptr) == 0);
|
||||||
test_verify_int(volptr, (void *) 42);
|
assert(volptr == (void *) 42);
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq(&volptr, oldptr, newptr), 1);
|
assert(ompi_atomic_cmpset_acq_ptr(&volptr, oldptr, newptr) == 1);
|
||||||
test_verify_int(volptr, newptr);
|
assert(volptr == newptr);
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_acq(&volptr, oldptr, newptr), 0);
|
assert(ompi_atomic_cmpset_acq_ptr(&volptr, oldptr, newptr) == 0);
|
||||||
test_verify_int(volptr, (void *) 42);
|
assert(volptr == (void *) 42);
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel(&volptr, oldptr, newptr), 1);
|
assert(ompi_atomic_cmpset_rel_ptr(&volptr, oldptr, newptr) == 1);
|
||||||
test_verify_int(volptr, newptr);
|
assert(volptr == newptr);
|
||||||
|
|
||||||
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
|
||||||
test_verify_int(ompi_atomic_cmpset_rel(&volptr, oldptr, newptr), 0);
|
assert(ompi_atomic_cmpset_rel_ptr(&volptr, oldptr, newptr) == 0);
|
||||||
test_verify_int(volptr, (void *) 42);
|
assert(volptr == (void *) 42);
|
||||||
|
|
||||||
/* -- add_32 tests -- */
|
/* -- add_32 tests -- */
|
||||||
|
|
||||||
val32 = 42;
|
val32 = 42;
|
||||||
test_verify_int(ompi_atomic_add_32(&val32, 5), (42 + 5));
|
assert(ompi_atomic_add_32(&val32, 5) == (42 + 5));
|
||||||
test_verify_int((42 + 5), val32);
|
assert((42 + 5) == val32);
|
||||||
|
|
||||||
/* -- add_64 tests -- */
|
/* -- add_64 tests -- */
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
if (enable_64_bit_tests) {
|
if (enable_64_bit_tests) {
|
||||||
val64 = 42;
|
val64 = 42;
|
||||||
test_verify_int(ompi_atomic_add_64(&val64, 5), (42 + 5));
|
assert(ompi_atomic_add_64(&val64, 5) == (42 + 5));
|
||||||
test_verify_int((42 + 5), val64);
|
assert((42 + 5) == val64);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* -- add_int tests -- */
|
/* -- add_int tests -- */
|
||||||
|
|
||||||
valint = 42;
|
valint = 42;
|
||||||
ompi_atomic_add(&valint, 5);
|
ompi_atomic_add(&valint, 5);
|
||||||
test_verify_int((42 + 5), valint);
|
assert((42 + 5) == valint);
|
||||||
|
|
||||||
|
|
||||||
/* threaded tests */
|
/* threaded tests */
|
||||||
|
|
||||||
val32 = 0;
|
val32 = 0;
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
val64 = 0ul;
|
val64 = 0ul;
|
||||||
#endif
|
#endif
|
||||||
valint = 0;
|
valint = 0;
|
||||||
|
|
||||||
/* -- create the thread set -- */
|
/* -- create the thread set -- */
|
||||||
|
#if HAVE_PTHREAD_H
|
||||||
th = (pthread_t *) malloc(nthreads * sizeof(pthread_t));
|
th = (pthread_t *) malloc(nthreads * sizeof(pthread_t));
|
||||||
if (!th) {
|
if (!th) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
@ -443,15 +361,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
free(th);
|
free(th);
|
||||||
|
|
||||||
test_verify_int((5 * nthreads * nreps), val32);
|
assert((5 * nthreads * nreps) == val32);
|
||||||
#ifdef ENABLE_64_BIT
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
if (enable_64_bit_tests) {
|
if (enable_64_bit_tests) {
|
||||||
test_verify_int((5 * nthreads * nreps), val64);
|
assert((5 * nthreads * nreps) == val64);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
test_verify_int((5 * nthreads * nreps), valint);
|
assert((5 * nthreads * nreps) == valint);
|
||||||
|
#endif
|
||||||
test_finalize();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
36
src/asm/test/atomic_barrier.c
Обычный файл
36
src/asm/test/atomic_barrier.c
Обычный файл
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
/* there really isn't a great way to test that the barriers
|
||||||
|
actually barrier, but at least make sure they don't kill the
|
||||||
|
machine.*/
|
||||||
|
|
||||||
|
ompi_atomic_mb();
|
||||||
|
ompi_atomic_rmb();
|
||||||
|
ompi_atomic_wmb();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
56
src/asm/test/atomic_cmpset_32_serial.c
Обычный файл
56
src/asm/test/atomic_cmpset_32_serial.c
Обычный файл
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
|
||||||
|
volatile int32_t vol32;
|
||||||
|
int32_t val32;
|
||||||
|
int32_t old32;
|
||||||
|
int32_t new32;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_32(&vol32, old32, new32) == 1);
|
||||||
|
assert(vol32 == new32);
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_32(&vol32, old32, new32) == 0);
|
||||||
|
assert(vol32 == 42);
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_acq_32(&vol32, old32, new32) == 1);
|
||||||
|
assert(vol32 == new32);
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_acq_32(&vol32, old32, new32) == 0);
|
||||||
|
assert(vol32 == 42);
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 42, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_rel_32(&vol32, old32, new32) == 1);
|
||||||
|
assert(vol32 == new32);
|
||||||
|
|
||||||
|
vol32 = 42, old32 = 420, new32 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_rel_32(&vol32, old32, new32) == 0);
|
||||||
|
assert(vol32 == 42);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
61
src/asm/test/atomic_cmpset_64_serial.c
Обычный файл
61
src/asm/test/atomic_cmpset_64_serial.c
Обычный файл
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
|
||||||
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
|
volatile int64_t vol64;
|
||||||
|
int64_t val64;
|
||||||
|
int64_t old64;
|
||||||
|
int64_t new64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#if OMPI_HAVE_ATOMIC_MATH_64
|
||||||
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
|
assert(1 == ompi_atomic_cmpset_64(&vol64, old64, new64));
|
||||||
|
assert(new64 == vol64);
|
||||||
|
|
||||||
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_64(&vol64, old64, new64) == 0);
|
||||||
|
assert(vol64 == 42);
|
||||||
|
|
||||||
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_acq_64(&vol64, old64, new64) == 1);
|
||||||
|
assert(vol64 == new64);
|
||||||
|
|
||||||
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_acq_64(&vol64, old64, new64) == 0);
|
||||||
|
assert(vol64 == 42);
|
||||||
|
|
||||||
|
vol64 = 42, old64 = 42, new64 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_rel_64(&vol64, old64, new64) == 1);
|
||||||
|
assert(vol64 == new64);
|
||||||
|
|
||||||
|
vol64 = 42, old64 = 420, new64 = 50;
|
||||||
|
assert(ompi_atomic_cmpset_rel_64(&vol64, old64, new64) == 0);
|
||||||
|
assert(vol64 == 42);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return 77;
|
||||||
|
#endif
|
||||||
|
}
|
106
src/asm/test/atomic_spinlock.c
Обычный файл
106
src/asm/test/atomic_spinlock.c
Обычный файл
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#ifdef HAVE_PTHREAD_H
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int atomic_verbose = 0;
|
||||||
|
|
||||||
|
struct start_info {
|
||||||
|
int tid;
|
||||||
|
int count;
|
||||||
|
ompi_lock_t *lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void* atomic_spinlock_start(void* arg)
|
||||||
|
{
|
||||||
|
struct start_info *data = (struct start_info*) arg;
|
||||||
|
|
||||||
|
return (void*) atomic_spinlock_test(data->lock, data->count,
|
||||||
|
data->tid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
atomic_spinlock_test_th(ompi_lock_t *lock, int count, int id, int thr_count)
|
||||||
|
{
|
||||||
|
#if HAVE_PTHREAD_H
|
||||||
|
pthread_t *th;
|
||||||
|
int tid, ret = 0;
|
||||||
|
struct start_info *data;
|
||||||
|
|
||||||
|
th = (pthread_t *) malloc(thr_count * sizeof(pthread_t));
|
||||||
|
if (!th) { perror("malloc"); exit(EXIT_FAILURE); }
|
||||||
|
data = (struct start_info *) malloc(thr_count * sizeof(struct start_info));
|
||||||
|
if (!th) { perror("malloc"); exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
|
for (tid = 0; tid < thr_count; tid++) {
|
||||||
|
data[tid].tid = tid;
|
||||||
|
data[tid].count = count;
|
||||||
|
data[tid].lock = lock;
|
||||||
|
|
||||||
|
if (pthread_create(&th[tid], NULL, atomic_spinlock_start, (void *) &(data[tid])) != 0) {
|
||||||
|
perror("pthread_create");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- wait for the thread set to finish -- */
|
||||||
|
for (tid = 0; tid < thr_count; tid++) {
|
||||||
|
void *thread_return;
|
||||||
|
|
||||||
|
if (pthread_join(th[tid], &thread_return) != 0) {
|
||||||
|
perror("pthread_join");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += (int) thread_return;
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
free(th);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return 77;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
atomic_spinlock_test(ompi_lock_t *lock, int count, int id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < count ; ++i) {
|
||||||
|
ompi_atomic_lock(lock);
|
||||||
|
if (atomic_verbose) { printf("id %03d has the lock (lock)\n", id); }
|
||||||
|
ompi_atomic_unlock(lock);
|
||||||
|
|
||||||
|
while (ompi_atomic_trylock(lock)) { ; }
|
||||||
|
if (atomic_verbose) { printf("id %03d has the lock (trylock)\n", id); }
|
||||||
|
ompi_atomic_unlock(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
33
src/asm/test/atomic_spinlock_2.c
Обычный файл
33
src/asm/test/atomic_spinlock_2.c
Обычный файл
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret = 77;
|
||||||
|
ompi_lock_t lock;
|
||||||
|
|
||||||
|
ompi_atomic_init(&lock, OMPI_ATOMIC_UNLOCKED);
|
||||||
|
ret = atomic_spinlock_test_th(&lock, TEST_REPS, 0, 2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
33
src/asm/test/atomic_spinlock_5.c
Обычный файл
33
src/asm/test/atomic_spinlock_5.c
Обычный файл
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret = 77;
|
||||||
|
ompi_lock_t lock;
|
||||||
|
|
||||||
|
ompi_atomic_init(&lock, OMPI_ATOMIC_UNLOCKED);
|
||||||
|
ret = atomic_spinlock_test_th(&lock, TEST_REPS, 0, 5);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
33
src/asm/test/atomic_spinlock_8.c
Обычный файл
33
src/asm/test/atomic_spinlock_8.c
Обычный файл
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret = 77;
|
||||||
|
ompi_lock_t lock;
|
||||||
|
|
||||||
|
ompi_atomic_init(&lock, OMPI_ATOMIC_UNLOCKED);
|
||||||
|
ret = atomic_spinlock_test_th(&lock, TEST_REPS, 0, 8);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
33
src/asm/test/atomic_spinlock_serial.c
Обычный файл
33
src/asm/test/atomic_spinlock_serial.c
Обычный файл
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||||
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef OMPI_BUILDING
|
||||||
|
#include "ompi_config.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "include/sys/atomic.h"
|
||||||
|
#include "atomic_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ompi_lock_t lock;
|
||||||
|
|
||||||
|
ompi_atomic_init(&lock, OMPI_ATOMIC_UNLOCKED);
|
||||||
|
ret = atomic_spinlock_test(&lock, TEST_REPS, 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -27,10 +27,10 @@
|
|||||||
* The following #defines will be true / false based on
|
* The following #defines will be true / false based on
|
||||||
* assembly support:
|
* assembly support:
|
||||||
*
|
*
|
||||||
* \c OMPI_HAVE_MEM_BARRIER atomic memory barriers
|
* - \c OMPI_HAVE_MEM_BARRIER atomic memory barriers
|
||||||
* \c OMPI_HAVE_ATOMIC_SPINLOCKS atomic spinlocks
|
* - \c OMPI_HAVE_ATOMIC_SPINLOCKS atomic spinlocks
|
||||||
* \c OMPI_HAVE_ATOMIC_MATH_32 if 32 bit add/sub/cmpset can be done "atomicly"
|
* - \c OMPI_HAVE_ATOMIC_MATH_32 if 32 bit add/sub/cmpset can be done "atomicly"
|
||||||
* \c OMPI_HAVE_ATOMIC_MATH_64 if 32 bit add/sub/cmpset can be done "atomicly"
|
* - \c OMPI_HAVE_ATOMIC_MATH_64 if 32 bit add/sub/cmpset can be done "atomicly"
|
||||||
*
|
*
|
||||||
* Note that for the Atomic math, atomic add/sub may be implemented as
|
* Note that for the Atomic math, atomic add/sub may be implemented as
|
||||||
* C code using ompi_atomic_cmpset. The appearance of atomic
|
* C code using ompi_atomic_cmpset. The appearance of atomic
|
||||||
@ -82,6 +82,7 @@ extern "C" {
|
|||||||
#include "include/sys/sparc64/atomic.h"
|
#include "include/sys/sparc64/atomic.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DOXYGEN
|
||||||
/* compare and set operations can't really be emulated from software,
|
/* compare and set operations can't really be emulated from software,
|
||||||
so if these defines aren't already set, they should be set to 0
|
so if these defines aren't already set, they should be set to 0
|
||||||
now */
|
now */
|
||||||
@ -91,6 +92,7 @@ extern "C" {
|
|||||||
#ifndef OMPI_HAVE_ATOMIC_CMPSET_64
|
#ifndef OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
#define OMPI_HAVE_ATOMIC_CMPSET_64 0
|
#define OMPI_HAVE_ATOMIC_CMPSET_64 0
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* DOXYGEN */
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
@ -98,7 +100,7 @@ extern "C" {
|
|||||||
* but can't inline
|
* but can't inline
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef OMPI_HAVE_ATOMIC_MEM_BARRIER
|
#if !defined(OMPI_HAVE_ATOMIC_MEM_BARRIER) && !defined(DOXYGEN)
|
||||||
/* no way to emulate in C code */
|
/* no way to emulate in C code */
|
||||||
#define OMPI_HAVE_ATOMIC_MEM_BARRIER 0
|
#define OMPI_HAVE_ATOMIC_MEM_BARRIER 0
|
||||||
#endif
|
#endif
|
||||||
@ -106,16 +108,38 @@ extern "C" {
|
|||||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_MEM_BARRIER
|
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_MEM_BARRIER
|
||||||
/**
|
/**
|
||||||
* Memory barrier
|
* Memory barrier
|
||||||
|
*
|
||||||
|
* Will use system-specific features to instruct the processor and
|
||||||
|
* memory controller that all writes and reads that have been posted
|
||||||
|
* before the call to \c ompi_atomic_mb() must appear to have
|
||||||
|
* completed before the next read or write.
|
||||||
|
*
|
||||||
|
* \note This can have some expensive side effects, including flushing
|
||||||
|
* the pipeline, preventing the cpu from reordering instructions, and
|
||||||
|
* generally grinding the memory controller's performance. Use only
|
||||||
|
* if you need *both* read and write barriers.
|
||||||
*/
|
*/
|
||||||
void ompi_atomic_mb(void);
|
void ompi_atomic_mb(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read memory barrier
|
* Read memory barrier
|
||||||
|
*
|
||||||
|
* Use system-specific features to instruct the processor and memory
|
||||||
|
* conrtoller that all reads that have been posted before the call to
|
||||||
|
* \c ompi_atomic_rmb() must appear to have been completed before the
|
||||||
|
* next read. Nothing is said about the ordering of writes when using
|
||||||
|
* \c ompi_atomic_rmb().
|
||||||
*/
|
*/
|
||||||
void ompi_atomic_rmb(void);
|
void ompi_atomic_rmb(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write memory barrier.
|
* Write memory barrier.
|
||||||
|
*
|
||||||
|
* Use system-specific features to instruct the processor and memory
|
||||||
|
* conrtoller that all writes that have been posted before the call to
|
||||||
|
* \c ompi_atomic_rmb() must appear to have been completed before the
|
||||||
|
* next write. Nothing is said about the ordering of reads when using
|
||||||
|
* \c ompi_atomic_rmb().
|
||||||
*/
|
*/
|
||||||
void ompi_atomic_wmb(void);
|
void ompi_atomic_wmb(void);
|
||||||
|
|
||||||
@ -138,13 +162,12 @@ struct ompi_lock_t {
|
|||||||
};
|
};
|
||||||
typedef struct ompi_lock_t ompi_lock_t;
|
typedef struct ompi_lock_t ompi_lock_t;
|
||||||
|
|
||||||
#ifndef OMPI_HAVE_ATOMIC_SPINLOCKS
|
#if !defined(OMPI_HAVE_ATOMIC_SPINLOCKS) && !defined(DOXYGEN)
|
||||||
#define OMPI_HAVE_ATOMIC_SPINLOCKS (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64)
|
#define OMPI_HAVE_ATOMIC_SPINLOCKS (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_SPINLOCKS
|
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_SPINLOCKS
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of lock states
|
* Enumeration of lock states
|
||||||
*/
|
*/
|
||||||
@ -195,7 +218,7 @@ static inline void ompi_atomic_unlock(ompi_lock_t *lock);
|
|||||||
* Atomic math operations
|
* Atomic math operations
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef OMPI_HAVE_ATOMIC_CMPSET_32
|
#if !defined(OMPI_HAVE_ATOMIC_CMPSET_32) && !defined(DOXYGEN)
|
||||||
#define OMPI_HAVE_ATOMIC_CMPSET_32 0
|
#define OMPI_HAVE_ATOMIC_CMPSET_32 0
|
||||||
#endif
|
#endif
|
||||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_CMPSET_32
|
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
@ -208,7 +231,7 @@ int ompi_atomic_cmpset_rel_32(volatile int32_t *addr, int32_t oldval,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef OMPI_HAVE_ATOMIC_CMPSET_64
|
#if !defined(OMPI_HAVE_ATOMIC_CMPSET_64) && !defined(DOXYGEN)
|
||||||
#define OMPI_HAVE_ATOMIC_CMPSET_64 0
|
#define OMPI_HAVE_ATOMIC_CMPSET_64 0
|
||||||
#endif
|
#endif
|
||||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_CMPSET_64
|
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
@ -220,7 +243,7 @@ int ompi_atomic_cmpset_rel_64(volatile int64_t *addr, int64_t oldval,
|
|||||||
int64_t newval);
|
int64_t newval);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OMPI_HAVE_ATOMIC_MATH_32
|
#if !defined(OMPI_HAVE_ATOMIC_MATH_32) && !defined(DOXYGEN)
|
||||||
/* define to 0 for these tests. WIll fix up later. */
|
/* define to 0 for these tests. WIll fix up later. */
|
||||||
#define OMPI_HAVE_ATOMIC_MATH_32 0
|
#define OMPI_HAVE_ATOMIC_MATH_32 0
|
||||||
#endif
|
#endif
|
||||||
@ -277,11 +300,26 @@ static inline void ompi_atomic_add_xx(volatile void* addr,
|
|||||||
static inline void ompi_atomic_sub_xx(volatile void* addr,
|
static inline void ompi_atomic_sub_xx(volatile void* addr,
|
||||||
int32_t value, size_t length);
|
int32_t value, size_t length);
|
||||||
|
|
||||||
|
static inline int ompi_atomic_cmpset_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval);
|
||||||
|
static inline int ompi_atomic_cmpset_acq_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval);
|
||||||
|
static inline int ompi_atomic_cmpset_rel_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval);
|
||||||
|
static inline int ompi_atomic_add_pt(volatile void* addr,
|
||||||
|
void* delta);
|
||||||
|
static inline int ompi_atomic_sub_ptr(volatile void* addr,
|
||||||
|
void* delta);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomic compare and set of pointer with relaxed semantics. This
|
* Atomic compare and set of pointer with relaxed semantics. This
|
||||||
* macro detect at compile time the type of the first argument
|
* macro detect at compile time the type of the first argument and
|
||||||
* and choose the correct function to be called.
|
* choose the correct function to be called.
|
||||||
|
*
|
||||||
|
* \note This macro should only be used for integer types.
|
||||||
*
|
*
|
||||||
* @param addr Address of <TYPE>.
|
* @param addr Address of <TYPE>.
|
||||||
* @param oldval Comparison value <TYPE>.
|
* @param oldval Comparison value <TYPE>.
|
||||||
@ -293,12 +331,13 @@ static inline void ompi_atomic_sub_xx(volatile void* addr,
|
|||||||
ompi_atomic_cmpset_xx( (volatile void*)(ADDR), (int64_t)(OLDVAL), \
|
ompi_atomic_cmpset_xx( (volatile void*)(ADDR), (int64_t)(OLDVAL), \
|
||||||
(int64_t)(NEWVAL), sizeof(*(ADDR)) )
|
(int64_t)(NEWVAL), sizeof(*(ADDR)) )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomic compare and set of pointer with acquire semantics. This
|
* Atomic compare and set of pointer with acquire semantics. This
|
||||||
* macro detect at compile time the type of the first argument
|
* macro detect at compile time the type of the first argument
|
||||||
* and choose the correct function to be called.
|
* and choose the correct function to be called.
|
||||||
*
|
*
|
||||||
|
* \note This macro should only be used for integer types.
|
||||||
|
*
|
||||||
* @param addr Address of <TYPE>.
|
* @param addr Address of <TYPE>.
|
||||||
* @param oldval Comparison value <TYPE>.
|
* @param oldval Comparison value <TYPE>.
|
||||||
* @param newval New value to set if comparision is true <TYPE>.
|
* @param newval New value to set if comparision is true <TYPE>.
|
||||||
@ -315,6 +354,8 @@ static inline void ompi_atomic_sub_xx(volatile void* addr,
|
|||||||
* macro detect at compile time the type of the first argument
|
* macro detect at compile time the type of the first argument
|
||||||
* and choose the correct function to b
|
* and choose the correct function to b
|
||||||
*
|
*
|
||||||
|
* \note This macro should only be used for integer types.
|
||||||
|
*
|
||||||
* @param addr Address of <TYPE>.
|
* @param addr Address of <TYPE>.
|
||||||
* @param oldval Comparison value <TYPE>.
|
* @param oldval Comparison value <TYPE>.
|
||||||
* @param newval New value to set if comparision is true <TYPE>.
|
* @param newval New value to set if comparision is true <TYPE>.
|
||||||
@ -331,6 +372,8 @@ static inline void ompi_atomic_sub_xx(volatile void* addr,
|
|||||||
* macro detect at compile time the type of the first argument
|
* macro detect at compile time the type of the first argument
|
||||||
* and choose the correct function to be called.
|
* and choose the correct function to be called.
|
||||||
*
|
*
|
||||||
|
* \note This macro should only be used for integer types.
|
||||||
|
*
|
||||||
* @param addr Address of <TYPE>
|
* @param addr Address of <TYPE>
|
||||||
* @param delta Value to add (converted to <TYPE>).
|
* @param delta Value to add (converted to <TYPE>).
|
||||||
*/
|
*/
|
||||||
@ -343,6 +386,8 @@ static inline void ompi_atomic_sub_xx(volatile void* addr,
|
|||||||
* macro detect at compile time the type of the first argument
|
* macro detect at compile time the type of the first argument
|
||||||
* and choose the correct function to be called.
|
* and choose the correct function to be called.
|
||||||
*
|
*
|
||||||
|
* \note This macro should only be used for integer types.
|
||||||
|
*
|
||||||
* @param addr Address of <TYPE>
|
* @param addr Address of <TYPE>
|
||||||
* @param delta Value to substract (converted to <TYPE>).
|
* @param delta Value to substract (converted to <TYPE>).
|
||||||
*/
|
*/
|
||||||
@ -366,4 +411,7 @@ static inline void ompi_atomic_sub_xx(volatile void* addr,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* OMPI_SYS_ATOMIC_H */
|
#endif /* OMPI_SYS_ATOMIC_H */
|
||||||
|
@ -221,6 +221,87 @@ ompi_atomic_sub_xx(volatile void* addr, int32_t value, size_t length)
|
|||||||
#endif /* (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64) */
|
#endif /* (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64) */
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ompi_atomic_cmpset_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval)
|
||||||
|
{
|
||||||
|
#if SIZEOF_VOID_P == 4 && OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
|
return ompi_atomic_cmpset_32((int32_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#elif SIZEOF_VOID_P == 8 && OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
|
return ompi_atomic_cmpset_64((int64_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ompi_atomic_cmpset_acq_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval)
|
||||||
|
{
|
||||||
|
#if SIZEOF_VOID_P == 4 && OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
|
return ompi_atomic_cmpset_acq_32((int32_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#elif SIZEOF_VOID_P == 8 && OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
|
return ompi_atomic_cmpset_acq_64((int64_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int ompi_atomic_cmpset_rel_ptr(volatile void* addr,
|
||||||
|
void* oldval,
|
||||||
|
void* newval)
|
||||||
|
{
|
||||||
|
#if SIZEOF_VOID_P == 4 && OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
|
return ompi_atomic_cmpset_rel_32((int32_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#elif SIZEOF_VOID_P == 8 && OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
|
return ompi_atomic_cmpset_rel_64((int64_t*) addr, (unsigned long) oldval,
|
||||||
|
(unsigned long) newval);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int ompi_atomic_add_pt(volatile void* addr,
|
||||||
|
void* delta)
|
||||||
|
{
|
||||||
|
#if SIZEOF_VOID_P == 4 && OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
|
return ompi_atomic_add_32((int32_t*) addr, (unsigned long) delta);
|
||||||
|
#elif SIZEOF_VOID_P == 8 && OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
|
return ompi_atomic_add_64((int64_t*) addr, (unsigned long) delta);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int ompi_atomic_sub_ptr(volatile void* addr,
|
||||||
|
void* delta)
|
||||||
|
{
|
||||||
|
#if SIZEOF_VOID_P == 4 && OMPI_HAVE_ATOMIC_CMPSET_32
|
||||||
|
return ompi_atomic_sub_32((int32_t*) addr, (unsigned long) delta);
|
||||||
|
#elif SIZEOF_VOID_P == 8 && OMPI_HAVE_ATOMIC_CMPSET_64
|
||||||
|
return ompi_atomic_sub_64((int64_t*) addr, (unsigned long) delta);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
* Atomic spinlocks
|
* Atomic spinlocks
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user