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