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