Index: lib/asan/tests/asan_test_utils.h =================================================================== --- lib/asan/tests/asan_test_utils.h +++ lib/asan/tests/asan_test_utils.h @@ -21,6 +21,8 @@ #endif #include "sanitizer_test_utils.h" +#include "sanitizer_pthread_wrappers.h" + #include #include #include @@ -30,10 +32,9 @@ #include #if !defined(_WIN32) -#include -#include -#include -#include +# include +# include +# include #endif #ifdef __linux__ @@ -48,10 +49,6 @@ #include #endif -// Check that pthread_create/pthread_join return success. -#define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d)) -#define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b)) - #if ASAN_HAS_EXCEPTIONS # define ASAN_THROW(x) throw (x) #else Index: lib/sanitizer_common/tests/CMakeLists.txt =================================================================== --- lib/sanitizer_common/tests/CMakeLists.txt +++ lib/sanitizer_common/tests/CMakeLists.txt @@ -26,6 +26,7 @@ sanitizer_thread_registry_test.cc) set(SANITIZER_TEST_HEADERS + sanitizer_pthread_wrappers.h sanitizer_test_utils.h) foreach(header ${SANITIZER_HEADERS}) list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header}) Index: lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h =================================================================== --- /dev/null +++ lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h @@ -0,0 +1,68 @@ +//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of *Sanitizer runtime. +// It provides handy wrappers for thread manipulation, that: +// a) assert on any failure rather than returning an error code +// b) defines pthread-like interface on platforms where where +// is not supplied by default. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PTHREAD_WRAPPERS_H +#define SANITIZER_PTHREAD_WRAPPERS_H + +#include "sanitizer_test_utils.h" + +#include "gtest/gtest.h" + +#if !defined(_WIN32) +# include +// Simply forward the arguments and check that the pthread functions succeed. +# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d)) +# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b)) +#else +typedef HANDLE pthread_t; + +struct PthreadHelperCreateThreadInfo { + void *(*start_routine)(void *); + void *arg; +}; + +inline DWORD WINAPI PthreadHelperThreadProc(void *arg) { + PthreadHelperCreateThreadInfo *start_data = + reinterpret_cast(arg); + void *ret = (start_data->start_routine)(start_data->arg); + delete start_data; + return (DWORD)ret; +} + +inline void PTHREAD_CREATE(pthread_t *thread, void *attr, + void *(*start_routine)(void *), void *arg) { + ASSERT_EQ(0, attr) << "Thread attributes are not supported yet."; + PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo; + data->start_routine = start_routine; + data->arg = arg; + *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0); + ASSERT_NE(nullptr, *thread) << "Failed to create a thread."; +} + +inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) { + ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet."; + ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE)); + ASSERT_NE(0, CloseHandle(thread)); +} + +inline void pthread_exit(void *retval) { + ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet."; + ExitThread((DWORD)retval); +} +#endif + +#endif // SANITIZER_PTHREAD_WRAPPERS_H Index: lib/sanitizer_common/tests/sanitizer_test_utils.h =================================================================== --- lib/sanitizer_common/tests/sanitizer_test_utils.h +++ lib/sanitizer_common/tests/sanitizer_test_utils.h @@ -15,6 +15,14 @@ #ifndef SANITIZER_TEST_UTILS_H #define SANITIZER_TEST_UTILS_H +#if defined(_WIN32) +// should always be the first include on Windows. +# include +// MSVS headers define max/min as macros, so std::max/min gets crazy. +# undef max +# undef min +#endif + #include #if defined(_MSC_VER)