This source file includes following definitions.
- get_ts_gettimeofday
- main
- value_xfer_thread
- bind_me_to
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 #include <stdio.h>
  18 #include <stdlib.h>
  19 #include <stdbool.h>
  20 #include <string.h>
  21 #include <pthread.h>
  22 #include <stdint.h>
  23 #include <hwloc.h>
  24 #include <sys/time.h>
  25 
  26 #include "opal/sys/atomic.h"
  27 
  28 
  29 
  30 #define MAX_VAL 32767
  31 
  32 typedef struct {
  33     int type;
  34     union {
  35         bool flag;
  36         int integer;
  37         int8_t int8;
  38         int16_t int16;
  39         int32_t int32;
  40         int64_t int64;
  41         
  42     } data;
  43 } my_value_t;
  44 
  45 
  46 typedef struct {
  47     volatile bool working;
  48     void *ptr; 
  49 } thread_handoff_t;
  50 
  51 
  52 thread_handoff_t handoff;
  53 
  54 
  55 bool time_to_stop = false;
  56 
  57 
  58 #define PERC_INC 10.0
  59 double perc_report_after = PERC_INC;
  60 double perc_current = 0.0;
  61 
  62 
  63 #define MB_MODE_NONE 0x0
  64 #define MB_MODE_RMB  0x1
  65 #define MB_MODE_WMB  0x2
  66 #define MB_MODE_MB   0x4
  67 #define MB_MODE_XMB  0x8
  68 #define MB_MODE_ALL (MB_MODE_RMB | MB_MODE_WMB)
  69 int mb_mode = MB_MODE_ALL;
  70 
  71 
  72 
  73 static hwloc_topology_t topo;
  74 
  75 
  76 
  77 
  78 #define OBJ_TYPE HWLOC_OBJ_CORE
  79 
  80 
  81 
  82 
  83 double acc_time, start_time, stop_time, delta;
  84 static double get_ts_gettimeofday(void) {
  85     double ret;
  86     struct timeval tv;
  87     gettimeofday(&tv, NULL);
  88     ret = tv.tv_sec;
  89     ret += (double)tv.tv_usec / 1000000.0;
  90     return ret;
  91 }
  92 
  93 
  94 
  95 
  96 void bind_me_to(bool main_thread);
  97 
  98 
  99 
 100 
 101 void *value_xfer_thread(void *arg);
 102 
 103 
 104 
 105 
 106 int main(int argc, char **argv) {
 107     pthread_t support_thread;
 108     int rc, i, max_iters = 10, cur_iter;
 109     my_value_t *val = NULL;
 110     int mode;
 111 
 112     
 113 
 114 
 115     if( argc > 1 ) {
 116         max_iters = atoi(argv[1]);
 117     }
 118     if( argc > 2 ) {
 119         mode = atoi(argv[2]);
 120         if( 0 > mode || mode > 5 ) {
 121             printf("Error: Invalid mode %d\n"
 122                    "\tNone = 0\n"
 123                    "\tRMB = 1\n"
 124                    "\tWMB = 2\n"
 125                    "\tBoth = 3\n"
 126                    "\tMB Only = 4\n",
 127                    "\tXMB Only = 5\n",
 128                    mode);
 129             exit(-1);
 130         }
 131     }
 132     else {
 133         mode = 3;
 134     }
 135     switch(mode) {
 136     case 0:
 137         mb_mode = MB_MODE_NONE;
 138         break;
 139     case 1:
 140         mb_mode = MB_MODE_RMB;
 141         break;
 142     case 2:
 143         mb_mode = MB_MODE_WMB;
 144         break;
 145     case 3:
 146         mb_mode = MB_MODE_ALL;
 147         break;
 148     case 4:
 149         mb_mode = MB_MODE_MB;
 150         break;
 151     case 5:
 152         mb_mode = MB_MODE_XMB;
 153         break;
 154     }
 155 
 156     
 157     hwloc_topology_init(&topo);
 158     hwloc_topology_load(topo);
 159 
 160     
 161     printf("---------------------------\n");
 162     printf("Iterations: %10d\n", max_iters);
 163     printf("Mode R MB : %10s\n", (mb_mode & MB_MODE_RMB ? "Enabled" : "Disabled") );
 164     printf("Mode W MB : %10s\n", (mb_mode & MB_MODE_WMB ? "Enabled" : "Disabled") );
 165     printf("Mode - MB : %10s\n", (mb_mode & MB_MODE_MB  ? "Enabled" : "Disabled") );
 166     printf("Mode X MB : %10s\n", (mb_mode & MB_MODE_XMB ? "Enabled" : "Disabled") );
 167     printf("---------------------------\n");
 168 
 169     bind_me_to(true);
 170     handoff.working = false;
 171 
 172     
 173 
 174 
 175     rc = pthread_create(&support_thread, NULL, value_xfer_thread, NULL);
 176     if( 0 != rc ) {
 177         printf("Error: Failed to create a thread! %d\n", rc);
 178         exit(-1);
 179     }
 180 
 181     
 182 
 183 
 184     acc_time = 0.0;
 185     for(cur_iter = 0; cur_iter < max_iters; ++cur_iter) {
 186         perc_current = (cur_iter / ((double)max_iters)) * 100.0;
 187         if( perc_current > perc_report_after ) {
 188             delta = (acc_time / cur_iter) * 1000000;
 189             printf("%6.1f %% complete : Iteration %10d / %10d : %6.1f usec / iter\n",
 190                    perc_current, cur_iter+1, max_iters, delta);
 191             perc_report_after += PERC_INC;
 192         }
 193 
 194         start_time = get_ts_gettimeofday();
 195         
 196         val = NULL;
 197         handoff.ptr = &val;
 198         if( mb_mode & MB_MODE_RMB ) {
 199             opal_atomic_rmb();
 200         }
 201         if( mb_mode & MB_MODE_MB ) {
 202             opal_atomic_mb();
 203         }
 204         handoff.working = true;
 205 
 206         
 207         while( handoff.working ) {
 208             usleep(1);
 209         }
 210         if( mb_mode & MB_MODE_WMB ) {
 211             opal_atomic_wmb();
 212         }
 213         if( mb_mode & MB_MODE_MB ) {
 214             opal_atomic_mb();
 215         }
 216 
 217         
 218         if( NULL == val ) {
 219             printf("[%10d / %10d] Error: val = %s\n", cur_iter+1, max_iters,
 220                    (NULL == val ? "NULL" : "Valid") );
 221             exit(-1);
 222         }
 223         else if( 999 != val->type ) {
 224             printf("[%10d / %10d] Error: val->type = %d\n", cur_iter+1, max_iters, val->type);
 225             exit(-1);
 226         }
 227         else if( (cur_iter+1)%MAX_VAL != val->data.int16 ) {
 228             printf("[%10d / %10d] Error: val->data.int16 = %d\n", cur_iter+1, max_iters, val->data.int16);
 229             exit(-1);
 230         }
 231 
 232         stop_time = get_ts_gettimeofday();
 233         acc_time += (stop_time - start_time);
 234 
 235         
 236         
 237         
 238         
 239         
 240         
 241         val = NULL;
 242     }
 243     delta = (acc_time / max_iters) * 1000000;
 244 
 245     
 246 
 247 
 248     time_to_stop = true;
 249 
 250     rc = pthread_join(support_thread, NULL);
 251     if( 0 != rc ) {
 252         printf("Error: Failed to join a thread! %d\n", rc);
 253         exit(-1);
 254     }
 255 
 256     hwloc_topology_destroy(topo);
 257 
 258     printf("Success - %6.1f usec / iter\n", delta);
 259 
 260     return 0;
 261 }
 262 
 263 void *value_xfer_thread(void *arg) {
 264     my_value_t **val = NULL;
 265     static int var = 0;
 266 
 267     
 268     bind_me_to(false);
 269 
 270     while( !time_to_stop ) {
 271         if( handoff.working ) {
 272             
 273             if( mb_mode & MB_MODE_WMB ) {
 274                 opal_atomic_wmb();
 275             }
 276             if( mb_mode & MB_MODE_MB ) {
 277                 opal_atomic_mb();
 278             }
 279 
 280             
 281             val = (my_value_t**)handoff.ptr;
 282             (*val) = malloc(sizeof(my_value_t));
 283             (*val)->type = 999;
 284             (*val)->data.int16 = (++var)%MAX_VAL;
 285 
 286             
 287             
 288             
 289             if( mb_mode & MB_MODE_RMB ) {
 290                 opal_atomic_rmb();
 291             }
 292             if( mb_mode & MB_MODE_MB ) {
 293                 opal_atomic_mb();
 294             }
 295             
 296             handoff.working = false;
 297         }
 298         else {
 299             
 300             usleep(1);
 301         }
 302     }
 303     pthread_exit(NULL);
 304 }
 305 
 306 void bind_me_to(bool main_thread) {
 307     int num_objs;
 308     hwloc_cpuset_t set;
 309     char *buffer = NULL;
 310     hwloc_obj_t obj;
 311 
 312     num_objs = hwloc_get_nbobjs_by_type(topo, OBJ_TYPE);
 313 
 314     if( main_thread ) {
 315         obj = hwloc_get_obj_by_type(topo, OBJ_TYPE, 0);
 316     }
 317     else {
 318         obj = hwloc_get_obj_by_type(topo, OBJ_TYPE, num_objs-1);
 319     }
 320 
 321     if( obj->type == OBJ_TYPE ) {
 322         hwloc_set_cpubind(topo, obj->cpuset, HWLOC_CPUBIND_THREAD);
 323     }
 324     else {
 325         printf("Error: Invalid object\n");
 326         exit(-1);
 327     }
 328 
 329     set = hwloc_bitmap_alloc();
 330     hwloc_get_cpubind(topo, set, HWLOC_CPUBIND_THREAD);
 331     hwloc_bitmap_opal_asprintf(&buffer, set);
 332     printf("%s : [objs = %d] : cpuset is %s\n", (main_thread ? "Main" : "Peer"), num_objs, buffer);
 333     free(buffer);
 334     hwloc_bitmap_free(set);
 335 }