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