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 #include "threading.h" 18 19 /* create fake symbol to avoid empty translation unit warning */ 20 int g_ZSTD_threading_useless_symbol; 21 22 #if defined(ZSTD_MULTITHREAD) && defined(_WIN32) 23 24 /** 25 * Windows minimalist Pthread Wrapper, based on : 26 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html 27 */ 28 29 30 /* === Dependencies === */ 31 #include <process.h> 32 #include <errno.h> 33 34 35 /* === Implementation === */ 36 37 static unsigned __stdcall worker(void *arg) 38 { 39 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg; 40 thread->arg = thread->start_routine(thread->arg); 41 return 0; 42 } 43 44 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, 45 void* (*start_routine) (void*), void* arg) 46 { 47 (void)unused; 48 thread->arg = arg; 49 thread->start_routine = start_routine; 50 thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL); 51 52 if (!thread->handle) 53 return errno; 54 else 55 return 0; 56 } 57 58 int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr) 59 { 60 DWORD result; 61 62 if (!thread.handle) return 0; 63 64 result = WaitForSingleObject(thread.handle, INFINITE); 65 switch (result) { 66 case WAIT_OBJECT_0: 67 if (value_ptr) *value_ptr = thread.arg; 68 return 0; 69 case WAIT_ABANDONED: 70 return EINVAL; 71 default: 72 return GetLastError(); 73 } 74 } 75 76 #endif /* ZSTD_MULTITHREAD */ 77 78 #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32) 79 80 #include <stdlib.h> 81 82 int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) 83 { 84 *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); 85 if (!*mutex) 86 return 1; 87 return pthread_mutex_init(*mutex, attr); 88 } 89 90 int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) 91 { 92 if (!*mutex) 93 return 0; 94 { 95 int const ret = pthread_mutex_destroy(*mutex); 96 free(*mutex); 97 return ret; 98 } 99 } 100 101 int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) 102 { 103 *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); 104 if (!*cond) 105 return 1; 106 return pthread_cond_init(*cond, attr); 107 } 108 109 int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) 110 { 111 if (!*cond) 112 return 0; 113 { 114 int const ret = pthread_cond_destroy(*cond); 115 free(*cond); 116 return ret; 117 } 118 } 119 120 #endif 121