root/test/asm/atomic_math.c

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

DEFINITIONS

This source file includes following definitions.
  1. atomic_math_test
  2. atomic_math_test_th
  3. main

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2014 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2015      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #define OMPI_BUILDING 0
  23 #include "opal_config.h"
  24 
  25 #ifdef HAVE_PTHREAD_H
  26 #include <pthread.h>
  27 #endif
  28 #include <stdlib.h>
  29 #include <stdio.h>
  30 
  31 #include "opal/sys/atomic.h"
  32 
  33 #define TEST_REPS 500
  34 
  35 opal_atomic_int32_t val32 = 0;
  36 #if OPAL_HAVE_ATOMIC_MATH_64
  37 opal_atomic_int64_t val64 = 0;
  38 #endif
  39 opal_atomic_int_t valint = 0;
  40 
  41 static void* atomic_math_test(void* arg)
  42 {
  43     int count = *((int*) arg);
  44     int i;
  45 
  46     for (i = 0 ; i < count ; ++i) {
  47         (void)opal_atomic_add_fetch_32(&val32, 5);
  48 #if OPAL_HAVE_ATOMIC_MATH_64
  49         (void)opal_atomic_add_fetch_64(&val64, 6);
  50 #endif
  51         opal_atomic_add (&valint, 4);
  52     }
  53 
  54     return NULL;
  55 }
  56 
  57 
  58 static int
  59 atomic_math_test_th(int count, int thr_count)
  60 {
  61     int value;
  62     pthread_t *th;
  63     int tid;
  64 
  65     th = (pthread_t *) malloc(thr_count * sizeof(pthread_t));
  66     if (!th) {
  67         perror("malloc");
  68         exit(EXIT_FAILURE);
  69     }
  70 
  71     /* Ok to use a single instance of ip_union_t from the stack here
  72        because a) we're passing the same count to all threads, and b)
  73        we're waiting for all the threads to finish before leaving this
  74        function, so there's no race condition of the instance
  75        disappearing before the threads start. */
  76     value = count;
  77     for (tid = 0; tid < thr_count; tid++) {
  78         if (pthread_create(&th[tid], NULL, atomic_math_test,
  79                            (void*) &value) != 0) {
  80             perror("pthread_create");
  81             exit(EXIT_FAILURE);
  82         }
  83     }
  84 
  85     /* -- wait for the thread set to finish -- */
  86     for (tid = 0; tid < thr_count; tid++) {
  87         void *thread_return;
  88 
  89         if (pthread_join(th[tid], &thread_return) != 0) {
  90             perror("pthread_join");
  91             exit(EXIT_FAILURE);
  92         }
  93     }
  94     free(th);
  95 
  96     return 0;
  97 }
  98 
  99 
 100 int
 101 main(int argc, char *argv[])
 102 {
 103     int32_t test32;
 104 #if OPAL_HAVE_ATOMIC_MATH_64
 105     int64_t test64;
 106 #endif
 107     int ret = 77;
 108     int num_threads = 1;
 109 
 110     if (argc != 2) {
 111         printf("*** Incorrect number of arguments.  Skipping test\n");
 112         return 77;
 113     }
 114     num_threads = atoi(argv[1]);
 115 
 116     test32 = opal_atomic_add_fetch_32 (&val32, 17);
 117     if (test32 != 17 || val32 != 17) {
 118         fprintf (stderr, "error in opal_atomic_add_fetch_32. expected (17, 17), got (%d, %d)\n", test32, val32);
 119         exit(EXIT_FAILURE);
 120     }
 121 
 122     test32 = opal_atomic_fetch_add_32 (&val32, 13);
 123     if (test32 != 17 || val32 != 30) {
 124         fprintf (stderr, "error in opal_atomic_fetch_add_32. expected (17, 30), got (%d, %d)\n", test32, val32);
 125         exit(EXIT_FAILURE);
 126     }
 127 
 128 
 129 
 130     test32 = opal_atomic_and_fetch_32 (&val32, 0x18);
 131     if (test32 != 24 || val32 != 24) {
 132         fprintf (stderr, "error in opal_atomic_and_fetch_32. expected (24, 24), got (%d, %d)\n", test32, val32);
 133         exit(EXIT_FAILURE);
 134     }
 135 
 136     test32 = opal_atomic_fetch_and_32 (&val32, 0x10);
 137     if (test32 != 24 || val32 != 16) {
 138         fprintf (stderr, "error in opal_atomic_fetch_and_32. expected (24, 16), got (%d, %d)\n", test32, val32);
 139         exit(EXIT_FAILURE);
 140     }
 141 
 142 
 143 
 144     test32 = opal_atomic_or_fetch_32 (&val32, 0x03);
 145     if (test32 != 19 || val32 != 19) {
 146         fprintf (stderr, "error in opal_atomic_or_fetch_32. expected (19, 19), got (%d, %d)\n", test32, val32);
 147         exit(EXIT_FAILURE);
 148     }
 149 
 150     test32 = opal_atomic_fetch_or_32 (&val32, 0x04);
 151     if (test32 != 19 || val32 != 23) {
 152         fprintf (stderr, "error in opal_atomic_fetch_or_32. expected (19, 23), got (%d, %d)\n", test32, val32);
 153         exit(EXIT_FAILURE);
 154     }
 155 
 156 
 157     test32 = opal_atomic_xor_fetch_32 (&val32, 0x03);
 158     if (test32 != 20 || val32 != 20) {
 159         fprintf (stderr, "error in opal_atomic_xor_fetch_32. expected (20, 20), got (%d, %d)\n", test32, val32);
 160         exit(EXIT_FAILURE);
 161     }
 162 
 163     test32 = opal_atomic_fetch_xor_32 (&val32, 0x05);
 164     if (test32 != 20 || val32 != 17) {
 165         fprintf (stderr, "error in opal_atomic_fetch_xor_32. expected (20, 17), got (%d, %d)\n", test32, val32);
 166         exit(EXIT_FAILURE);
 167     }
 168 
 169 
 170 
 171     test32 = opal_atomic_sub_fetch_32 (&val32, 14);
 172     if (test32 != 3 || val32 != 3) {
 173         fprintf (stderr, "error in opal_atomic_sub_fetch_32. expected (3, 3), got (%d, %d)\n", test32, val32);
 174         exit(EXIT_FAILURE);
 175     }
 176 
 177     test32 = opal_atomic_fetch_xor_32 (&val32, 3);
 178     if (test32 != 3 || val32 != 0) {
 179         fprintf (stderr, "error in opal_atomic_fetch_sub_32. expected (3, 0), got (%d, %d)\n", test32, val32);
 180         exit(EXIT_FAILURE);
 181     }
 182 
 183 #if OPAL_HAVE_ATOMIC_MATH_64
 184     test64 = opal_atomic_add_fetch_64 (&val64, 17);
 185     if (test64 != 17 || val64 != 17) {
 186         fprintf (stderr, "error in opal_atomic_add_fetch_64. expected (17, 17), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 187         exit(EXIT_FAILURE);
 188     }
 189 
 190     test64 = opal_atomic_fetch_add_64 (&val64, 13);
 191     if (test64 != 17 || val64 != 30) {
 192         fprintf (stderr, "error in opal_atomic_fetch_add_64. expected (17, 30), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 193         exit(EXIT_FAILURE);
 194     }
 195 
 196 
 197 
 198     test64 = opal_atomic_and_fetch_64 (&val64, 0x18);
 199     if (test64 != 24 || val64 != 24) {
 200         fprintf (stderr, "error in opal_atomic_and_fetch_64. expected (24, 24), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 201         exit(EXIT_FAILURE);
 202     }
 203 
 204     test64 = opal_atomic_fetch_and_64 (&val64, 0x10);
 205     if (test64 != 24 || val64 != 16) {
 206         fprintf (stderr, "error in opal_atomic_fetch_and_64. expected (24, 16), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 207         exit(EXIT_FAILURE);
 208     }
 209 
 210 
 211 
 212     test64 = opal_atomic_or_fetch_64 (&val64, 0x03);
 213     if (test64 != 19 || val64 != 19) {
 214         fprintf (stderr, "error in opal_atomic_or_fetch_64. expected (19, 19), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 215         exit(EXIT_FAILURE);
 216     }
 217 
 218     test64 = opal_atomic_fetch_or_64 (&val64, 0x04);
 219     if (test64 != 19 || val64 != 23) {
 220         fprintf (stderr, "error in opal_atomic_fetch_or_64. expected (19, 23), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 221         exit(EXIT_FAILURE);
 222     }
 223 
 224 
 225     test64 = opal_atomic_xor_fetch_64 (&val64, 0x03);
 226     if (test64 != 20 || val64 != 20) {
 227         fprintf (stderr, "error in opal_atomic_xor_fetch_64. expected (20, 20), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 228         exit(EXIT_FAILURE);
 229     }
 230 
 231     test64 = opal_atomic_fetch_xor_64 (&val64, 0x05);
 232     if (test64 != 20 || val64 != 17) {
 233         fprintf (stderr, "error in opal_atomic_fetch_xor_64. expected (20, 17), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 234         exit(EXIT_FAILURE);
 235     }
 236 
 237 
 238 
 239     test64 = opal_atomic_sub_fetch_64 (&val64, 14);
 240     if (test64 != 3 || val64 != 3) {
 241         fprintf (stderr, "error in opal_atomic_sub_fetch_64. expected (3, 3), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 242         exit(EXIT_FAILURE);
 243     }
 244 
 245     test64 = opal_atomic_fetch_xor_64 (&val64, 3);
 246     if (test64 != 3 || val64 != 0) {
 247         fprintf (stderr, "error in opal_atomic_fetch_sub_64. expected (3, 0), got (%" PRId64 ", %" PRId64 ")\n", test64, val64);
 248         exit(EXIT_FAILURE);
 249     }
 250 #endif
 251 
 252     ret = atomic_math_test_th(TEST_REPS, num_threads);
 253     if (ret == 77) return ret;
 254     opal_atomic_mb();
 255     if (val32 != TEST_REPS * num_threads * 5) {
 256         printf("opal_atomic_add_fetch32 failed.  Expected %d, got %d.\n",
 257                TEST_REPS * num_threads * 5, val32);
 258         ret = 1;
 259     }
 260 #if OPAL_HAVE_ATOMIC_MATH_64
 261     if (val64 != TEST_REPS * num_threads * 6) {
 262         /* Safe to case to (int) here because we know it's going to be
 263            a small value */
 264         printf("opal_atomic_add_fetch32 failed.  Expected %d, got %d.\n",
 265                TEST_REPS * num_threads * 6, (int) val64);
 266         ret = 1;
 267     }
 268 #else
 269     printf("      * skipping 64 bit tests\n");
 270 #endif
 271     if (valint != TEST_REPS * num_threads * 4) {
 272         printf("opal_atomic_add_fetch32 failed.  Expected %d, got %d.\n",
 273                TEST_REPS * num_threads * 4, valint);
 274         ret = 1;
 275     }
 276 
 277     return ret;
 278 }

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