Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmzstd/lib/common/threading.c
5015 views
1
/**
2
* Copyright (c) 2016 Tino Reichardt
3
* All rights reserved.
4
*
5
* You can contact the author at:
6
* - zstdmt source repository: https://github.com/mcmilk/zstdmt
7
*
8
* This source code is licensed under both the BSD-style license (found in the
9
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
10
* in the COPYING file in the root directory of this source tree).
11
* You may select, at your option, one of the above-listed licenses.
12
*/
13
14
/**
15
* This file will hold wrapper for systems, which do not support pthreads
16
*/
17
18
#include "threading.h"
19
20
/* create fake symbol to avoid empty translation unit warning */
21
int g_ZSTD_threading_useless_symbol;
22
23
#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
24
25
/**
26
* Windows minimalist Pthread Wrapper
27
*/
28
29
30
/* === Dependencies === */
31
#include <process.h>
32
#include <errno.h>
33
34
35
/* === Implementation === */
36
37
typedef struct {
38
void* (*start_routine)(void*);
39
void* arg;
40
int initialized;
41
ZSTD_pthread_cond_t initialized_cond;
42
ZSTD_pthread_mutex_t initialized_mutex;
43
} ZSTD_thread_params_t;
44
45
static unsigned __stdcall worker(void *arg)
46
{
47
void* (*start_routine)(void*);
48
void* thread_arg;
49
50
/* Initialized thread_arg and start_routine and signal main thread that we don't need it
51
* to wait any longer.
52
*/
53
{
54
ZSTD_thread_params_t* thread_param = (ZSTD_thread_params_t*)arg;
55
thread_arg = thread_param->arg;
56
start_routine = thread_param->start_routine;
57
58
/* Signal main thread that we are running and do not depend on its memory anymore */
59
ZSTD_pthread_mutex_lock(&thread_param->initialized_mutex);
60
thread_param->initialized = 1;
61
ZSTD_pthread_cond_signal(&thread_param->initialized_cond);
62
ZSTD_pthread_mutex_unlock(&thread_param->initialized_mutex);
63
}
64
65
start_routine(thread_arg);
66
67
return 0;
68
}
69
70
int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
71
void* (*start_routine) (void*), void* arg)
72
{
73
ZSTD_thread_params_t thread_param;
74
(void)unused;
75
76
if (thread==NULL) return -1;
77
*thread = NULL;
78
79
thread_param.start_routine = start_routine;
80
thread_param.arg = arg;
81
thread_param.initialized = 0;
82
83
/* Setup thread initialization synchronization */
84
if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
85
/* Should never happen on Windows */
86
return -1;
87
}
88
if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) {
89
/* Should never happen on Windows */
90
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
91
return -1;
92
}
93
94
/* Spawn thread */
95
*thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
96
if (*thread==NULL) {
97
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
98
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
99
return errno;
100
}
101
102
/* Wait for thread to be initialized */
103
ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex);
104
while(!thread_param.initialized) {
105
ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex);
106
}
107
ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex);
108
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
109
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
110
111
return 0;
112
}
113
114
int ZSTD_pthread_join(ZSTD_pthread_t thread)
115
{
116
DWORD result;
117
118
if (!thread) return 0;
119
120
result = WaitForSingleObject(thread, INFINITE);
121
CloseHandle(thread);
122
123
switch (result) {
124
case WAIT_OBJECT_0:
125
return 0;
126
case WAIT_ABANDONED:
127
return EINVAL;
128
default:
129
return GetLastError();
130
}
131
}
132
133
#endif /* ZSTD_MULTITHREAD */
134
135
#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
136
137
#define ZSTD_DEPS_NEED_MALLOC
138
#include "zstd_deps.h"
139
140
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
141
{
142
assert(mutex != NULL);
143
*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
144
if (!*mutex)
145
return 1;
146
return pthread_mutex_init(*mutex, attr);
147
}
148
149
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
150
{
151
assert(mutex != NULL);
152
if (!*mutex)
153
return 0;
154
{
155
int const ret = pthread_mutex_destroy(*mutex);
156
ZSTD_free(*mutex);
157
return ret;
158
}
159
}
160
161
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
162
{
163
assert(cond != NULL);
164
*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
165
if (!*cond)
166
return 1;
167
return pthread_cond_init(*cond, attr);
168
}
169
170
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
171
{
172
assert(cond != NULL);
173
if (!*cond)
174
return 0;
175
{
176
int const ret = pthread_cond_destroy(*cond);
177
ZSTD_free(*cond);
178
return ret;
179
}
180
}
181
182
#endif
183
184