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