| // 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 | 
 | 	} | 
 | } |