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 */ 21int 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 38static 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 45int 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 59int 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 84int 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 92int 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 103int 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 111int 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