1*22ce4affSfengbojiang /**
2*22ce4affSfengbojiang * Copyright (c) 2016 Tino Reichardt
3*22ce4affSfengbojiang * All rights reserved.
4*22ce4affSfengbojiang *
5*22ce4affSfengbojiang * You can contact the author at:
6*22ce4affSfengbojiang * - zstdmt source repository: https://github.com/mcmilk/zstdmt
7*22ce4affSfengbojiang *
8*22ce4affSfengbojiang * This source code is licensed under both the BSD-style license (found in the
9*22ce4affSfengbojiang * LICENSE file in the root directory of this source tree) and the GPLv2 (found
10*22ce4affSfengbojiang * in the COPYING file in the root directory of this source tree).
11*22ce4affSfengbojiang * You may select, at your option, one of the above-listed licenses.
12*22ce4affSfengbojiang */
13*22ce4affSfengbojiang
14*22ce4affSfengbojiang /**
15*22ce4affSfengbojiang * This file will hold wrapper for systems, which do not support pthreads
16*22ce4affSfengbojiang */
17*22ce4affSfengbojiang
18*22ce4affSfengbojiang #include "threading.h"
19*22ce4affSfengbojiang
20*22ce4affSfengbojiang /* create fake symbol to avoid empty translation unit warning */
21*22ce4affSfengbojiang int g_ZSTD_threading_useless_symbol;
22*22ce4affSfengbojiang
23*22ce4affSfengbojiang #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
24*22ce4affSfengbojiang
25*22ce4affSfengbojiang /**
26*22ce4affSfengbojiang * Windows minimalist Pthread Wrapper, based on :
27*22ce4affSfengbojiang * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
28*22ce4affSfengbojiang */
29*22ce4affSfengbojiang
30*22ce4affSfengbojiang
31*22ce4affSfengbojiang /* === Dependencies === */
32*22ce4affSfengbojiang #include <process.h>
33*22ce4affSfengbojiang #include <errno.h>
34*22ce4affSfengbojiang
35*22ce4affSfengbojiang
36*22ce4affSfengbojiang /* === Implementation === */
37*22ce4affSfengbojiang
worker(void * arg)38*22ce4affSfengbojiang static unsigned __stdcall worker(void *arg)
39*22ce4affSfengbojiang {
40*22ce4affSfengbojiang ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
41*22ce4affSfengbojiang thread->arg = thread->start_routine(thread->arg);
42*22ce4affSfengbojiang return 0;
43*22ce4affSfengbojiang }
44*22ce4affSfengbojiang
ZSTD_pthread_create(ZSTD_pthread_t * thread,const void * unused,void * (* start_routine)(void *),void * arg)45*22ce4affSfengbojiang int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
46*22ce4affSfengbojiang void* (*start_routine) (void*), void* arg)
47*22ce4affSfengbojiang {
48*22ce4affSfengbojiang (void)unused;
49*22ce4affSfengbojiang thread->arg = arg;
50*22ce4affSfengbojiang thread->start_routine = start_routine;
51*22ce4affSfengbojiang thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
52*22ce4affSfengbojiang
53*22ce4affSfengbojiang if (!thread->handle)
54*22ce4affSfengbojiang return errno;
55*22ce4affSfengbojiang else
56*22ce4affSfengbojiang return 0;
57*22ce4affSfengbojiang }
58*22ce4affSfengbojiang
ZSTD_pthread_join(ZSTD_pthread_t thread,void ** value_ptr)59*22ce4affSfengbojiang int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
60*22ce4affSfengbojiang {
61*22ce4affSfengbojiang DWORD result;
62*22ce4affSfengbojiang
63*22ce4affSfengbojiang if (!thread.handle) return 0;
64*22ce4affSfengbojiang
65*22ce4affSfengbojiang result = WaitForSingleObject(thread.handle, INFINITE);
66*22ce4affSfengbojiang switch (result) {
67*22ce4affSfengbojiang case WAIT_OBJECT_0:
68*22ce4affSfengbojiang if (value_ptr) *value_ptr = thread.arg;
69*22ce4affSfengbojiang return 0;
70*22ce4affSfengbojiang case WAIT_ABANDONED:
71*22ce4affSfengbojiang return EINVAL;
72*22ce4affSfengbojiang default:
73*22ce4affSfengbojiang return GetLastError();
74*22ce4affSfengbojiang }
75*22ce4affSfengbojiang }
76*22ce4affSfengbojiang
77*22ce4affSfengbojiang #endif /* ZSTD_MULTITHREAD */
78*22ce4affSfengbojiang
79*22ce4affSfengbojiang #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
80*22ce4affSfengbojiang
81*22ce4affSfengbojiang #define ZSTD_DEPS_NEED_MALLOC
82*22ce4affSfengbojiang #include "zstd_deps.h"
83*22ce4affSfengbojiang
ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t * mutex,pthread_mutexattr_t const * attr)84*22ce4affSfengbojiang int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
85*22ce4affSfengbojiang {
86*22ce4affSfengbojiang *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
87*22ce4affSfengbojiang if (!*mutex)
88*22ce4affSfengbojiang return 1;
89*22ce4affSfengbojiang return pthread_mutex_init(*mutex, attr);
90*22ce4affSfengbojiang }
91*22ce4affSfengbojiang
ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t * mutex)92*22ce4affSfengbojiang int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
93*22ce4affSfengbojiang {
94*22ce4affSfengbojiang if (!*mutex)
95*22ce4affSfengbojiang return 0;
96*22ce4affSfengbojiang {
97*22ce4affSfengbojiang int const ret = pthread_mutex_destroy(*mutex);
98*22ce4affSfengbojiang ZSTD_free(*mutex);
99*22ce4affSfengbojiang return ret;
100*22ce4affSfengbojiang }
101*22ce4affSfengbojiang }
102*22ce4affSfengbojiang
ZSTD_pthread_cond_init(ZSTD_pthread_cond_t * cond,pthread_condattr_t const * attr)103*22ce4affSfengbojiang int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
104*22ce4affSfengbojiang {
105*22ce4affSfengbojiang *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
106*22ce4affSfengbojiang if (!*cond)
107*22ce4affSfengbojiang return 1;
108*22ce4affSfengbojiang return pthread_cond_init(*cond, attr);
109*22ce4affSfengbojiang }
110*22ce4affSfengbojiang
ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t * cond)111*22ce4affSfengbojiang int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
112*22ce4affSfengbojiang {
113*22ce4affSfengbojiang if (!*cond)
114*22ce4affSfengbojiang return 0;
115*22ce4affSfengbojiang {
116*22ce4affSfengbojiang int const ret = pthread_cond_destroy(*cond);
117*22ce4affSfengbojiang ZSTD_free(*cond);
118*22ce4affSfengbojiang return ret;
119*22ce4affSfengbojiang }
120*22ce4affSfengbojiang }
121*22ce4affSfengbojiang
122*22ce4affSfengbojiang #endif
123