root/test/asm/atomic_cmpset.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. thread_main
  2. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2015      Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * Copyright (c) 2017      Los Alamos National Security, LLC. All rights
  17  *                         reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 
  25 #define OMPI_BUILDING 0
  26 #include "opal_config.h"
  27 
  28 #undef NDEBUG
  29 #define DEBUG
  30 
  31 #include <assert.h>
  32 #ifdef HAVE_PTHREAD_H
  33 #include <pthread.h>
  34 #endif
  35 #include <stdarg.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>
  39 
  40 #include "opal/sys/atomic.h"
  41 
  42 
  43 /* default options */
  44 int nreps = 100;
  45 int nthreads = 2;
  46 int enable_verbose = 0;
  47 
  48 opal_atomic_int32_t vol32 = 0;
  49 opal_atomic_int32_t val32 = 0;
  50 int32_t old32 = 0;
  51 int32_t new32 = 0;
  52 
  53 #if OPAL_HAVE_ATOMIC_MATH_64
  54 opal_atomic_int64_t vol64 = 0;
  55 opal_atomic_int64_t val64 = 0;
  56 int64_t old64 = 0;
  57 int64_t new64 = 0;
  58 #endif
  59 
  60 #if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_128
  61 opal_atomic_int128_t vol128;
  62 opal_atomic_int128_t val128;
  63 opal_int128_t old128;
  64 opal_int128_t new128;
  65 #endif
  66 
  67 opal_atomic_int_t volint = 0;
  68 opal_atomic_int_t valint = 0;
  69 int oldint = 0;
  70 int newint = 0;
  71 
  72 opal_atomic_intptr_t volptr = 0;
  73 intptr_t oldptr = 0;
  74 intptr_t newptr = 0;
  75 
  76 
  77 static void *thread_main(void *arg)
  78 {
  79     int rank = (int) (unsigned long) arg;
  80     int i;
  81 
  82     /* thread tests */
  83 
  84     for (i = 0; i < nreps; i++) {
  85         opal_atomic_add_fetch_32(&val32, 5);
  86 #if OPAL_HAVE_ATOMIC_MATH_64
  87         opal_atomic_add_fetch_64(&val64, 5);
  88 #endif
  89         opal_atomic_add (&valint, 5);
  90     }
  91 
  92     return (void *) (unsigned long) (rank + 1000);
  93 }
  94 
  95 int main(int argc, char *argv[])
  96 {
  97     int tid;
  98     pthread_t *th;
  99 
 100     if (argc != 2) {
 101         printf("*** Incorrect number of arguments.  Skipping test\n");
 102         return 77;
 103     }
 104     nthreads = atoi(argv[1]);
 105 
 106 
 107     /* first test single-threaded functionality */
 108 
 109     /* -- cmpset 32-bit tests -- */
 110 
 111     vol32 = 42, old32 = 42, new32 = 50;
 112     assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) == true);
 113     opal_atomic_rmb();
 114     assert(vol32 == new32);
 115     assert(old32 == 42);
 116 
 117     vol32 = 42, old32 = 420, new32 = 50;
 118     assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) ==  false);
 119     opal_atomic_rmb();
 120     assert(vol32 == 42);
 121     assert(old32 == 42);
 122 
 123     vol32 = 42, old32 = 42, new32 = 50;
 124     assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) == true);
 125     assert(vol32 == new32);
 126     assert(old32 == 42);
 127 
 128     vol32 = 42, old32 = 420, new32 = 50;
 129     assert(opal_atomic_compare_exchange_strong_acq_32 (&vol32, &old32, new32) == false);
 130     assert(vol32 == 42);
 131     assert(old32 == 42);
 132 
 133     vol32 = 42, old32 = 42, new32 = 50;
 134     assert(opal_atomic_compare_exchange_strong_rel_32 (&vol32, &old32, new32) ==  true);
 135     opal_atomic_rmb();
 136     assert(vol32 == new32);
 137     assert(old32 == 42);
 138 
 139     vol32 = 42, old32 = 420, new32 = 50;
 140     assert(opal_atomic_compare_exchange_strong_rel_32 (&vol32, &old32, new32) == false);
 141     opal_atomic_rmb();
 142     assert(vol32 == 42);
 143     assert(old32 == 42);
 144 
 145     /* -- cmpset 64-bit tests -- */
 146 
 147 #if OPAL_HAVE_ATOMIC_MATH_64
 148     vol64 = 42, old64 = 42, new64 = 50;
 149     assert(opal_atomic_compare_exchange_strong_64 (&vol64, &old64, new64) == true);
 150     opal_atomic_rmb();
 151     assert(new64 == vol64);
 152     assert(old64 == 42);
 153 
 154     vol64 = 42, old64 = 420, new64 = 50;
 155     assert(opal_atomic_compare_exchange_strong_64 (&vol64, &old64, new64) == false);
 156     opal_atomic_rmb();
 157     assert(vol64 == 42);
 158     assert(old64 == 42);
 159 
 160     vol64 = 42, old64 = 42, new64 = 50;
 161     assert(opal_atomic_compare_exchange_strong_acq_64 (&vol64, &old64, new64) == true);
 162     assert(vol64 == new64);
 163     assert(old64 == 42);
 164 
 165     vol64 = 42, old64 = 420, new64 = 50;
 166     assert(opal_atomic_compare_exchange_strong_acq_64 (&vol64, &old64, new64) == false);
 167     assert(vol64 == 42);
 168     assert(old64 == 42);
 169 
 170     vol64 = 42, old64 = 42, new64 = 50;
 171     assert(opal_atomic_compare_exchange_strong_rel_64 (&vol64, &old64, new64) == true);
 172     opal_atomic_rmb();
 173     assert(vol64 == new64);
 174     assert(old64 == 42);
 175 
 176     vol64 = 42, old64 = 420, new64 = 50;
 177     assert(opal_atomic_compare_exchange_strong_rel_64 (&vol64, &old64, new64) == false);
 178     opal_atomic_rmb();
 179     assert(vol64 == 42);
 180     assert(old64 == 42);
 181 #endif
 182 
 183     /* -- cmpset 128-bit tests -- */
 184 
 185 #if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_128
 186     vol128 = 42, old128 = 42, new128 = 50;
 187     assert(opal_atomic_compare_exchange_strong_128 (&vol128, &old128, new128) == true);
 188     opal_atomic_rmb();
 189     assert(new128 == vol128);
 190     assert(old128 == 42);
 191 
 192     vol128 = 42, old128 = 420, new128 = 50;
 193     assert(opal_atomic_compare_exchange_strong_128 (&vol128, &old128, new128) == false);
 194     opal_atomic_rmb();
 195     assert(vol128 == 42);
 196     assert(old128 == 42);
 197 #endif
 198 
 199     /* -- cmpset int tests -- */
 200 
 201     volint = 42, oldint = 42, newint = 50;
 202     assert(opal_atomic_compare_exchange_strong (&volint, &oldint, newint) == true);
 203     opal_atomic_rmb();
 204     assert(volint == newint);
 205     assert(oldint == 42);
 206 
 207     volint = 42, oldint = 420, newint = 50;
 208     assert(opal_atomic_compare_exchange_strong (&volint, &oldint, newint) == false);
 209     opal_atomic_rmb();
 210     assert(volint == 42);
 211     assert(oldint == 42);
 212 
 213     volint = 42, oldint = 42, newint = 50;
 214     assert(opal_atomic_compare_exchange_strong_acq (&volint, &oldint, newint) == true);
 215     assert(volint == newint);
 216     assert(oldint == 42);
 217 
 218     volint = 42, oldint = 420, newint = 50;
 219     assert(opal_atomic_compare_exchange_strong_acq (&volint, &oldint, newint) == false);
 220     assert(volint == 42);
 221     assert(oldint == 42);
 222 
 223     volint = 42, oldint = 42, newint = 50;
 224     assert(opal_atomic_compare_exchange_strong_rel (&volint, &oldint, newint) == true);
 225     opal_atomic_rmb();
 226     assert(volint == newint);
 227     assert(oldint == 42);
 228 
 229     volint = 42, oldint = 420, newint = 50;
 230     assert(opal_atomic_compare_exchange_strong_rel (&volint, &oldint, newint) == false);
 231     opal_atomic_rmb();
 232     assert(volint == 42);
 233     assert(oldint == 42);
 234 
 235 
 236     /* -- cmpset ptr tests -- */
 237 
 238     volptr = 42, oldptr = 42, newptr = 50;
 239     assert(opal_atomic_compare_exchange_strong_ptr (&volptr, &oldptr, newptr) == true);
 240     opal_atomic_rmb();
 241     assert(volptr == newptr);
 242     assert(oldptr == 42);
 243 
 244     volptr = 42, oldptr = 420, newptr = 50;
 245     assert(opal_atomic_compare_exchange_strong_ptr (&volptr, &oldptr, newptr) == false);
 246     opal_atomic_rmb();
 247     assert(volptr == 42);
 248     assert(oldptr == 42);
 249 
 250     volptr = 42, oldptr = 42, newptr = 50;
 251     assert(opal_atomic_compare_exchange_strong_acq_ptr (&volptr, &oldptr, newptr) == true);
 252     assert(volptr == newptr);
 253     assert(oldptr == 42);
 254 
 255     volptr = 42, oldptr = 420, newptr = 50;
 256     assert(opal_atomic_compare_exchange_strong_acq_ptr (&volptr, &oldptr, newptr) == false);
 257     assert(volptr == 42);
 258     assert(oldptr == 42);
 259 
 260     volptr = 42, oldptr = 42, newptr = 50;
 261     assert(opal_atomic_compare_exchange_strong_rel_ptr (&volptr, &oldptr, newptr) == true);
 262     opal_atomic_rmb();
 263     assert(volptr == newptr);
 264     assert(oldptr == 42);
 265 
 266     volptr = 42, oldptr = 420, newptr = 50;
 267     assert(opal_atomic_compare_exchange_strong_rel_ptr (&volptr, &oldptr, newptr) == false);
 268     opal_atomic_rmb();
 269     assert(volptr == 42);
 270     assert(oldptr == 42);
 271 
 272     /* -- add_32 tests -- */
 273 
 274     val32 = 42;
 275     assert(opal_atomic_add_fetch_32(&val32, 5) == (42 + 5));
 276     opal_atomic_rmb();
 277     assert((42 + 5) == val32);
 278 
 279     /* -- add_64 tests -- */
 280 #if OPAL_HAVE_ATOMIC_MATH_64
 281     val64 = 42;
 282     assert(opal_atomic_add_fetch_64(&val64, 5) == (42 + 5));
 283     opal_atomic_rmb();
 284     assert((42 + 5) == val64);
 285 #endif
 286     /* -- add_int tests -- */
 287 
 288     valint = 42;
 289     opal_atomic_add (&valint, 5);
 290     opal_atomic_rmb();
 291     assert((42 + 5) == valint);
 292 
 293 
 294     /* threaded tests */
 295 
 296     val32 = 0;
 297 #if OPAL_HAVE_ATOMIC_MATH_64
 298     val64 = 0ul;
 299 #endif
 300     valint = 0;
 301 
 302     /* -- create the thread set -- */
 303     th = (pthread_t *) malloc(nthreads * sizeof(pthread_t));
 304     if (!th) {
 305         perror("malloc");
 306         exit(EXIT_FAILURE);
 307     }
 308     for (tid = 0; tid < nthreads; tid++) {
 309         if (pthread_create(&th[tid], NULL, thread_main, (void *) (unsigned long) tid) != 0) {
 310             perror("pthread_create");
 311             exit(EXIT_FAILURE);
 312         }
 313     }
 314 
 315     /* -- wait for the thread set to finish -- */
 316 
 317     for (tid = 0; tid < nthreads; tid++) {
 318         void *thread_return;
 319 
 320         if (pthread_join(th[tid], &thread_return) != 0) {
 321             perror("pthread_join");
 322             exit(EXIT_FAILURE);
 323         }
 324     }
 325     free(th);
 326 
 327     opal_atomic_rmb();
 328     assert((5 * nthreads * nreps) == val32);
 329 #if OPAL_HAVE_ATOMIC_MATH_64
 330     opal_atomic_rmb();
 331     assert((5 * nthreads * nreps) ==  val64);
 332 #endif
 333     opal_atomic_rmb();
 334     assert((5 * nthreads * nreps) == valint);
 335 
 336     return 0;
 337 }

/* [<][>][^][v][top][bottom][index][help] */