13cab2bb3Spatrick //===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of *Sanitizer runtime.
103cab2bb3Spatrick // It provides handy wrappers for thread manipulation, that:
113cab2bb3Spatrick // a) assert on any failure rather than returning an error code
123cab2bb3Spatrick // b) defines pthread-like interface on platforms where where <pthread.h>
133cab2bb3Spatrick // is not supplied by default.
143cab2bb3Spatrick //
153cab2bb3Spatrick //===----------------------------------------------------------------------===//
163cab2bb3Spatrick
173cab2bb3Spatrick #ifndef SANITIZER_PTHREAD_WRAPPERS_H
183cab2bb3Spatrick #define SANITIZER_PTHREAD_WRAPPERS_H
193cab2bb3Spatrick
203cab2bb3Spatrick #include "sanitizer_test_utils.h"
213cab2bb3Spatrick
223cab2bb3Spatrick #if !defined(_WIN32)
233cab2bb3Spatrick # include <pthread.h>
243cab2bb3Spatrick // Simply forward the arguments and check that the pthread functions succeed.
253cab2bb3Spatrick # define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
263cab2bb3Spatrick # define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
273cab2bb3Spatrick #else
283cab2bb3Spatrick typedef HANDLE pthread_t;
293cab2bb3Spatrick
303cab2bb3Spatrick struct PthreadHelperCreateThreadInfo {
313cab2bb3Spatrick void *(*start_routine)(void *);
323cab2bb3Spatrick void *arg;
333cab2bb3Spatrick };
343cab2bb3Spatrick
PthreadHelperThreadProc(void * arg)353cab2bb3Spatrick inline DWORD WINAPI PthreadHelperThreadProc(void *arg) {
363cab2bb3Spatrick PthreadHelperCreateThreadInfo *start_data =
373cab2bb3Spatrick reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg);
38*1f9cb04fSpatrick (start_data->start_routine)(start_data->arg);
393cab2bb3Spatrick delete start_data;
40*1f9cb04fSpatrick return 0;
413cab2bb3Spatrick }
423cab2bb3Spatrick
PTHREAD_CREATE(pthread_t * thread,void * attr,void * (* start_routine)(void *),void * arg)433cab2bb3Spatrick inline void PTHREAD_CREATE(pthread_t *thread, void *attr,
443cab2bb3Spatrick void *(*start_routine)(void *), void *arg) {
453cab2bb3Spatrick ASSERT_EQ(0, attr) << "Thread attributes are not supported yet.";
463cab2bb3Spatrick PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo;
473cab2bb3Spatrick data->start_routine = start_routine;
483cab2bb3Spatrick data->arg = arg;
493cab2bb3Spatrick *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0);
503cab2bb3Spatrick DWORD err = GetLastError();
513cab2bb3Spatrick ASSERT_NE(nullptr, *thread) << "Failed to create a thread, got error 0x"
523cab2bb3Spatrick << std::hex << err;
533cab2bb3Spatrick }
543cab2bb3Spatrick
PTHREAD_JOIN(pthread_t thread,void ** value_ptr)553cab2bb3Spatrick inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) {
563cab2bb3Spatrick ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet.";
573cab2bb3Spatrick ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
583cab2bb3Spatrick ASSERT_NE(0, CloseHandle(thread));
593cab2bb3Spatrick }
603cab2bb3Spatrick
pthread_exit(void * retval)613cab2bb3Spatrick inline void pthread_exit(void *retval) {
623cab2bb3Spatrick ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet.";
63*1f9cb04fSpatrick ExitThread(0);
643cab2bb3Spatrick }
653cab2bb3Spatrick #endif // _WIN32
663cab2bb3Spatrick
673cab2bb3Spatrick #endif // SANITIZER_PTHREAD_WRAPPERS_H
68