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 #define ZSTD_DEPS_NEED_MALLOC 82 #include "zstd_deps.h" 83 84 int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) 85 { 86 *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t)); 87 if (!*mutex) 88 return 1; 89 return pthread_mutex_init(*mutex, attr); 90 } 91 92 int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) 93 { 94 if (!*mutex) 95 return 0; 96 { 97 int const ret = pthread_mutex_destroy(*mutex); 98 ZSTD_free(*mutex); 99 return ret; 100 } 101 } 102 103 int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) 104 { 105 *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t)); 106 if (!*cond) 107 return 1; 108 return pthread_cond_init(*cond, attr); 109 } 110 111 int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) 112 { 113 if (!*cond) 114 return 0; 115 { 116 int const ret = pthread_cond_destroy(*cond); 117 ZSTD_free(*cond); 118 return ret; 119 } 120 } 121 122 #endif 123