forked from OSchip/llvm-project
Allow unit testing on Windows
These changes allow testing on Windows using clang.exe. There are two main changes: 1. Only link to -lm when it actually exists on the system 2. Create basic versions of pthread_create() and pthread_join() for windows. They are not POSIX compliant by any stretch but will allow any existing and future tests to use pthread_create() and pthread_join() for testing interactions of libomp with os threads. Differential Revision: http://reviews.llvm.org/D20391 llvm-svn: 270464
This commit is contained in:
parent
6c8f20d73d
commit
1ab887d403
|
@ -146,7 +146,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)
|
||||
|
|
|
@ -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)
|
||||
|
@ -20,6 +24,7 @@ pythonize_bool(LIBOMP_USE_HWLOC)
|
|||
pythonize_bool(LIBOMP_OMPT_SUPPORT)
|
||||
pythonize_bool(LIBOMP_OMPT_BLAME)
|
||||
pythonize_bool(LIBOMP_OMPT_TRACE)
|
||||
pythonize_bool(LIBOMP_HAVE_LIBM)
|
||||
|
||||
set(LIBOMP_TEST_CFLAGS "" CACHE STRING
|
||||
"Extra compiler flags to send to the test compiler")
|
||||
|
|
|
@ -48,6 +48,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"
|
||||
|
||||
# Allow XFAIL to work
|
||||
config.target_triple = [ ]
|
||||
if re.search('gcc', config.test_compiler) is not None:
|
||||
|
@ -92,7 +97,7 @@ if config.has_ompt:
|
|||
config.substitutions.append(("%libomp-compile-and-run", \
|
||||
"%libomp-compile && %libomp-run"))
|
||||
config.substitutions.append(("%libomp-compile", \
|
||||
"%clang %cflags %s -o %t -lm"))
|
||||
"%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))
|
||||
|
|
|
@ -11,6 +11,7 @@ config.operating_system = "@CMAKE_SYSTEM_NAME@"
|
|||
config.hwloc_library_dir = "@LIBOMP_HWLOC_LIBRARY_DIR@"
|
||||
config.using_hwloc = @LIBOMP_USE_HWLOC@
|
||||
config.has_ompt = @LIBOMP_OMPT_SUPPORT@ and @LIBOMP_OMPT_BLAME@ and @LIBOMP_OMPT_TRACE@
|
||||
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")
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// RUN: %libomp-compile-and-run
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include "omp_testsuite.h"
|
||||
|
||||
#define NUM_THREADS 10
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue