1*a28cd43dSSascha Wildner /** 2*a28cd43dSSascha Wildner * Copyright (c) 2016 Tino Reichardt 3*a28cd43dSSascha Wildner * All rights reserved. 4*a28cd43dSSascha Wildner * 5*a28cd43dSSascha Wildner * You can contact the author at: 6*a28cd43dSSascha Wildner * - zstdmt source repository: https://github.com/mcmilk/zstdmt 7*a28cd43dSSascha Wildner * 8*a28cd43dSSascha Wildner * This source code is licensed under both the BSD-style license (found in the 9*a28cd43dSSascha Wildner * LICENSE file in the root directory of this source tree) and the GPLv2 (found 10*a28cd43dSSascha Wildner * in the COPYING file in the root directory of this source tree). 11*a28cd43dSSascha Wildner * You may select, at your option, one of the above-listed licenses. 12*a28cd43dSSascha Wildner */ 13*a28cd43dSSascha Wildner 14*a28cd43dSSascha Wildner #ifndef THREADING_H_938743 15*a28cd43dSSascha Wildner #define THREADING_H_938743 16*a28cd43dSSascha Wildner 17*a28cd43dSSascha Wildner #include "debug.h" 18*a28cd43dSSascha Wildner 19*a28cd43dSSascha Wildner #if defined (__cplusplus) 20*a28cd43dSSascha Wildner extern "C" { 21*a28cd43dSSascha Wildner #endif 22*a28cd43dSSascha Wildner 23*a28cd43dSSascha Wildner #if defined(ZSTD_MULTITHREAD) && defined(_WIN32) 24*a28cd43dSSascha Wildner 25*a28cd43dSSascha Wildner /** 26*a28cd43dSSascha Wildner * Windows minimalist Pthread Wrapper, based on : 27*a28cd43dSSascha Wildner * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html 28*a28cd43dSSascha Wildner */ 29*a28cd43dSSascha Wildner #ifdef WINVER 30*a28cd43dSSascha Wildner # undef WINVER 31*a28cd43dSSascha Wildner #endif 32*a28cd43dSSascha Wildner #define WINVER 0x0600 33*a28cd43dSSascha Wildner 34*a28cd43dSSascha Wildner #ifdef _WIN32_WINNT 35*a28cd43dSSascha Wildner # undef _WIN32_WINNT 36*a28cd43dSSascha Wildner #endif 37*a28cd43dSSascha Wildner #define _WIN32_WINNT 0x0600 38*a28cd43dSSascha Wildner 39*a28cd43dSSascha Wildner #ifndef WIN32_LEAN_AND_MEAN 40*a28cd43dSSascha Wildner # define WIN32_LEAN_AND_MEAN 41*a28cd43dSSascha Wildner #endif 42*a28cd43dSSascha Wildner 43*a28cd43dSSascha Wildner #undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ 44*a28cd43dSSascha Wildner #include <windows.h> 45*a28cd43dSSascha Wildner #undef ERROR 46*a28cd43dSSascha Wildner #define ERROR(name) ZSTD_ERROR(name) 47*a28cd43dSSascha Wildner 48*a28cd43dSSascha Wildner 49*a28cd43dSSascha Wildner /* mutex */ 50*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_t CRITICAL_SECTION 51*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_init(a, b) ((void)(b), InitializeCriticalSection((a)), 0) 52*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_destroy(a) DeleteCriticalSection((a)) 53*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_lock(a) EnterCriticalSection((a)) 54*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_unlock(a) LeaveCriticalSection((a)) 55*a28cd43dSSascha Wildner 56*a28cd43dSSascha Wildner /* condition variable */ 57*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_t CONDITION_VARIABLE 58*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_init(a, b) ((void)(b), InitializeConditionVariable((a)), 0) 59*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_destroy(a) ((void)(a)) 60*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE) 61*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_signal(a) WakeConditionVariable((a)) 62*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a)) 63*a28cd43dSSascha Wildner 64*a28cd43dSSascha Wildner /* ZSTD_pthread_create() and ZSTD_pthread_join() */ 65*a28cd43dSSascha Wildner typedef struct { 66*a28cd43dSSascha Wildner HANDLE handle; 67*a28cd43dSSascha Wildner void* (*start_routine)(void*); 68*a28cd43dSSascha Wildner void* arg; 69*a28cd43dSSascha Wildner } ZSTD_pthread_t; 70*a28cd43dSSascha Wildner 71*a28cd43dSSascha Wildner int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, 72*a28cd43dSSascha Wildner void* (*start_routine) (void*), void* arg); 73*a28cd43dSSascha Wildner 74*a28cd43dSSascha Wildner int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr); 75*a28cd43dSSascha Wildner 76*a28cd43dSSascha Wildner /** 77*a28cd43dSSascha Wildner * add here more wrappers as required 78*a28cd43dSSascha Wildner */ 79*a28cd43dSSascha Wildner 80*a28cd43dSSascha Wildner 81*a28cd43dSSascha Wildner #elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */ 82*a28cd43dSSascha Wildner /* === POSIX Systems === */ 83*a28cd43dSSascha Wildner # include <pthread.h> 84*a28cd43dSSascha Wildner 85*a28cd43dSSascha Wildner #if DEBUGLEVEL < 1 86*a28cd43dSSascha Wildner 87*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_t pthread_mutex_t 88*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b)) 89*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a)) 90*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock((a)) 91*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock((a)) 92*a28cd43dSSascha Wildner 93*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_t pthread_cond_t 94*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_init(a, b) pthread_cond_init((a), (b)) 95*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_destroy(a) pthread_cond_destroy((a)) 96*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait((a), (b)) 97*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_signal(a) pthread_cond_signal((a)) 98*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast((a)) 99*a28cd43dSSascha Wildner 100*a28cd43dSSascha Wildner #define ZSTD_pthread_t pthread_t 101*a28cd43dSSascha Wildner #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) 102*a28cd43dSSascha Wildner #define ZSTD_pthread_join(a, b) pthread_join((a),(b)) 103*a28cd43dSSascha Wildner 104*a28cd43dSSascha Wildner #else /* DEBUGLEVEL >= 1 */ 105*a28cd43dSSascha Wildner 106*a28cd43dSSascha Wildner /* Debug implementation of threading. 107*a28cd43dSSascha Wildner * In this implementation we use pointers for mutexes and condition variables. 108*a28cd43dSSascha Wildner * This way, if we forget to init/destroy them the program will crash or ASAN 109*a28cd43dSSascha Wildner * will report leaks. 110*a28cd43dSSascha Wildner */ 111*a28cd43dSSascha Wildner 112*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_t pthread_mutex_t* 113*a28cd43dSSascha Wildner int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr); 114*a28cd43dSSascha Wildner int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex); 115*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock(*(a)) 116*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock(*(a)) 117*a28cd43dSSascha Wildner 118*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_t pthread_cond_t* 119*a28cd43dSSascha Wildner int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr); 120*a28cd43dSSascha Wildner int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond); 121*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait(*(a), *(b)) 122*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_signal(a) pthread_cond_signal(*(a)) 123*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast(*(a)) 124*a28cd43dSSascha Wildner 125*a28cd43dSSascha Wildner #define ZSTD_pthread_t pthread_t 126*a28cd43dSSascha Wildner #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) 127*a28cd43dSSascha Wildner #define ZSTD_pthread_join(a, b) pthread_join((a),(b)) 128*a28cd43dSSascha Wildner 129*a28cd43dSSascha Wildner #endif 130*a28cd43dSSascha Wildner 131*a28cd43dSSascha Wildner #else /* ZSTD_MULTITHREAD not defined */ 132*a28cd43dSSascha Wildner /* No multithreading support */ 133*a28cd43dSSascha Wildner 134*a28cd43dSSascha Wildner typedef int ZSTD_pthread_mutex_t; 135*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_init(a, b) ((void)(a), (void)(b), 0) 136*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_destroy(a) ((void)(a)) 137*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_lock(a) ((void)(a)) 138*a28cd43dSSascha Wildner #define ZSTD_pthread_mutex_unlock(a) ((void)(a)) 139*a28cd43dSSascha Wildner 140*a28cd43dSSascha Wildner typedef int ZSTD_pthread_cond_t; 141*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_init(a, b) ((void)(a), (void)(b), 0) 142*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_destroy(a) ((void)(a)) 143*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_wait(a, b) ((void)(a), (void)(b)) 144*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_signal(a) ((void)(a)) 145*a28cd43dSSascha Wildner #define ZSTD_pthread_cond_broadcast(a) ((void)(a)) 146*a28cd43dSSascha Wildner 147*a28cd43dSSascha Wildner /* do not use ZSTD_pthread_t */ 148*a28cd43dSSascha Wildner 149*a28cd43dSSascha Wildner #endif /* ZSTD_MULTITHREAD */ 150*a28cd43dSSascha Wildner 151*a28cd43dSSascha Wildner #if defined (__cplusplus) 152*a28cd43dSSascha Wildner } 153*a28cd43dSSascha Wildner #endif 154*a28cd43dSSascha Wildner 155*a28cd43dSSascha Wildner #endif /* THREADING_H_938743 */ 156