1 /** 2 * Copyright (c) 2016 Tino Reichardt 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 * 9 * You can contact the author at: 10 * - zstdmt source repository: https://github.com/mcmilk/zstdmt 11 */ 12 13 /** 14 * This file will hold wrapper for systems, which do not support pthreads 15 */ 16 17 /* create fake symbol to avoid empty translation unit warning */ 18 int g_ZSTD_threading_useless_symbol; 19 20 #if defined(ZSTD_MULTITHREAD) && defined(_WIN32) 21 22 /** 23 * Windows minimalist Pthread Wrapper, based on : 24 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html 25 */ 26 27 28 /* === Dependencies === */ 29 #include <process.h> 30 #include <errno.h> 31 #include "threading.h" 32 33 34 /* === Implementation === */ 35 36 static unsigned __stdcall worker(void *arg) 37 { 38 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg; 39 thread->arg = thread->start_routine(thread->arg); 40 return 0; 41 } 42 43 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, 44 void* (*start_routine) (void*), void* arg) 45 { 46 (void)unused; 47 thread->arg = arg; 48 thread->start_routine = start_routine; 49 thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL); 50 51 if (!thread->handle) 52 return errno; 53 else 54 return 0; 55 } 56 57 int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr) 58 { 59 DWORD result; 60 61 if (!thread.handle) return 0; 62 63 result = WaitForSingleObject(thread.handle, INFINITE); 64 switch (result) { 65 case WAIT_OBJECT_0: 66 if (value_ptr) *value_ptr = thread.arg; 67 return 0; 68 case WAIT_ABANDONED: 69 return EINVAL; 70 default: 71 return GetLastError(); 72 } 73 } 74 75 #endif /* ZSTD_MULTITHREAD */ 76