// Copyright 2016 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "Thread.hpp" namespace sw { Thread::Thread(void (*threadFunction)(void *parameters), void *parameters) { Event init; Entry entry = {threadFunction, parameters, &init}; #if defined(_WIN32) handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL); #else pthread_create(&handle, NULL, startFunction, &entry); #endif init.wait(); } Thread::~Thread() { join(); // Make threads exit before deleting them to not block here } void Thread::join() { if(!hasJoined) { #if defined(_WIN32) WaitForSingleObject(handle, INFINITE); CloseHandle(handle); #else pthread_join(handle, NULL); #endif hasJoined = true; } } #if defined(_WIN32) unsigned long __stdcall Thread::startFunction(void *parameters) { Entry entry = *(Entry*)parameters; entry.init->signal(); entry.threadFunction(entry.threadParameters); return 0; } #else void *Thread::startFunction(void *parameters) { Entry entry = *(Entry*)parameters; entry.init->signal(); entry.threadFunction(entry.threadParameters); return nullptr; } #endif Event::Event() { #if defined(_WIN32) handle = CreateEvent(NULL, FALSE, FALSE, NULL); #else pthread_cond_init(&handle, NULL); pthread_mutex_init(&mutex, NULL); signaled = false; #endif } Event::~Event() { #if defined(_WIN32) CloseHandle(handle); #else pthread_cond_destroy(&handle); pthread_mutex_destroy(&mutex); #endif } }