1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Thread.hpp" 16 17 namespace sw 18 { Thread(void (* threadFunction)(void * parameters),void * parameters)19 Thread::Thread(void (*threadFunction)(void *parameters), void *parameters) 20 { 21 Event init; 22 Entry entry = {threadFunction, parameters, &init}; 23 24 #if defined(_WIN32) 25 handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL); 26 #else 27 pthread_create(&handle, NULL, startFunction, &entry); 28 #endif 29 30 init.wait(); 31 } 32 ~Thread()33 Thread::~Thread() 34 { 35 join(); // Make threads exit before deleting them to not block here 36 } 37 join()38 void Thread::join() 39 { 40 if(!hasJoined) 41 { 42 #if defined(_WIN32) 43 WaitForSingleObject(handle, INFINITE); 44 CloseHandle(handle); 45 #else 46 pthread_join(handle, NULL); 47 #endif 48 49 hasJoined = true; 50 } 51 } 52 53 #if defined(_WIN32) startFunction(void * parameters)54 unsigned long __stdcall Thread::startFunction(void *parameters) 55 { 56 Entry entry = *(Entry*)parameters; 57 entry.init->signal(); 58 entry.threadFunction(entry.threadParameters); 59 return 0; 60 } 61 #else startFunction(void * parameters)62 void *Thread::startFunction(void *parameters) 63 { 64 Entry entry = *(Entry*)parameters; 65 entry.init->signal(); 66 entry.threadFunction(entry.threadParameters); 67 return nullptr; 68 } 69 #endif 70 Event()71 Event::Event() 72 { 73 #if defined(_WIN32) 74 handle = CreateEvent(NULL, FALSE, FALSE, NULL); 75 #else 76 pthread_cond_init(&handle, NULL); 77 pthread_mutex_init(&mutex, NULL); 78 signaled = false; 79 #endif 80 } 81 ~Event()82 Event::~Event() 83 { 84 #if defined(_WIN32) 85 CloseHandle(handle); 86 #else 87 pthread_cond_destroy(&handle); 88 pthread_mutex_destroy(&mutex); 89 #endif 90 } 91 } 92