From 3b9d4343564233db19992950bbdb4a301d97f8f4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 31 Dec 2016 16:32:19 +0100 Subject: [PATCH] extended ZSTDMT code support for non-MT systems and WIN32 (preliminary) --- lib/common/pool.c | 7 +-- lib/common/threading.c | 73 +++++++++++++++++++++++++++++++ lib/common/threading.h | 79 ++++++++++++++++++++++++++++++++++ lib/compress/zstdmt_compress.c | 2 +- 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 lib/common/threading.c create mode 100644 lib/common/threading.h diff --git a/lib/common/pool.c b/lib/common/pool.c index 4ec1dfff..97ca7dda 100644 --- a/lib/common/pool.c +++ b/lib/common/pool.c @@ -13,7 +13,7 @@ #ifdef ZSTD_PTHREAD -#include +#include /* A job is a function and an opaque argument */ typedef struct POOL_job_s { @@ -161,7 +161,8 @@ void POOL_add(void *ctxVoid, POOL_function function, void *opaque) { pthread_cond_signal(&ctx->queuePopCond); } -#else +#else /* ZSTD_PTHREAD not defined */ +/* No multi-threading support */ /* We don't need any data, but if it is empty malloc() might return NULL. */ struct POOL_ctx_s { @@ -183,4 +184,4 @@ void POOL_add(void *ctx, POOL_function function, void *opaque) { function(opaque); } -#endif +#endif /* ZSTD_PTHREAD */ diff --git a/lib/common/threading.c b/lib/common/threading.c new file mode 100644 index 00000000..1725650c --- /dev/null +++ b/lib/common/threading.c @@ -0,0 +1,73 @@ + +/** + * Copyright (c) 2016 Tino Reichardt + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * You can contact the author at: + * - zstdmt source repository: https://github.com/mcmilk/zstdmt + */ + +/** + * This file will hold wrapper for systems, which do not support Pthreads + */ + +#ifdef _WIN32 + +/** + * Windows minimalist Pthread Wrapper, based on : + * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html + */ + + +/* === Dependencies === */ +#include +#include +#include "threading.h" + + +/* === Implementation === */ + +static unsigned __stdcall worker(void *arg) +{ + pthread_t* const thread = (pthread_t*) arg; + thread->arg = thread->start_routine(thread->arg); + return 0; +} + +int pthread_create(pthread_t* thread, const void* unused, + void* (*start_routine) (void*), void* arg) +{ + (void)unused; + thread->arg = arg; + thread->start_routine = start_routine; + thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL); + + if (!thread->handle) + return errno; + else + return 0; +} + +int _pthread_join(pthread_t * thread, void **value_ptr) +{ + DWORD result; + + if (!thread->handle) return 0; + + result = WaitForSingleObject(thread->handle, INFINITE); + switch (result) { + case WAIT_OBJECT_0: + if (value_ptr) *value_ptr = thread->arg; + return 0; + case WAIT_ABANDONED: + return EINVAL; + default: + return GetLastError(); + } +} + +#endif diff --git a/lib/common/threading.h b/lib/common/threading.h new file mode 100644 index 00000000..a8126eb7 --- /dev/null +++ b/lib/common/threading.h @@ -0,0 +1,79 @@ + +/** + * Copyright (c) 2016 Tino Reichardt + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * You can contact the author at: + * - zstdmt source repository: https://github.com/mcmilk/zstdmt + */ + +#ifndef THREADING_H_938743 +#define THREADING_H_938743 + +#if defined (__cplusplus) +extern "C" { +#endif + +#if defined(ZSTD_PTHREAD) && defined(_WIN32) + +/** + * Windows minimalist Pthread Wrapper, based on : + * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html + */ + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +/* mutex */ +#define pthread_mutex_t CRITICAL_SECTION +#define pthread_mutex_init(a,b) InitializeCriticalSection((a)) +#define pthread_mutex_destroy(a) DeleteCriticalSection((a)) +#define pthread_mutex_lock EnterCriticalSection +#define pthread_mutex_unlock LeaveCriticalSection + +/* pthread_create() and pthread_join() */ +typedef struct { + HANDLE handle; + void* (*start_routine)(void*); + void*varg; +} pthread_t; + +int pthread_create(pthread_t* thread, const void* unused, + void* (*start_routine) (void*), void* arg); + +#define pthread_join(a, b) _pthread_join(&(a), (b)) +int _pthread_join(pthread_t* thread, void** value_ptr); + +/** + * add here more wrappers as required + */ + + +#elif defined(ZSTD_PTHREAD) /* posix assumed ; need a better detection mathod */ +/* === POSIX Systems === */ +# include + +#else /* ZSTD_PTHREAD not defined */ +/* No multithreading support */ + +typedef int pthread_mutex_t; +#define pthread_mutex_init(a,b) +#define pthread_mutex_destroy(a) +#define pthread_mutex_lock(a) +#define pthread_mutex_unlock(a) + +/* do not use pthread_t */ + +#endif /* ZSTD_PTHREAD */ + +#if defined (__cplusplus) +} +#endif + +#endif /* THREADING_H_938743 */ diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 97de6e64..770f5975 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -1,6 +1,6 @@ #include /* malloc */ #include /* threadpool */ -#include /* mutex */ +#include "threading.h" /* mutex */ #include "zstd_internal.h" /* MIN, ERROR */ #include "zstdmt_compress.h"