1*d86ed7fbStbbdev /* 2*d86ed7fbStbbdev Copyright (c) 2005-2020 Intel Corporation 3*d86ed7fbStbbdev 4*d86ed7fbStbbdev Licensed under the Apache License, Version 2.0 (the "License"); 5*d86ed7fbStbbdev you may not use this file except in compliance with the License. 6*d86ed7fbStbbdev You may obtain a copy of the License at 7*d86ed7fbStbbdev 8*d86ed7fbStbbdev http://www.apache.org/licenses/LICENSE-2.0 9*d86ed7fbStbbdev 10*d86ed7fbStbbdev Unless required by applicable law or agreed to in writing, software 11*d86ed7fbStbbdev distributed under the License is distributed on an "AS IS" BASIS, 12*d86ed7fbStbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d86ed7fbStbbdev See the License for the specific language governing permissions and 14*d86ed7fbStbbdev limitations under the License. 15*d86ed7fbStbbdev */ 16*d86ed7fbStbbdev 17*d86ed7fbStbbdev /* 18*d86ed7fbStbbdev The original source for this example is 19*d86ed7fbStbbdev Copyright (c) 1994-2008 John E. Stone 20*d86ed7fbStbbdev All rights reserved. 21*d86ed7fbStbbdev 22*d86ed7fbStbbdev Redistribution and use in source and binary forms, with or without 23*d86ed7fbStbbdev modification, are permitted provided that the following conditions 24*d86ed7fbStbbdev are met: 25*d86ed7fbStbbdev 1. Redistributions of source code must retain the above copyright 26*d86ed7fbStbbdev notice, this list of conditions and the following disclaimer. 27*d86ed7fbStbbdev 2. Redistributions in binary form must reproduce the above copyright 28*d86ed7fbStbbdev notice, this list of conditions and the following disclaimer in the 29*d86ed7fbStbbdev documentation and/or other materials provided with the distribution. 30*d86ed7fbStbbdev 3. The name of the author may not be used to endorse or promote products 31*d86ed7fbStbbdev derived from this software without specific prior written permission. 32*d86ed7fbStbbdev 33*d86ed7fbStbbdev THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 34*d86ed7fbStbbdev OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35*d86ed7fbStbbdev WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36*d86ed7fbStbbdev ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 37*d86ed7fbStbbdev DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38*d86ed7fbStbbdev DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39*d86ed7fbStbbdev OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40*d86ed7fbStbbdev HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41*d86ed7fbStbbdev LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42*d86ed7fbStbbdev OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43*d86ed7fbStbbdev SUCH DAMAGE. 44*d86ed7fbStbbdev */ 45*d86ed7fbStbbdev 46*d86ed7fbStbbdev #ifdef EMULATE_PTHREADS 47*d86ed7fbStbbdev 48*d86ed7fbStbbdev #include <assert.h> 49*d86ed7fbStbbdev #include "pthread_w.hpp" 50*d86ed7fbStbbdev 51*d86ed7fbStbbdev /* 52*d86ed7fbStbbdev Basics 53*d86ed7fbStbbdev */ 54*d86ed7fbStbbdev 55*d86ed7fbStbbdev int pthread_create(pthread_t *thread, 56*d86ed7fbStbbdev pthread_attr_t *attr, 57*d86ed7fbStbbdev void *(*start_routine)(void *), 58*d86ed7fbStbbdev void *arg) { 59*d86ed7fbStbbdev pthread_t th; 60*d86ed7fbStbbdev 61*d86ed7fbStbbdev if (thread == nullptr) 62*d86ed7fbStbbdev return EINVAL; 63*d86ed7fbStbbdev *thread = nullptr; 64*d86ed7fbStbbdev 65*d86ed7fbStbbdev if (start_routine == nullptr) 66*d86ed7fbStbbdev return EINVAL; 67*d86ed7fbStbbdev 68*d86ed7fbStbbdev th = (pthread_t)malloc(sizeof(pthread_s)); 69*d86ed7fbStbbdev memset(th, 0, sizeof(pthread_s)); 70*d86ed7fbStbbdev 71*d86ed7fbStbbdev th->winthread_handle = 72*d86ed7fbStbbdev CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, &th->winthread_id); 73*d86ed7fbStbbdev if (th->winthread_handle == nullptr) 74*d86ed7fbStbbdev return EAGAIN; /* GetLastError() */ 75*d86ed7fbStbbdev 76*d86ed7fbStbbdev *thread = th; 77*d86ed7fbStbbdev return 0; 78*d86ed7fbStbbdev } 79*d86ed7fbStbbdev 80*d86ed7fbStbbdev int pthread_join(pthread_t th, void **thread_return) { 81*d86ed7fbStbbdev BOOL b_ret; 82*d86ed7fbStbbdev DWORD dw_ret; 83*d86ed7fbStbbdev 84*d86ed7fbStbbdev if (thread_return) 85*d86ed7fbStbbdev *thread_return = nullptr; 86*d86ed7fbStbbdev 87*d86ed7fbStbbdev if ((th == nullptr) || (th->winthread_handle == nullptr)) 88*d86ed7fbStbbdev return EINVAL; 89*d86ed7fbStbbdev 90*d86ed7fbStbbdev dw_ret = WaitForSingleObject(th->winthread_handle, INFINITE); 91*d86ed7fbStbbdev if (dw_ret != WAIT_OBJECT_0) 92*d86ed7fbStbbdev return ERROR_PTHREAD; /* dw_ret == WAIT_FAILED; GetLastError() */ 93*d86ed7fbStbbdev 94*d86ed7fbStbbdev if (thread_return) { 95*d86ed7fbStbbdev BOOL e_ret; 96*d86ed7fbStbbdev DWORD exit_val; 97*d86ed7fbStbbdev e_ret = GetExitCodeThread(th->winthread_handle, &exit_val); 98*d86ed7fbStbbdev if (!e_ret) 99*d86ed7fbStbbdev return ERROR_PTHREAD; /* GetLastError() */ 100*d86ed7fbStbbdev *thread_return = (void *)(std::size_t)exit_val; 101*d86ed7fbStbbdev } 102*d86ed7fbStbbdev 103*d86ed7fbStbbdev b_ret = CloseHandle(th->winthread_handle); 104*d86ed7fbStbbdev if (!b_ret) 105*d86ed7fbStbbdev return ERROR_PTHREAD; /* GetLastError() */ 106*d86ed7fbStbbdev memset(th, 0, sizeof(pthread_s)); 107*d86ed7fbStbbdev free(th); 108*d86ed7fbStbbdev th = nullptr; 109*d86ed7fbStbbdev 110*d86ed7fbStbbdev return 0; 111*d86ed7fbStbbdev } 112*d86ed7fbStbbdev 113*d86ed7fbStbbdev void pthread_exit(void *retval) { 114*d86ed7fbStbbdev /* specific to PTHREAD_TO_WINTHREAD */ 115*d86ed7fbStbbdev 116*d86ed7fbStbbdev ExitThread((DWORD)( 117*d86ed7fbStbbdev (std::size_t)retval)); /* thread becomes signalled so its death can be waited upon */ 118*d86ed7fbStbbdev /*NOTREACHED*/ 119*d86ed7fbStbbdev assert(0); 120*d86ed7fbStbbdev return; /* void fnc; can't return an error code */ 121*d86ed7fbStbbdev } 122*d86ed7fbStbbdev 123*d86ed7fbStbbdev /* 124*d86ed7fbStbbdev Mutex 125*d86ed7fbStbbdev */ 126*d86ed7fbStbbdev 127*d86ed7fbStbbdev int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mutex_attr) { 128*d86ed7fbStbbdev InitializeCriticalSection(&mutex->critsec); 129*d86ed7fbStbbdev return 0; 130*d86ed7fbStbbdev } 131*d86ed7fbStbbdev 132*d86ed7fbStbbdev int pthread_mutex_destroy(pthread_mutex_t *mutex) { 133*d86ed7fbStbbdev return 0; 134*d86ed7fbStbbdev } 135*d86ed7fbStbbdev 136*d86ed7fbStbbdev int pthread_mutex_lock(pthread_mutex_t *mutex) { 137*d86ed7fbStbbdev EnterCriticalSection(&mutex->critsec); 138*d86ed7fbStbbdev return 0; 139*d86ed7fbStbbdev } 140*d86ed7fbStbbdev 141*d86ed7fbStbbdev int pthread_mutex_unlock(pthread_mutex_t *mutex) { 142*d86ed7fbStbbdev LeaveCriticalSection(&mutex->critsec); 143*d86ed7fbStbbdev return 0; 144*d86ed7fbStbbdev } 145*d86ed7fbStbbdev 146*d86ed7fbStbbdev #endif /* EMULATE_PTHREADS */ 147