10c16b537SWarner Losh /**
20c16b537SWarner Losh * Copyright (c) 2016 Tino Reichardt
30c16b537SWarner Losh * All rights reserved.
40c16b537SWarner Losh *
537f1f268SConrad Meyer * You can contact the author at:
637f1f268SConrad Meyer * - zstdmt source repository: https://github.com/mcmilk/zstdmt
737f1f268SConrad Meyer *
80c16b537SWarner Losh * This source code is licensed under both the BSD-style license (found in the
90c16b537SWarner Losh * LICENSE file in the root directory of this source tree) and the GPLv2 (found
100c16b537SWarner Losh * in the COPYING file in the root directory of this source tree).
1137f1f268SConrad Meyer * You may select, at your option, one of the above-listed licenses.
120c16b537SWarner Losh */
130c16b537SWarner Losh
140c16b537SWarner Losh /**
150c16b537SWarner Losh * This file will hold wrapper for systems, which do not support pthreads
160c16b537SWarner Losh */
170c16b537SWarner Losh
189cbefe25SConrad Meyer #include "threading.h"
199cbefe25SConrad Meyer
202b9c00cbSConrad Meyer /* create fake symbol to avoid empty translation unit warning */
212b9c00cbSConrad Meyer int g_ZSTD_threading_useless_symbol;
220c16b537SWarner Losh
230c16b537SWarner Losh #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
240c16b537SWarner Losh
250c16b537SWarner Losh /**
260c16b537SWarner Losh * Windows minimalist Pthread Wrapper, based on :
270c16b537SWarner Losh * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
280c16b537SWarner Losh */
290c16b537SWarner Losh
300c16b537SWarner Losh
310c16b537SWarner Losh /* === Dependencies === */
320c16b537SWarner Losh #include <process.h>
330c16b537SWarner Losh #include <errno.h>
340c16b537SWarner Losh
350c16b537SWarner Losh
360c16b537SWarner Losh /* === Implementation === */
370c16b537SWarner Losh
worker(void * arg)380c16b537SWarner Losh static unsigned __stdcall worker(void *arg)
390c16b537SWarner Losh {
400c16b537SWarner Losh ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
410c16b537SWarner Losh thread->arg = thread->start_routine(thread->arg);
420c16b537SWarner Losh return 0;
430c16b537SWarner Losh }
440c16b537SWarner Losh
ZSTD_pthread_create(ZSTD_pthread_t * thread,const void * unused,void * (* start_routine)(void *),void * arg)450c16b537SWarner Losh int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
460c16b537SWarner Losh void* (*start_routine) (void*), void* arg)
470c16b537SWarner Losh {
480c16b537SWarner Losh (void)unused;
490c16b537SWarner Losh thread->arg = arg;
500c16b537SWarner Losh thread->start_routine = start_routine;
510c16b537SWarner Losh thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
520c16b537SWarner Losh
530c16b537SWarner Losh if (!thread->handle)
540c16b537SWarner Losh return errno;
550c16b537SWarner Losh else
560c16b537SWarner Losh return 0;
570c16b537SWarner Losh }
580c16b537SWarner Losh
ZSTD_pthread_join(ZSTD_pthread_t thread,void ** value_ptr)590c16b537SWarner Losh int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
600c16b537SWarner Losh {
610c16b537SWarner Losh DWORD result;
620c16b537SWarner Losh
630c16b537SWarner Losh if (!thread.handle) return 0;
640c16b537SWarner Losh
650c16b537SWarner Losh result = WaitForSingleObject(thread.handle, INFINITE);
660c16b537SWarner Losh switch (result) {
670c16b537SWarner Losh case WAIT_OBJECT_0:
680c16b537SWarner Losh if (value_ptr) *value_ptr = thread.arg;
690c16b537SWarner Losh return 0;
700c16b537SWarner Losh case WAIT_ABANDONED:
710c16b537SWarner Losh return EINVAL;
720c16b537SWarner Losh default:
730c16b537SWarner Losh return GetLastError();
740c16b537SWarner Losh }
750c16b537SWarner Losh }
760c16b537SWarner Losh
770c16b537SWarner Losh #endif /* ZSTD_MULTITHREAD */
789cbefe25SConrad Meyer
799cbefe25SConrad Meyer #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
809cbefe25SConrad Meyer
81*f7cd7fe5SConrad Meyer #define ZSTD_DEPS_NEED_MALLOC
82*f7cd7fe5SConrad Meyer #include "zstd_deps.h"
839cbefe25SConrad Meyer
ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t * mutex,pthread_mutexattr_t const * attr)849cbefe25SConrad Meyer int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
859cbefe25SConrad Meyer {
86*f7cd7fe5SConrad Meyer *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
879cbefe25SConrad Meyer if (!*mutex)
889cbefe25SConrad Meyer return 1;
899cbefe25SConrad Meyer return pthread_mutex_init(*mutex, attr);
909cbefe25SConrad Meyer }
919cbefe25SConrad Meyer
ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t * mutex)929cbefe25SConrad Meyer int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
939cbefe25SConrad Meyer {
949cbefe25SConrad Meyer if (!*mutex)
959cbefe25SConrad Meyer return 0;
969cbefe25SConrad Meyer {
979cbefe25SConrad Meyer int const ret = pthread_mutex_destroy(*mutex);
98*f7cd7fe5SConrad Meyer ZSTD_free(*mutex);
999cbefe25SConrad Meyer return ret;
1009cbefe25SConrad Meyer }
1019cbefe25SConrad Meyer }
1029cbefe25SConrad Meyer
ZSTD_pthread_cond_init(ZSTD_pthread_cond_t * cond,pthread_condattr_t const * attr)1039cbefe25SConrad Meyer int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
1049cbefe25SConrad Meyer {
105*f7cd7fe5SConrad Meyer *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
1069cbefe25SConrad Meyer if (!*cond)
1079cbefe25SConrad Meyer return 1;
1089cbefe25SConrad Meyer return pthread_cond_init(*cond, attr);
1099cbefe25SConrad Meyer }
1109cbefe25SConrad Meyer
ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t * cond)1119cbefe25SConrad Meyer int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
1129cbefe25SConrad Meyer {
1139cbefe25SConrad Meyer if (!*cond)
1149cbefe25SConrad Meyer return 0;
1159cbefe25SConrad Meyer {
1169cbefe25SConrad Meyer int const ret = pthread_cond_destroy(*cond);
117*f7cd7fe5SConrad Meyer ZSTD_free(*cond);
1189cbefe25SConrad Meyer return ret;
1199cbefe25SConrad Meyer }
1209cbefe25SConrad Meyer }
1219cbefe25SConrad Meyer
1229cbefe25SConrad Meyer #endif
123