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