Index: openmp/trunk/runtime/src/dllexports =================================================================== --- openmp/trunk/runtime/src/dllexports +++ openmp/trunk/runtime/src/dllexports @@ -397,6 +397,7 @@ %endif %endif kmpc_aligned_malloc 265 +kmpc_set_disp_num_buffers 267 # User API entry points that have both lower- and upper- case versions for Fortran. # Number for lowercase version is indicated. Number for uppercase is obtained by adding 1000. @@ -528,6 +529,8 @@ %endif %endif # OMP_41 +kmp_set_disp_num_buffers 890 + %ifndef stub # Ordinals between 900 and 999 are reserved Index: openmp/trunk/runtime/src/i18n/en_US.txt =================================================================== --- openmp/trunk/runtime/src/i18n/en_US.txt +++ openmp/trunk/runtime/src/i18n/en_US.txt @@ -408,6 +408,7 @@ AffUsingHwloc "%1$s: Affinity capable, using hwloc." AffIgnoringHwloc "%1$s: Ignoring hwloc mechanism." AffHwlocErrorOccurred "%1$s: Hwloc failed in %2$s. Relying on internal affinity mechanisms." +EnvSerialWarn "%1$s must be set prior to OpenMP runtime library initialization; ignored." # -------------------------------------------------------------------------------------------------- Index: openmp/trunk/runtime/src/include/41/omp.h.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp.h.var +++ openmp/trunk/runtime/src/include/41/omp.h.var @@ -140,6 +140,7 @@ extern void __KAI_KMPC_CONVENTION kmp_set_library_turnaround (void); extern void __KAI_KMPC_CONVENTION kmp_set_library_throughput (void); extern void __KAI_KMPC_CONVENTION kmp_set_defaults (char const *); + extern void __KAI_KMPC_CONVENTION kmp_set_disp_num_buffers (int); /* Intel affinity API */ typedef void * kmp_affinity_mask_t; Index: openmp/trunk/runtime/src/include/41/omp_lib.h.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp_lib.h.var +++ openmp/trunk/runtime/src/include/41/omp_lib.h.var @@ -391,6 +391,11 @@ integer (kind=omp_integer_kind) kmp_get_library end function kmp_get_library + subroutine kmp_set_disp_num_buffers(num) bind(c) + import + integer (kind=omp_integer_kind), value :: num + end subroutine kmp_set_disp_num_buffers + function kmp_set_affinity(mask) bind(c) import integer (kind=omp_integer_kind) kmp_set_affinity @@ -544,6 +549,7 @@ !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_stacksize_s !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_blocktime !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_library +!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_disp_num_buffers !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_affinity !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity !DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_max_proc @@ -615,6 +621,7 @@ !$omp declare target(kmp_get_stacksize_s ) !$omp declare target(kmp_get_blocktime ) !$omp declare target(kmp_get_library ) +!$omp declare target(kmp_set_disp_num_buffers ) !$omp declare target(kmp_set_affinity ) !$omp declare target(kmp_get_affinity ) !$omp declare target(kmp_get_affinity_max_proc ) Index: openmp/trunk/runtime/src/include/41/omp_lib.f90.var =================================================================== --- openmp/trunk/runtime/src/include/41/omp_lib.f90.var +++ openmp/trunk/runtime/src/include/41/omp_lib.f90.var @@ -410,6 +410,11 @@ integer (kind=omp_integer_kind) kmp_get_library end function kmp_get_library + subroutine kmp_set_disp_num_buffers(num) bind(c) + use omp_lib_kinds + integer (kind=omp_integer_kind), value :: num + end subroutine kmp_set_disp_num_buffers + function kmp_set_affinity(mask) bind(c) use omp_lib_kinds integer (kind=omp_integer_kind) kmp_set_affinity Index: openmp/trunk/runtime/src/kmp.h =================================================================== --- openmp/trunk/runtime/src/kmp.h +++ openmp/trunk/runtime/src/kmp.h @@ -1050,8 +1050,7 @@ #define KMP_MAX_NEXT_WAIT (INT_MAX/2) #define KMP_DEFAULT_NEXT_WAIT 1024U -// max possible dynamic loops in concurrent execution per team -#define KMP_MAX_DISP_BUF 7 +#define KMP_DFLT_DISP_NUM_BUFF 7 #define KMP_MAX_ORDERED 8 #define KMP_MAX_FIELDS 32 @@ -2806,6 +2805,7 @@ #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ extern int __kmp_dflt_max_active_levels; /* max_active_levels for nested parallelism enabled by default a la OMP_MAX_ACTIVE_LEVELS */ +extern int __kmp_dispatch_num_buffers; /* max possible dynamic loops in concurrent execution per team */ #if KMP_NESTED_HOT_TEAMS extern int __kmp_hot_teams_mode; extern int __kmp_hot_teams_max_level; @@ -3623,6 +3623,7 @@ KMP_EXPORT void KMPC_CONVENTION kmpc_set_stacksize_s(size_t); KMP_EXPORT void KMPC_CONVENTION kmpc_set_library(int); KMP_EXPORT void KMPC_CONVENTION kmpc_set_defaults(char const *); +KMP_EXPORT void KMPC_CONVENTION kmpc_set_disp_num_buffers(int); #ifdef __cplusplus } Index: openmp/trunk/runtime/src/kmp_csupport.c =================================================================== --- openmp/trunk/runtime/src/kmp_csupport.c +++ openmp/trunk/runtime/src/kmp_csupport.c @@ -1653,6 +1653,15 @@ __kmp_aux_set_defaults( str, KMP_STRLEN( str ) ); } +void +kmpc_set_disp_num_buffers( int arg ) +{ + // ignore after initialization because some teams have already + // allocated dispatch buffers + if( __kmp_init_serial == 0 && arg > 0 ) + __kmp_dispatch_num_buffers = arg; +} + int kmpc_set_affinity_mask_proc( int proc, void **mask ) { @@ -3061,7 +3070,7 @@ } KMP_DEBUG_ASSERT(team->t.t_nproc > 1); idx = pr_buf->th_doacross_buf_idx++; // Increment index of shared buffer for the next loop - sh_buf = &team->t.t_disp_buffer[idx % KMP_MAX_DISP_BUF]; + sh_buf = &team->t.t_disp_buffer[idx % __kmp_dispatch_num_buffers]; // Save bounds info into allocated private buffer KMP_DEBUG_ASSERT(pr_buf->th_doacross_info == NULL); @@ -3111,7 +3120,7 @@ } KMP_DEBUG_ASSERT(trace_count > 0); - // Check if shared buffer is not occupied by other loop (idx - KMP_MAX_DISP_BUF) + // Check if shared buffer is not occupied by other loop (idx - __kmp_dispatch_num_buffers) if( idx != sh_buf->doacross_buf_idx ) { // Shared buffer is occupied, wait for it to be free __kmp_wait_yield_4( (kmp_uint32*)&sh_buf->doacross_buf_idx, idx, __kmp_eq_4, NULL ); @@ -3300,14 +3309,14 @@ if( num_done == th->th.th_team_nproc ) { // we are the last thread, need to free shared resources int idx = pr_buf->th_doacross_buf_idx - 1; - dispatch_shared_info_t *sh_buf = &team->t.t_disp_buffer[idx % KMP_MAX_DISP_BUF]; + dispatch_shared_info_t *sh_buf = &team->t.t_disp_buffer[idx % __kmp_dispatch_num_buffers]; KMP_DEBUG_ASSERT(pr_buf->th_doacross_info[1] == (kmp_int64)&sh_buf->doacross_num_done); KMP_DEBUG_ASSERT(num_done == (kmp_int64)sh_buf->doacross_num_done); KMP_DEBUG_ASSERT(idx == sh_buf->doacross_buf_idx); __kmp_thread_free(th, (void*)sh_buf->doacross_flags); sh_buf->doacross_flags = NULL; sh_buf->doacross_num_done = 0; - sh_buf->doacross_buf_idx += KMP_MAX_DISP_BUF; // free buffer for future re-use + sh_buf->doacross_buf_idx += __kmp_dispatch_num_buffers; // free buffer for future re-use } // free private resources (need to keep buffer index forever) __kmp_thread_free(th, (void*)pr_buf->th_doacross_info); Index: openmp/trunk/runtime/src/kmp_dispatch.cpp =================================================================== --- openmp/trunk/runtime/src/kmp_dispatch.cpp +++ openmp/trunk/runtime/src/kmp_dispatch.cpp @@ -656,9 +656,9 @@ /* What happens when number of threads changes, need to resize buffer? */ pr = reinterpret_cast< dispatch_private_info_template< T > * > - ( &th -> th.th_dispatch -> th_disp_buffer[ my_buffer_index % KMP_MAX_DISP_BUF ] ); + ( &th -> th.th_dispatch -> th_disp_buffer[ my_buffer_index % __kmp_dispatch_num_buffers ] ); sh = reinterpret_cast< dispatch_shared_info_template< UT > volatile * > - ( &team -> t.t_disp_buffer[ my_buffer_index % KMP_MAX_DISP_BUF ] ); + ( &team -> t.t_disp_buffer[ my_buffer_index % __kmp_dispatch_num_buffers ] ); } /* Currently just ignore the monotonic and non-monotonic modifiers (the compiler isn't producing them @@ -2150,7 +2150,7 @@ KMP_MB(); /* Flush all pending memory write invalidates. */ - sh -> buffer_index += KMP_MAX_DISP_BUF; + sh -> buffer_index += __kmp_dispatch_num_buffers; KD_TRACE(100, ("__kmp_dispatch_next: T#%d change buffer_index:%d\n", gtid, sh->buffer_index) ); Index: openmp/trunk/runtime/src/kmp_ftn_entry.h =================================================================== --- openmp/trunk/runtime/src/kmp_ftn_entry.h +++ openmp/trunk/runtime/src/kmp_ftn_entry.h @@ -215,6 +215,19 @@ #endif } +void FTN_STDCALL +FTN_SET_DISP_NUM_BUFFERS( int KMP_DEREF arg ) +{ + #ifdef KMP_STUB + ; // empty routine + #else + // ignore after initialization because some teams have already + // allocated dispatch buffers + if( __kmp_init_serial == 0 && (KMP_DEREF arg) > 0 ) + __kmp_dispatch_num_buffers = KMP_DEREF arg; + #endif +} + int FTN_STDCALL FTN_SET_AFFINITY( void **mask ) { Index: openmp/trunk/runtime/src/kmp_ftn_os.h =================================================================== --- openmp/trunk/runtime/src/kmp_ftn_os.h +++ openmp/trunk/runtime/src/kmp_ftn_os.h @@ -35,6 +35,7 @@ #define FTN_SET_LIBRARY kmp_set_library #define FTN_GET_LIBRARY kmp_get_library #define FTN_SET_DEFAULTS kmp_set_defaults + #define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers #define FTN_SET_AFFINITY kmp_set_affinity #define FTN_GET_AFFINITY kmp_get_affinity #define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc @@ -152,6 +153,7 @@ #define FTN_SET_LIBRARY kmp_set_library_ #define FTN_GET_LIBRARY kmp_get_library_ #define FTN_SET_DEFAULTS kmp_set_defaults_ + #define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers_ #define FTN_SET_AFFINITY kmp_set_affinity_ #define FTN_GET_AFFINITY kmp_get_affinity_ #define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc_ @@ -270,6 +272,7 @@ #define FTN_SET_LIBRARY KMP_SET_LIBRARY #define FTN_GET_LIBRARY KMP_GET_LIBRARY #define FTN_SET_DEFAULTS KMP_SET_DEFAULTS + #define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS #define FTN_SET_AFFINITY KMP_SET_AFFINITY #define FTN_GET_AFFINITY KMP_GET_AFFINITY #define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC @@ -388,6 +391,7 @@ #define FTN_SET_LIBRARY KMP_SET_LIBRARY_ #define FTN_GET_LIBRARY KMP_GET_LIBRARY_ #define FTN_SET_DEFAULTS KMP_SET_DEFAULTS_ + #define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS_ #define FTN_SET_AFFINITY KMP_SET_AFFINITY_ #define FTN_GET_AFFINITY KMP_GET_AFFINITY_ #define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC_ Index: openmp/trunk/runtime/src/kmp_global.c =================================================================== --- openmp/trunk/runtime/src/kmp_global.c +++ openmp/trunk/runtime/src/kmp_global.c @@ -128,6 +128,7 @@ int __kmp_tp_capacity = 0; int __kmp_tp_cached = 0; int __kmp_dflt_nested = FALSE; +int __kmp_dispatch_num_buffers = KMP_DFLT_DISP_NUM_BUFF; int __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; /* max_active_levels limit */ #if KMP_NESTED_HOT_TEAMS int __kmp_hot_teams_mode = 0; /* 0 - free extra threads when reduced */ Index: openmp/trunk/runtime/src/kmp_runtime.c =================================================================== --- openmp/trunk/runtime/src/kmp_runtime.c +++ openmp/trunk/runtime/src/kmp_runtime.c @@ -489,7 +489,7 @@ static void __kmp_print_team_storage_map( const char *header, kmp_team_t *team, int team_id, int num_thr ) { - int num_disp_buff = team->t.t_max_nproc > 1 ? KMP_MAX_DISP_BUF : 2; + int num_disp_buff = team->t.t_max_nproc > 1 ? __kmp_dispatch_num_buffers : 2; __kmp_print_storage_map_gtid( -1, team, team + 1, sizeof(kmp_team_t), "%s_%d", header, team_id ); @@ -2967,7 +2967,7 @@ __kmp_allocate_team_arrays(kmp_team_t *team, int max_nth) { int i; - int num_disp_buff = max_nth > 1 ? KMP_MAX_DISP_BUF : 2; + int num_disp_buff = max_nth > 1 ? __kmp_dispatch_num_buffers : 2; team->t.t_threads = (kmp_info_t**) __kmp_allocate( sizeof(kmp_info_t*) * max_nth ); team->t.t_disp_buffer = (dispatch_shared_info_t*) __kmp_allocate( sizeof(dispatch_shared_info_t) * num_disp_buff ); @@ -4040,7 +4040,7 @@ * Use team max_nproc since this will never change for the team. */ size_t disp_size = sizeof( dispatch_private_info_t ) * - ( team->t.t_max_nproc == 1 ? 1 : KMP_MAX_DISP_BUF ); + ( team->t.t_max_nproc == 1 ? 1 : __kmp_dispatch_num_buffers ); KD_TRACE( 10, ("__kmp_initialize_info: T#%d max_nproc: %d\n", gtid, team->t.t_max_nproc ) ); KMP_ASSERT( dispatch ); KMP_DEBUG_ASSERT( team->t.t_dispatch ); @@ -4055,7 +4055,7 @@ if ( __kmp_storage_map ) { __kmp_print_storage_map_gtid( gtid, &dispatch->th_disp_buffer[ 0 ], - &dispatch->th_disp_buffer[ team->t.t_max_nproc == 1 ? 1 : KMP_MAX_DISP_BUF ], + &dispatch->th_disp_buffer[ team->t.t_max_nproc == 1 ? 1 : __kmp_dispatch_num_buffers ], disp_size, "th_%d.th_dispatch.th_disp_buffer " "(team_%d.t_dispatch[%d].th_disp_buffer)", gtid, team->t.t_id, gtid ); @@ -6997,7 +6997,7 @@ KMP_DEBUG_ASSERT( team->t.t_disp_buffer ); if ( team->t.t_max_nproc > 1 ) { int i; - for (i = 0; i < KMP_MAX_DISP_BUF; ++i) { + for (i = 0; i < __kmp_dispatch_num_buffers; ++i) { team->t.t_disp_buffer[ i ].buffer_index = i; #if OMP_41_ENABLED team->t.t_disp_buffer[i].doacross_buf_idx = i; Index: openmp/trunk/runtime/src/kmp_settings.c =================================================================== --- openmp/trunk/runtime/src/kmp_settings.c +++ openmp/trunk/runtime/src/kmp_settings.c @@ -1197,6 +1197,23 @@ } // __kmp_stg_print_max_task_priority #endif // OMP_41_ENABLED +// ------------------------------------------------------------------------------------------------- +// KMP_DISP_NUM_BUFFERS +// ------------------------------------------------------------------------------------------------- +static void +__kmp_stg_parse_disp_buffers( char const * name, char const * value, void * data ) { + if ( TCR_4(__kmp_init_serial) ) { + KMP_WARNING( EnvSerialWarn, name ); + return; + } // read value before serial initialization only + __kmp_stg_parse_int( name, value, 1, KMP_MAX_NTH, & __kmp_dispatch_num_buffers ); +} // __kmp_stg_parse_disp_buffers + +static void +__kmp_stg_print_disp_buffers( kmp_str_buf_t * buffer, char const * name, void * data ) { + __kmp_stg_print_int( buffer, name, __kmp_dispatch_num_buffers ); +} // __kmp_stg_print_disp_buffers + #if KMP_NESTED_HOT_TEAMS // ------------------------------------------------------------------------------------------------- // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE @@ -4646,6 +4663,7 @@ #endif { "OMP_THREAD_LIMIT", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 }, { "OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 }, + { "KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers, __kmp_stg_print_disp_buffers, NULL, 0, 0 }, #if KMP_NESTED_HOT_TEAMS { "KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level, __kmp_stg_print_hot_teams_level, NULL, 0, 0 }, { "KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode, __kmp_stg_print_hot_teams_mode, NULL, 0, 0 }, Index: openmp/trunk/runtime/src/kmp_stub.c =================================================================== --- openmp/trunk/runtime/src/kmp_stub.c +++ openmp/trunk/runtime/src/kmp_stub.c @@ -41,6 +41,7 @@ #define kmp_set_blocktime kmpc_set_blocktime #define kmp_set_library kmpc_set_library #define kmp_set_defaults kmpc_set_defaults +#define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers #define kmp_malloc kmpc_malloc #define kmp_aligned_malloc kmpc_aligned_malloc #define kmp_calloc kmpc_calloc @@ -100,6 +101,7 @@ void kmp_set_blocktime( omp_int_t arg ) { i; __kmps_set_blocktime( arg ); } void kmp_set_library( omp_int_t arg ) { i; __kmps_set_library( arg ); } void kmp_set_defaults( char const * str ) { i; } +void kmp_set_disp_num_buffers( omp_int_t arg ) { i; } /* KMP memory management functions. */ void * kmp_malloc( size_t size ) { i; return malloc( size ); } Index: openmp/trunk/runtime/test/env/kmp_set_dispatch_buf.c =================================================================== --- openmp/trunk/runtime/test/env/kmp_set_dispatch_buf.c +++ openmp/trunk/runtime/test/env/kmp_set_dispatch_buf.c @@ -0,0 +1,76 @@ +// RUN: %libomp-compile && env KMP_DISP_NUM_BUFFERS=0 %libomp-run +// RUN: env KMP_DISP_NUM_BUFFERS=1 %libomp-run && env KMP_DISP_NUM_BUFFERS=3 %libomp-run +// RUN: env KMP_DISP_NUM_BUFFERS=4 %libomp-run && env KMP_DISP_NUM_BUFFERS=7 %libomp-run +// RUN: %libomp-compile -DMY_SCHEDULE=guided && env KMP_DISP_NUM_BUFFERS=1 %libomp-run +// RUN: env KMP_DISP_NUM_BUFFERS=3 %libomp-run && env KMP_DISP_NUM_BUFFERS=4 %libomp-run +// RUN: env KMP_DISP_NUM_BUFFERS=7 %libomp-run +#include +#include +#include +#include +#include "omp_testsuite.h" + +#define INCR 7 +#define MY_MAX 200 +#define MY_MIN -200 +#define NUM_LOOPS 100 +#ifndef MY_SCHEDULE +# define MY_SCHEDULE dynamic +#endif + +int a, b, a_known_value, b_known_value; + +int test_kmp_set_disp_num_buffers() +{ + int success = 1; + a = 0; + b = 0; + // run many small dynamic loops to stress the dispatch buffer system + #pragma omp parallel + { + int i,j; + for (j = 0; j < NUM_LOOPS; j++) { + #pragma omp for schedule(MY_SCHEDULE) nowait + for (i = MY_MIN; i < MY_MAX; i+=INCR) { + #pragma omp atomic + a++; + } + #pragma omp for schedule(MY_SCHEDULE) nowait + for (i = MY_MAX; i >= MY_MIN; i-=INCR) { + #pragma omp atomic + b++; + } + } + } + // detect failure + if (a != a_known_value || b != b_known_value) { + success = 0; + printf("a = %d (should be %d), b = %d (should be %d)\n", a, a_known_value, + b, b_known_value); + } + return success; +} + +int main(int argc, char** argv) +{ + int i,j; + int num_failed=0; + + // figure out the known values to compare with calculated result + a_known_value = 0; + b_known_value = 0; + + for (j = 0; j < NUM_LOOPS; j++) { + for (i = MY_MIN; i < MY_MAX; i+=INCR) + a_known_value++; + for (i = MY_MAX; i >= MY_MIN; i-=INCR) + b_known_value++; + } + + for(i = 0; i < REPETITIONS; i++) { + if(!test_kmp_set_disp_num_buffers()) { + num_failed++; + } + } + return num_failed; +} Index: openmp/trunk/runtime/test/worksharing/for/kmp_set_dispatch_buf.c =================================================================== --- openmp/trunk/runtime/test/worksharing/for/kmp_set_dispatch_buf.c +++ openmp/trunk/runtime/test/worksharing/for/kmp_set_dispatch_buf.c @@ -0,0 +1,91 @@ +// RUN: %libomp-compile && %libomp-run 7 +// RUN: %libomp-run 0 && %libomp-run -1 +// RUN: %libomp-run 1 && %libomp-run 2 && %libomp-run 5 +// RUN: %libomp-compile -DMY_SCHEDULE=guided && %libomp-run 7 +// RUN: %libomp-run 1 && %libomp-run 2 && %libomp-run 5 +#include +#include +#include +#include +#include "omp_testsuite.h" + +#define INCR 7 +#define MY_MAX 200 +#define MY_MIN -200 +#ifndef MY_SCHEDULE +# define MY_SCHEDULE dynamic +#endif + +int num_disp_buffers, num_loops; +int a, b, a_known_value, b_known_value; + +int test_kmp_set_disp_num_buffers() +{ + int success = 1; + a = 0; + b = 0; + // run many small dynamic loops to stress the dispatch buffer system + #pragma omp parallel + { + int i,j; + for (j = 0; j < num_loops; j++) { + #pragma omp for schedule(MY_SCHEDULE) nowait + for (i = MY_MIN; i < MY_MAX; i+=INCR) { + #pragma omp atomic + a++; + } + #pragma omp for schedule(MY_SCHEDULE) nowait + for (i = MY_MAX; i >= MY_MIN; i-=INCR) { + #pragma omp atomic + b++; + } + } + } + // detect failure + if (a != a_known_value || b != b_known_value) { + success = 0; + printf("a = %d (should be %d), b = %d (should be %d)\n", a, a_known_value, + b, b_known_value); + } + return success; +} + +int main(int argc, char** argv) +{ + int i,j; + int num_failed=0; + + if (argc != 2) { + fprintf(stderr, "usage: %s num_disp_buffers\n", argv[0]); + exit(1); + } + + // set the number of dispatch buffers + num_disp_buffers = atoi(argv[1]); + kmp_set_disp_num_buffers(num_disp_buffers); + + // figure out the known values to compare with calculated result + a_known_value = 0; + b_known_value = 0; + + // if specified to use bad num_disp_buffers set num_loops + // to something reasonable + if (num_disp_buffers <= 0) + num_loops = 10; + else + num_loops = num_disp_buffers*10; + + for (j = 0; j < num_loops; j++) { + for (i = MY_MIN; i < MY_MAX; i+=INCR) + a_known_value++; + for (i = MY_MAX; i >= MY_MIN; i-=INCR) + b_known_value++; + } + + for(i = 0; i < REPETITIONS; i++) { + if(!test_kmp_set_disp_num_buffers()) { + num_failed++; + } + } + return num_failed; +}