1 /** 2 * Copyright (c) 2016 Tino Reichardt 3 * All rights reserved. 4 * 5 * You can contact the author at: 6 * - zstdmt source repository: https://github.com/mcmilk/zstdmt 7 * 8 * This source code is licensed under both the BSD-style license (found in the 9 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 10 * in the COPYING file in the root directory of this source tree). 11 * You may select, at your option, one of the above-listed licenses. 12 */ 13 14 /** 15 * This file will hold wrapper for systems, which do not support pthreads 16 */ 17 18 #include "threading.h" 19 20 /* create fake symbol to avoid empty translation unit warning */ 21 int g_ZSTD_threading_useless_symbol; 22 23 #if defined(ZSTD_MULTITHREAD) && defined(_WIN32) 24 25 /** 26 * Windows minimalist Pthread Wrapper, based on : 27 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html 28 */ 29 30 31 /* === Dependencies === */ 32 #include <process.h> 33 #include <errno.h> 34 35 36 /* === Implementation === */ 37 38 static unsigned __stdcall worker(void *arg) 39 { 40 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg; 41 thread->arg = thread->start_routine(thread->arg); 42 return 0; 43 } 44 45 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, 46 void* (*start_routine) (void*), void* arg) 47 { 48 (void)unused; 49 thread->arg = arg; 50 thread->start_routine = start_routine; 51 thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL); 52 53 if (!thread->handle) 54 return errno; 55 else 56 return 0; 57 } 58 59 int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr) 60 { 61 DWORD result; 62 63 if (!thread.handle) return 0; 64 65 result = WaitForSingleObject(thread.handle, INFINITE); 66 switch (result) { 67 case WAIT_OBJECT_0: 68 if (value_ptr) *value_ptr = thread.arg; 69 return 0; 70 case WAIT_ABANDONED: 71 return EINVAL; 72 default: 73 return GetLastError(); 74 } 75 } 76 77 #endif /* ZSTD_MULTITHREAD */ 78 79 #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32) 80 81 #include <stdlib.h> 82 83 int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) 84 { 85 *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); 86 if (!*mutex) 87 return 1; 88 return pthread_mutex_init(*mutex, attr); 89 } 90 91 int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) 92 { 93 if (!*mutex) 94 return 0; 95 { 96 int const ret = pthread_mutex_destroy(*mutex); 97 free(*mutex); 98 return ret; 99 } 100 } 101 102 int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) 103 { 104 *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t)); 105 if (!*cond) 106 return 1; 107 return pthread_cond_init(*cond, attr); 108 } 109 110 int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) 111 { 112 if (!*cond) 113 return 0; 114 { 115 int const ret = pthread_cond_destroy(*cond); 116 free(*cond); 117 return ret; 118 } 119 } 120 121 #endif 122