Compare commits
12
Commits
master
...
release_38
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f265434b0 | ||
|
|
5d7cd23bf9 | ||
|
|
419f79a525 | ||
|
|
60b06d9aa3 | ||
|
|
1d8561a4a6 | ||
|
|
473d3c796a | ||
|
|
ed91a0b160 | ||
|
|
dad1f8e014 | ||
|
|
8296dac06b | ||
|
|
e64e7eefb8 | ||
|
|
02b26dc7bb | ||
|
|
d1c1aa93f6 |
@@ -192,8 +192,9 @@ elseif("${libomp_build_type_lowercase}" STREQUAL "minsizerel")
|
||||
set(MINSIZEREL_BUILD TRUE)
|
||||
endif()
|
||||
|
||||
# Include itt notify interface? Right now, always.
|
||||
set(LIBOMP_USE_ITT_NOTIFY TRUE)
|
||||
# Include itt notify interface?
|
||||
set(LIBOMP_USE_ITT_NOTIFY TRUE CACHE BOOL
|
||||
"Enable ITT notify?")
|
||||
|
||||
# normal, profile, stubs library.
|
||||
set(NORMAL_LIBRARY FALSE)
|
||||
@@ -326,6 +327,7 @@ if(${LIBOMP_STANDALONE_BUILD})
|
||||
libomp_say("Build -- ${LIBOMP_BUILD}")
|
||||
libomp_say("Use Stats-gathering -- ${LIBOMP_STATS}")
|
||||
libomp_say("Use Debugger-support -- ${LIBOMP_USE_DEBUGGER}")
|
||||
libomp_say("Use ITT notify -- ${LIBOMP_USE_ITT_NOTIFY}")
|
||||
libomp_say("Use OMPT-support -- ${LIBOMP_OMPT_SUPPORT}")
|
||||
if(${LIBOMP_OMPT_SUPPORT})
|
||||
libomp_say("Use OMPT-blame -- ${LIBOMP_OMPT_BLAME}")
|
||||
|
||||
@@ -144,7 +144,11 @@ set_target_properties(omp PROPERTIES
|
||||
)
|
||||
|
||||
# Get the library's location within the build tree for the unit tester
|
||||
get_target_property(LIBOMP_LIBRARY_DIR omp LIBRARY_OUTPUT_DIRECTORY)
|
||||
if(NOT WIN32)
|
||||
get_target_property(LIBOMP_LIBRARY_DIR omp LIBRARY_OUTPUT_DIRECTORY)
|
||||
else()
|
||||
get_target_property(LIBOMP_LIBRARY_DIR omp RUNTIME_OUTPUT_DIRECTORY)
|
||||
endif()
|
||||
if(NOT LIBOMP_LIBRARY_DIR)
|
||||
set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
|
||||
@@ -181,10 +185,11 @@ if(WIN32)
|
||||
add_dependencies(omp libomp-needed-windows-files)
|
||||
# z_Windows_NT-586_asm.asm requires definitions to be sent via command line
|
||||
# It only needs the architecutre macro and OMPT_SUPPORT=0|1
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "_M_IA32" IF_TRUE IA32)
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "_M_AMD64" IF_TRUE INTEL64)
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "OMPT_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPT_SUPPORT)
|
||||
set_source_files_properties(z_Windows_NT-586_asm.asm PROPERTIES COMPILE_DEFINITIONS "${LIBOMP_MASM_DEFINITIONS}")
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_IA32" IF_TRUE IA32)
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_AMD64" IF_TRUE INTEL64)
|
||||
libomp_append(LIBOMP_MASM_DEFINITIONS "-DOMPT_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPT_SUPPORT)
|
||||
libomp_list_to_string("${LIBOMP_MASM_DEFINITIONS}" LIBOMP_MASM_DEFINITIONS)
|
||||
set_property(SOURCE z_Windows_NT-586_asm.asm APPEND_STRING PROPERTY COMPILE_FLAGS " ${LIBOMP_MASM_DEFINITIONS}")
|
||||
set_source_files_properties(thirdparty/ittnotify/ittnotify_static.c PROPERTIES COMPILE_DEFINITIONS "UNICODE")
|
||||
|
||||
# Create Windows import library
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
#if defined( __cplusplus ) && ( KMP_OS_WINDOWS )
|
||||
// create shortcuts for c99 complex types
|
||||
|
||||
// Visual Studio cannot have function parameters that have the
|
||||
// align __declspec attribute, so we must remove it. (Compiler Error C2719)
|
||||
#if KMP_COMPILER_MSVC
|
||||
# undef KMP_DO_ALIGN
|
||||
# define KMP_DO_ALIGN(alignment) /* Nothing */
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER < 1600) && defined(_DEBUG)
|
||||
// Workaround for the problem of _DebugHeapTag unresolved external.
|
||||
// This problem prevented to use our static debug library for C tests
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
#define KMP_ADJUST_BLOCKTIME 1
|
||||
#define BUILD_PARALLEL_ORDERED 1
|
||||
#define KMP_ASM_INTRINS 1
|
||||
#define USE_ITT_BUILD 1
|
||||
#define USE_ITT_BUILD LIBOMP_USE_ITT_NOTIFY
|
||||
#define INTEL_ITTNOTIFY_PREFIX __kmp_itt_
|
||||
#if ! KMP_MIC
|
||||
# define USE_LOAD_BALANCE 1
|
||||
|
||||
@@ -511,7 +511,7 @@ __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32 global_tid)
|
||||
|
||||
// we need to wait for the proxy tasks before finishing the thread
|
||||
if ( task_team != NULL && task_team->tt.tt_found_proxy_tasks )
|
||||
__kmp_task_team_wait(this_thr, serial_team, NULL ); // is an ITT object needed here?
|
||||
__kmp_task_team_wait(this_thr, serial_team USE_ITT_BUILD_ARG(NULL) ); // is an ITT object needed here?
|
||||
#endif
|
||||
|
||||
KMP_MB();
|
||||
@@ -654,8 +654,10 @@ __kmpc_flush(ident_t *loc)
|
||||
if ( ! __kmp_cpuinfo.sse2 ) {
|
||||
// CPU cannot execute SSE2 instructions.
|
||||
} else {
|
||||
#if KMP_COMPILER_ICC || KMP_COMPILER_MSVC
|
||||
#if KMP_COMPILER_ICC
|
||||
_mm_mfence();
|
||||
#elif KMP_COMPILER_MSVC
|
||||
MemoryBarrier();
|
||||
#else
|
||||
__sync_synchronize();
|
||||
#endif // KMP_COMPILER_ICC
|
||||
|
||||
@@ -3578,6 +3578,7 @@ __kmp_cleanup_indirect_user_locks()
|
||||
__kmp_free(ll->lock);
|
||||
ll->lock = NULL;
|
||||
}
|
||||
__kmp_indirect_lock_pool[k] = NULL;
|
||||
}
|
||||
// Clean up the remaining undestroyed locks.
|
||||
for (i = 0; i < __kmp_i_lock_table.next; i++) {
|
||||
|
||||
@@ -3804,7 +3804,9 @@ __kmp_register_root( int initial_thread )
|
||||
/* prepare the master thread for get_gtid() */
|
||||
__kmp_gtid_set_specific( gtid );
|
||||
|
||||
#if USE_ITT_BUILD
|
||||
__kmp_itt_thread_name( gtid );
|
||||
#endif /* USE_ITT_BUILD */
|
||||
|
||||
#ifdef KMP_TDATA_GTID
|
||||
__kmp_gtid = gtid;
|
||||
@@ -3972,7 +3974,7 @@ __kmp_unregister_root_current_thread( int gtid )
|
||||
// the runtime is shutting down so we won't report any events
|
||||
thread->th.ompt_thread_info.state = ompt_state_undefined;
|
||||
#endif
|
||||
__kmp_task_team_wait(thread, team, NULL );
|
||||
__kmp_task_team_wait(thread, team USE_ITT_BUILD_ARG(NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -691,13 +691,12 @@ __kmp_task_finish( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t *resumed_tas
|
||||
}
|
||||
|
||||
// Free this task and then ancestor tasks if they have no children.
|
||||
// Restore th_current_task first as suggested by John:
|
||||
// johnmc: if an asynchronous inquiry peers into the runtime system
|
||||
// it doesn't see the freed task as the current task.
|
||||
thread->th.th_current_task = resumed_task;
|
||||
__kmp_free_task_and_ancestors(gtid, taskdata, thread);
|
||||
|
||||
// FIXME johnmc: I this statement should be before the last one so if an
|
||||
// asynchronous inquiry peers into the runtime system it doesn't see the freed
|
||||
// task as the current task
|
||||
__kmp_threads[ gtid ] -> th.th_current_task = resumed_task; // restore current_task
|
||||
|
||||
// TODO: GEH - make sure root team implicit task is initialized properly.
|
||||
// KMP_DEBUG_ASSERT( resumed_task->td_flags.executing == 0 );
|
||||
resumed_task->td_flags.executing = 1; // resume previous task
|
||||
|
||||
@@ -105,7 +105,7 @@ char const __kmp_version_copyright[] = KMP_VERSION_PREFIX KMP_COPYRIGHT;
|
||||
char const __kmp_version_lib_ver[] = KMP_VERSION_PREFIX "version: " stringer( KMP_VERSION_MAJOR ) "." stringer( KMP_VERSION_MINOR ) "." stringer( KMP_VERSION_BUILD );
|
||||
char const __kmp_version_lib_type[] = KMP_VERSION_PREFIX "library type: " KMP_LIB_TYPE;
|
||||
char const __kmp_version_link_type[] = KMP_VERSION_PREFIX "link type: " KMP_LINK_TYPE;
|
||||
char const __kmp_version_build_time[] = KMP_VERSION_PREFIX "build time: " __DATE__ " " __TIME__;
|
||||
char const __kmp_version_build_time[] = KMP_VERSION_PREFIX "build time: " "no_timestamp";
|
||||
#if KMP_MIC2
|
||||
char const __kmp_version_target_env[] = KMP_VERSION_PREFIX "target environment: MIC2";
|
||||
#endif
|
||||
|
||||
@@ -1414,6 +1414,227 @@ KMP_LABEL(kmp_1_exit):
|
||||
// -----------------------------------------------------------------------
|
||||
#endif /* KMP_ARCH_X86_64 */
|
||||
|
||||
#if KMP_ARCH_PPC64
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// typedef void (*microtask_t)( int *gtid, int *tid, ... );
|
||||
//
|
||||
// int
|
||||
// __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...),
|
||||
// int gtid, int tid,
|
||||
// int argc, void *p_argv[] ) {
|
||||
// (*pkfn)( & gtid, & tid, argv[0], ... );
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// parameters:
|
||||
// r3: pkfn
|
||||
// r4: gtid
|
||||
// r5: tid
|
||||
// r6: argc
|
||||
// r7: p_argv
|
||||
// r8: &exit_frame
|
||||
//
|
||||
// return: r3 (always 1/TRUE)
|
||||
//
|
||||
.text
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
.abiversion 2
|
||||
# endif
|
||||
.globl __kmp_invoke_microtask
|
||||
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
.p2align 4
|
||||
# else
|
||||
.p2align 2
|
||||
# endif
|
||||
|
||||
.type __kmp_invoke_microtask,@function
|
||||
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
__kmp_invoke_microtask:
|
||||
.Lfunc_begin0:
|
||||
.Lfunc_gep0:
|
||||
addis 2, 12, .TOC.-.Lfunc_gep0@ha
|
||||
addi 2, 2, .TOC.-.Lfunc_gep0@l
|
||||
.Lfunc_lep0:
|
||||
.localentry __kmp_invoke_microtask, .Lfunc_lep0-.Lfunc_gep0
|
||||
# else
|
||||
.section .opd,"aw",@progbits
|
||||
__kmp_invoke_microtask:
|
||||
.p2align 3
|
||||
.quad .Lfunc_begin0
|
||||
.quad .TOC.@tocbase
|
||||
.quad 0
|
||||
.text
|
||||
.Lfunc_begin0:
|
||||
# endif
|
||||
|
||||
// -- Begin __kmp_invoke_microtask
|
||||
// mark_begin;
|
||||
|
||||
// We need to allocate a stack frame large enough to hold all of the parameters
|
||||
// on the stack for the microtask plus what this function needs. That's 48
|
||||
// bytes under the ELFv1 ABI (32 bytes under ELFv2), plus 8*(2 + argc) for the
|
||||
// parameters to the microtask, plus 8 bytes to store the values of r4 and r5,
|
||||
// and 8 bytes to store r31. With OMP-T support, we need an additional 8 bytes
|
||||
// to save r30 to hold a copy of r8.
|
||||
|
||||
.cfi_startproc
|
||||
mflr 0
|
||||
std 31, -8(1)
|
||||
std 0, 16(1)
|
||||
|
||||
// This is unusual because normally we'd set r31 equal to r1 after the stack
|
||||
// frame is established. In this case, however, we need to dynamically compute
|
||||
// the stack frame size, and so we keep a direct copy of r1 to access our
|
||||
// register save areas and restore the r1 value before returning.
|
||||
mr 31, 1
|
||||
.cfi_def_cfa_register r31
|
||||
.cfi_offset r31, -8
|
||||
.cfi_offset lr, 16
|
||||
|
||||
// Compute the size necessary for the local stack frame.
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
li 12, 72
|
||||
# else
|
||||
li 12, 88
|
||||
# endif
|
||||
sldi 0, 6, 3
|
||||
add 12, 0, 12
|
||||
neg 12, 12
|
||||
|
||||
// We need to make sure that the stack frame stays aligned (to 16 bytes, except
|
||||
// under the BG/Q CNK, where it must be to 32 bytes).
|
||||
# if KMP_OS_CNK
|
||||
li 0, -32
|
||||
# else
|
||||
li 0, -16
|
||||
# endif
|
||||
and 12, 0, 12
|
||||
|
||||
// Establish the local stack frame.
|
||||
stdux 1, 1, 12
|
||||
|
||||
# if OMPT_SUPPORT
|
||||
.cfi_offset r30, -16
|
||||
std 30, -16(31)
|
||||
std 1, 0(8)
|
||||
mr 30, 8
|
||||
# endif
|
||||
|
||||
// Store gtid and tid to the stack because they're passed by reference to the microtask.
|
||||
stw 4, -20(31)
|
||||
stw 5, -24(31)
|
||||
|
||||
mr 12, 6
|
||||
mr 4, 7
|
||||
|
||||
cmpwi 0, 12, 1
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 5, 0(4)
|
||||
|
||||
cmpwi 0, 12, 2
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 6, 8(4)
|
||||
|
||||
cmpwi 0, 12, 3
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 7, 16(4)
|
||||
|
||||
cmpwi 0, 12, 4
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 8, 24(4)
|
||||
|
||||
cmpwi 0, 12, 5
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 9, 32(4)
|
||||
|
||||
cmpwi 0, 12, 6
|
||||
blt 0, .Lcall
|
||||
|
||||
ld 10, 40(4)
|
||||
|
||||
cmpwi 0, 12, 7
|
||||
blt 0, .Lcall
|
||||
|
||||
// There are more than 6 microtask parameters, so we need to store the
|
||||
// remainder to the stack.
|
||||
addi 12, 12, -6
|
||||
mtctr 12
|
||||
|
||||
// These are set to 8 bytes before the first desired store address (we're using
|
||||
// pre-increment loads and stores in the loop below). The parameter save area
|
||||
// for the microtask begins 48 + 8*8 == 112 bytes above r1 for ELFv1 and
|
||||
// 32 + 8*8 == 96 bytes above r1 for ELFv2.
|
||||
addi 4, 4, 40
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
addi 12, 1, 88
|
||||
# else
|
||||
addi 12, 1, 104
|
||||
# endif
|
||||
|
||||
.Lnext:
|
||||
ldu 0, 8(4)
|
||||
stdu 0, 8(12)
|
||||
bdnz .Lnext
|
||||
|
||||
.Lcall:
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
std 2, 24(1)
|
||||
mr 12, 3
|
||||
#else
|
||||
std 2, 40(1)
|
||||
// For ELFv1, we need to load the actual function address from the function descriptor.
|
||||
ld 12, 0(3)
|
||||
ld 2, 8(3)
|
||||
ld 11, 16(3)
|
||||
#endif
|
||||
|
||||
addi 3, 31, -20
|
||||
addi 4, 31, -24
|
||||
|
||||
mtctr 12
|
||||
bctrl
|
||||
# if KMP_ARCH_PPC64_LE
|
||||
ld 2, 24(1)
|
||||
# else
|
||||
ld 2, 40(1)
|
||||
# endif
|
||||
|
||||
# if OMPT_SUPPORT
|
||||
li 3, 0
|
||||
std 3, 0(30)
|
||||
# endif
|
||||
|
||||
li 3, 1
|
||||
|
||||
# if OMPT_SUPPORT
|
||||
ld 30, -16(31)
|
||||
# endif
|
||||
|
||||
mr 1, 31
|
||||
ld 0, 16(1)
|
||||
ld 31, -8(1)
|
||||
mtlr 0
|
||||
blr
|
||||
|
||||
.long 0
|
||||
.quad 0
|
||||
.Lfunc_end0:
|
||||
.size __kmp_invoke_microtask, .Lfunc_end0-.Lfunc_begin0
|
||||
.cfi_endproc
|
||||
|
||||
// -- End __kmp_invoke_microtask
|
||||
|
||||
#endif /* KMP_ARCH_PPC64 */
|
||||
|
||||
#if KMP_ARCH_ARM
|
||||
.data
|
||||
.comm .gomp_critical_user_,32,8
|
||||
|
||||
@@ -2615,7 +2615,7 @@ __kmp_get_load_balance( int max )
|
||||
|
||||
#endif // USE_LOAD_BALANCE
|
||||
|
||||
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC)
|
||||
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || KMP_ARCH_PPC64)
|
||||
|
||||
// we really only need the case with 1 argument, because CLANG always build
|
||||
// a struct of pointers to shared variables referenced in the outlined function
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# CMakeLists.txt file for unit testing OpenMP Library
|
||||
include(FindPythonInterp)
|
||||
include(CheckTypeSize)
|
||||
include(CheckLibraryExists)
|
||||
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
libomp_warning_say("Could not find Python.")
|
||||
@@ -8,6 +9,9 @@ if(NOT PYTHONINTERP_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Some tests use math functions
|
||||
check_library_exists(m sqrt "" LIBOMP_HAVE_LIBM)
|
||||
|
||||
macro(pythonize_bool var)
|
||||
if (${var})
|
||||
set(${var} True)
|
||||
@@ -17,6 +21,7 @@ macro(pythonize_bool var)
|
||||
endmacro()
|
||||
|
||||
pythonize_bool(LIBOMP_USE_HWLOC)
|
||||
pythonize_bool(LIBOMP_HAVE_LIBM)
|
||||
|
||||
set(LIBOMP_TEST_CFLAGS "" CACHE STRING
|
||||
"Extra compiler flags to send to the test compiler")
|
||||
|
||||
@@ -15,7 +15,7 @@ int test_omp_barrier()
|
||||
int rank;
|
||||
rank = omp_get_thread_num ();
|
||||
if (rank ==1) {
|
||||
my_sleep(SLEEPTIME);
|
||||
my_sleep(((double)SLEEPTIME)/REPETITIONS); // give 1 sec to whole test
|
||||
result2 = 3;
|
||||
}
|
||||
#pragma omp barrier
|
||||
@@ -31,10 +31,14 @@ int main()
|
||||
int i;
|
||||
int num_failed=0;
|
||||
|
||||
#ifdef _OPENMP
|
||||
omp_set_dynamic(0); // prevent runtime to change number of threads
|
||||
omp_set_num_threads(4); // the test expects at least 3 threads
|
||||
for(i = 0; i < REPETITIONS; i++) {
|
||||
if(!test_omp_barrier()) {
|
||||
num_failed++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
+20
-1
@@ -2,6 +2,7 @@
|
||||
# Configuration file for the 'lit' test runner.
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import lit.formats
|
||||
|
||||
# Tell pylint that we know config and lit_config exist somewhere.
|
||||
@@ -46,6 +47,11 @@ config.test_cflags = config.test_openmp_flag + \
|
||||
" -L " + config.library_dir + \
|
||||
" " + config.test_extra_cflags
|
||||
|
||||
# extra libraries
|
||||
libs = ""
|
||||
if config.has_libm:
|
||||
libs += " -lm"
|
||||
|
||||
# Setup environment to find dynamic library at runtime
|
||||
append_dynamic_library_path(config.library_dir)
|
||||
if config.using_hwloc:
|
||||
@@ -57,9 +63,22 @@ if config.operating_system == 'Darwin':
|
||||
if config.using_hwloc:
|
||||
config.test_cflags += " -Wl,-rpath," + config.hwloc_library_dir
|
||||
|
||||
# Find the SDK on Darwin
|
||||
if config.operating_system == 'Darwin':
|
||||
cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out, err = cmd.communicate()
|
||||
out = out.strip()
|
||||
res = cmd.wait()
|
||||
if res == 0 and out:
|
||||
config.test_cflags += " -isysroot " + out
|
||||
|
||||
# substitutions
|
||||
config.substitutions.append(("%libomp-compile-and-run", \
|
||||
"%clang %cflags %s -o %t -lm && %t"))
|
||||
"%libomp-compile && %libomp-run"))
|
||||
config.substitutions.append(("%libomp-compile", \
|
||||
"%clang %cflags %s -o %t" + libs))
|
||||
config.substitutions.append(("%libomp-run", "%t"))
|
||||
config.substitutions.append(("%clang", config.test_compiler))
|
||||
config.substitutions.append(("%openmp_flag", config.test_openmp_flag))
|
||||
config.substitutions.append(("%cflags", config.test_cflags))
|
||||
|
||||
@@ -9,6 +9,7 @@ config.omp_header_directory = "@LIBOMP_BINARY_DIR@/src"
|
||||
config.operating_system = "@CMAKE_SYSTEM_NAME@"
|
||||
config.hwloc_library_dir = "@LIBOMP_HWLOC_LIBRARY_DIR@"
|
||||
config.using_hwloc = @LIBOMP_USE_HWLOC@
|
||||
config.has_libm = @LIBOMP_HAVE_LIBM@
|
||||
|
||||
# Let the main config do the real work.
|
||||
lit_config.load_config(config, "@LIBOMP_BASE_DIR@/test/lit.cfg")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define OMP_TESTSUITE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <omp.h>
|
||||
|
||||
/* General */
|
||||
@@ -19,4 +20,60 @@
|
||||
#define NUM_TASKS 25
|
||||
#define MAX_TASKS_PER_THREAD 5
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows versions of pthread_create() and pthread_join()
|
||||
# include <windows.h>
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
// encapsulates the information about a pthread-callable function
|
||||
struct thread_func_info_t {
|
||||
void* (*start_routine)(void*);
|
||||
void* arg;
|
||||
};
|
||||
|
||||
// call the void* start_routine(void*);
|
||||
static DWORD __thread_func_wrapper(LPVOID lpParameter) {
|
||||
struct thread_func_info_t* function_information;
|
||||
function_information = (struct thread_func_info_t*)lpParameter;
|
||||
function_information->start_routine(function_information->arg);
|
||||
free(function_information);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// attr is ignored
|
||||
static int pthread_create(pthread_t *thread, void *attr,
|
||||
void *(*start_routine) (void *), void *arg) {
|
||||
pthread_t pthread;
|
||||
struct thread_func_info_t* info;
|
||||
info = (struct thread_func_info_t*)malloc(sizeof(struct thread_func_info_t));
|
||||
info->start_routine = start_routine;
|
||||
info->arg = arg;
|
||||
pthread = CreateThread(NULL, 0, __thread_func_wrapper, info, 0, NULL);
|
||||
if (pthread == NULL) {
|
||||
fprintf(stderr, "CreateThread() failed: Error #%u.\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
*thread = pthread;
|
||||
return 0;
|
||||
}
|
||||
// retval is ignored for now
|
||||
static int pthread_join(pthread_t thread, void **retval) {
|
||||
int rc;
|
||||
rc = WaitForSingleObject(thread, INFINITE);
|
||||
if (rc == WAIT_FAILED) {
|
||||
fprintf(stderr, "WaitForSingleObject() failed: Error #%u.\n",
|
||||
GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
rc = CloseHandle(thread);
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "CloseHandle() failed: Error #%u.\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user