12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===// 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is distributed under the University of Illinois Open Source 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// License. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is a part of *Sanitizer runtime. 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// It provides handy wrappers for thread manipulation, that: 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// a) assert on any failure rather than returning an error code 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// b) defines pthread-like interface on platforms where where <pthread.h> 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// is not supplied by default. 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef SANITIZER_PTHREAD_WRAPPERS_H 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define SANITIZER_PTHREAD_WRAPPERS_H 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_test_utils.h" 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# include <pthread.h> 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Simply forward the arguments and check that the pthread functions succeed. 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d)) 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b)) 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef HANDLE pthread_t; 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct PthreadHelperCreateThreadInfo { 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *(*start_routine)(void *); 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *arg; 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}; 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesinline DWORD WINAPI PthreadHelperThreadProc(void *arg) { 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PthreadHelperCreateThreadInfo *start_data = 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg); 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *ret = (start_data->start_routine)(start_data->arg); 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines delete start_data; 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return (DWORD)ret; 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesinline void PTHREAD_CREATE(pthread_t *thread, void *attr, 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *(*start_routine)(void *), void *arg) { 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_EQ(0, attr) << "Thread attributes are not supported yet."; 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo; 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines data->start_routine = start_routine; 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines data->arg = arg; 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0); 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_NE(nullptr, *thread) << "Failed to create a thread."; 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesinline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) { 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet."; 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE)); 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_NE(0, CloseHandle(thread)); 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesinline void pthread_exit(void *retval) { 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet."; 622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ExitThread((DWORD)retval); 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // _WIN32 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_PTHREAD_WRAPPERS_H 67