root/test/class/opal_fifo.c

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

DEFINITIONS

This source file includes following definitions.
  1. thread_test
  2. thread_test_exhaust
  3. check_fifo_consistency
  4. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014      Los Alamos National Security, LLC. All rights
   4  *                         reserved.
   5  * Copyright (c) 2018      IBM Corporation.  All rights reserved.
   6  * $COPYRIGHT$
   7  *
   8  * Additional copyrights may follow
   9  *
  10  * $HEADER$
  11  */
  12 
  13 #include "opal_config.h"
  14 #include <assert.h>
  15 
  16 #include "support.h"
  17 #include "opal/class/opal_fifo.h"
  18 #include "opal/runtime/opal.h"
  19 #include "opal/constants.h"
  20 
  21 #include <stdlib.h>
  22 #include <stdio.h>
  23 #include <stddef.h>
  24 
  25 #include <sys/time.h>
  26 
  27 #define OPAL_FIFO_TEST_THREAD_COUNT 8
  28 #define ITERATIONS 1000000
  29 #define ITEM_COUNT 100
  30 #define ITEMS_PER_LOOP 30
  31 
  32 #if !defined(timersub)
  33 #define timersub(a, b, r) \
  34     do {                  \
  35         (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;        \
  36         if ((a)->tv_usec < (b)->tv_usec) {              \
  37             (r)->tv_sec--;                              \
  38             (a)->tv_usec += 1000000;                    \
  39         }                                               \
  40         (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;     \
  41     } while (0)
  42 #endif
  43 
  44 static void *thread_test (void *arg) {
  45     opal_fifo_t *fifo = (opal_fifo_t *) arg;
  46     opal_list_item_t *item;
  47     struct timeval start, stop, total;
  48     double timing;
  49 
  50     gettimeofday (&start, NULL);
  51     for (int i = 0 ; i < ITERATIONS ; ++i) {
  52         item = opal_fifo_pop_atomic (fifo);
  53         if (NULL != item) {
  54             (void) opal_fifo_push_atomic (fifo, item);
  55         }
  56     }
  57     gettimeofday (&stop, NULL);
  58 
  59     timersub(&stop, &start, &total);
  60 
  61     timing = ((double) total.tv_sec + (double) total.tv_usec * 1e-6) / (double) ITERATIONS;
  62 
  63     printf ("Atomics thread finished. Time: %d s %d us %d nsec/poppush\n", (int) total.tv_sec,
  64             (int)total.tv_usec, (int)(timing / 1e-9));
  65 
  66     return NULL;
  67 }
  68 
  69 static void *thread_test_exhaust (void *arg) {
  70   opal_fifo_t *fifo = (opal_fifo_t *) arg;
  71   opal_list_item_t *items[ITEMS_PER_LOOP];
  72   struct timeval start, stop, total;
  73   int item_count = 0;
  74   double timing;
  75 
  76   gettimeofday (&start, NULL);
  77 
  78   for (int i = 0 ; i < ITERATIONS ; i += ITEMS_PER_LOOP) {
  79     for (int j = 0 ; j < ITEMS_PER_LOOP ; ++j) {
  80       items[j] = opal_fifo_pop_atomic (fifo);
  81       if (items[j]) {
  82         ++item_count;
  83       }
  84     }
  85 
  86     for (int j = 0 ; j < ITEMS_PER_LOOP ; ++j) {
  87       if (items[j]) {
  88         (void) opal_fifo_push_atomic (fifo, items[j]);
  89       }
  90     }
  91   }
  92 
  93   gettimeofday (&stop, NULL);
  94 
  95   timersub(&stop, &start, &total);
  96 
  97   timing = ((double) total.tv_sec + (double) total.tv_usec * 1e-6) / (double) item_count;
  98 
  99   fprintf (stderr, "Exhaustive atomics thread finished. Popped %d items. Time: %d s %d us %d nsec/poppush\n", item_count,
 100            (int) total.tv_sec, (int)total.tv_usec, (int)(timing / 1e-9));
 101 
 102   return NULL;
 103 }
 104 
 105 static bool check_fifo_consistency (opal_fifo_t *fifo, int expected_count)
 106 {
 107     volatile opal_list_item_t *volatile item;
 108     int count;
 109 
 110     for (count = 0, item = fifo->opal_fifo_head.data.item ; item != &fifo->opal_fifo_ghost ;
 111          item = opal_list_get_next(item), count++);
 112 
 113     return count == expected_count;
 114 }
 115 
 116 int main (int argc, char *argv[]) {
 117     pthread_t threads[OPAL_FIFO_TEST_THREAD_COUNT];
 118     opal_list_item_t *item, *prev, *item2;
 119     struct timeval start, stop, total;
 120     opal_fifo_t fifo;
 121     bool success;
 122     double timing;
 123     int rc;
 124 
 125     rc = opal_init_util (&argc, &argv);
 126     test_verify_int(OPAL_SUCCESS, rc);
 127     if (OPAL_SUCCESS != rc) {
 128         test_finalize();
 129         exit (1);
 130     }
 131 
 132     test_init("opal_fifo_t");
 133 
 134     OBJ_CONSTRUCT(&fifo, opal_fifo_t);
 135 
 136     item = OBJ_NEW(opal_list_item_t);
 137     prev = opal_fifo_push_st (&fifo, item);
 138     if (&fifo.opal_fifo_ghost == prev) {
 139         test_success ();
 140     } else {
 141         test_failure (" opal_fifo_push_st on empty fifo");
 142     }
 143 
 144     item2 = opal_fifo_pop_st (&fifo);
 145     if (item == item2) {
 146         test_success ();
 147     } else {
 148         test_failure (" opal_fifo_pop_st");
 149     }
 150 
 151     OBJ_RELEASE(item);
 152 
 153     for (int i = 0 ; i < ITEM_COUNT ; ++i) {
 154         item = OBJ_NEW(opal_list_item_t);
 155         item->item_free = 0;
 156         opal_fifo_push_st (&fifo, item);
 157     }
 158 
 159     if (check_fifo_consistency (&fifo, ITEM_COUNT)) {
 160         test_success ();
 161     } else {
 162         test_failure (" opal_fifo_push_st(multiple items)");
 163     }
 164 
 165     gettimeofday (&start, NULL);
 166     for (int i = 0 ; i < ITERATIONS ; ++i) {
 167         item = opal_fifo_pop_st (&fifo);
 168         (void) opal_fifo_push_st (&fifo, item);
 169     }
 170     gettimeofday (&stop, NULL);
 171 
 172     timersub(&stop, &start, &total);
 173 
 174     timing = ((double) total.tv_sec + (double) total.tv_usec * 1e-6) / (double) ITERATIONS;
 175 
 176     if (check_fifo_consistency (&fifo, ITEM_COUNT)) {
 177         test_success ();
 178     } else {
 179         test_failure (" fifo push/pop");
 180     }
 181 
 182     printf ("Single thread test. Time: %d s %d us %d nsec/poppush\n", (int) total.tv_sec,
 183             (int)total.tv_usec, (int)(timing / 1e-9));
 184 
 185     thread_test (&fifo);
 186 
 187     if (check_fifo_consistency (&fifo, ITEM_COUNT)) {
 188         test_success ();
 189     } else {
 190         test_failure (" fifo push/pop single-threaded with atomics");
 191     }
 192 
 193     gettimeofday (&start, NULL);
 194     for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) {
 195         pthread_create (threads + i, NULL, thread_test, &fifo);
 196     }
 197 
 198     for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) {
 199         void *ret;
 200 
 201         pthread_join (threads[i], &ret);
 202     }
 203     gettimeofday (&stop, NULL);
 204 
 205     timersub(&stop, &start, &total);
 206 
 207     timing = ((double) total.tv_sec + (double) total.tv_usec * 1e-6) / (double) (ITERATIONS * OPAL_FIFO_TEST_THREAD_COUNT);
 208 
 209     if (check_fifo_consistency (&fifo, ITEM_COUNT)) {
 210         test_success ();
 211     } else {
 212         test_failure (" fifo push/pop multi-threaded with atomics");
 213     }
 214 
 215     printf ("All threads finished. Thread count: %d Time: %d s %d us %d nsec/poppush\n",
 216             OPAL_FIFO_TEST_THREAD_COUNT, (int) total.tv_sec, (int)total.tv_usec, (int)(timing / 1e-9));
 217 
 218 
 219     gettimeofday (&start, NULL);
 220     for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) {
 221         pthread_create (threads + i, NULL, thread_test_exhaust, &fifo);
 222     }
 223 
 224     for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) {
 225         void *ret;
 226 
 227         pthread_join (threads[i], &ret);
 228     }
 229     gettimeofday (&stop, NULL);
 230 
 231     timersub(&stop, &start, &total);
 232 
 233     timing = ((double) total.tv_sec + (double) total.tv_usec * 1e-6) / (double) (ITERATIONS * OPAL_FIFO_TEST_THREAD_COUNT);
 234 
 235     if (check_fifo_consistency (&fifo, ITEM_COUNT)) {
 236         test_success ();
 237     } else {
 238         test_failure (" fifo push/pop multi-threaded with atomics when there are insufficient items");
 239     }
 240 
 241     printf ("All threads finished. Thread count: %d Time: %d s %d us %d nsec/poppush\n",
 242             OPAL_FIFO_TEST_THREAD_COUNT, (int) total.tv_sec, (int)total.tv_usec, (int)(timing / 1e-9));
 243 
 244     success = true;
 245     for (int i = 0 ; i < ITEM_COUNT ; ++i) {
 246         item = opal_fifo_pop_st (&fifo);
 247         if (NULL == item) {
 248             success = false;
 249             break;
 250         }
 251         OBJ_RELEASE(item);
 252     }
 253 
 254     if (success) {
 255         test_success ();
 256     } else {
 257         test_failure (" fifo pop all items");
 258     }
 259 
 260     OBJ_DESTRUCT(&fifo);
 261 
 262     opal_finalize_util ();
 263 
 264     return test_finalize ();
 265 }

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