Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmzstd/lib/common/threading.c
3158 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
thread_param.start_routine = start_routine;
77
thread_param.arg = arg;
78
thread_param.initialized = 0;
79
*thread = NULL;
80
81
/* Setup thread initialization synchronization */
82
if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
83
/* Should never happen on Windows */
84
return -1;
85
}
86
if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) {
87
/* Should never happen on Windows */
88
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
89
return -1;
90
}
91
92
/* Spawn thread */
93
*thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
94
if (!thread) {
95
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
96
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
97
return errno;
98
}
99
100
/* Wait for thread to be initialized */
101
ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex);
102
while(!thread_param.initialized) {
103
ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex);
104
}
105
ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex);
106
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
107
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
108
109
return 0;
110
}
111
112
int ZSTD_pthread_join(ZSTD_pthread_t thread)
113
{
114
DWORD result;
115
116
if (!thread) return 0;
117
118
result = WaitForSingleObject(thread, INFINITE);
119
CloseHandle(thread);
120
121
switch (result) {
122
case WAIT_OBJECT_0:
123
return 0;
124
case WAIT_ABANDONED:
125
return EINVAL;
126
default:
127
return GetLastError();
128
}
129
}
130
131
#endif /* ZSTD_MULTITHREAD */
132
133
#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
134
135
#define ZSTD_DEPS_NEED_MALLOC
136
#include "zstd_deps.h"
137
138
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
139
{
140
*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
141
if (!*mutex)
142
return 1;
143
return pthread_mutex_init(*mutex, attr);
144
}
145
146
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
147
{
148
if (!*mutex)
149
return 0;
150
{
151
int const ret = pthread_mutex_destroy(*mutex);
152
ZSTD_free(*mutex);
153
return ret;
154
}
155
}
156
157
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
158
{
159
*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
160
if (!*cond)
161
return 1;
162
return pthread_cond_init(*cond, attr);
163
}
164
165
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
166
{
167
if (!*cond)
168
return 0;
169
{
170
int const ret = pthread_cond_destroy(*cond);
171
ZSTD_free(*cond);
172
return ret;
173
}
174
}
175
176
#endif
177
178