Coverage Report

Created: 2026-01-17 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xz/src/common/mythread.h
Line
Count
Source
1
// SPDX-License-Identifier: 0BSD
2
3
///////////////////////////////////////////////////////////////////////////////
4
//
5
/// \file       mythread.h
6
/// \brief      Some threading related helper macros and functions
7
//
8
//  Author:     Lasse Collin
9
//
10
///////////////////////////////////////////////////////////////////////////////
11
12
#ifndef MYTHREAD_H
13
#define MYTHREAD_H
14
15
#include "sysdefs.h"
16
17
// If any type of threading is enabled, #define MYTHREAD_ENABLED.
18
#if defined(MYTHREAD_POSIX) || defined(MYTHREAD_WIN95) \
19
    || defined(MYTHREAD_VISTA)
20
# define MYTHREAD_ENABLED 1
21
#endif
22
23
24
#ifdef MYTHREAD_ENABLED
25
26
////////////////////////////////////////
27
// Shared between all threading types //
28
////////////////////////////////////////
29
30
// Locks a mutex for a duration of a block.
31
//
32
// Perform mythread_mutex_lock(&mutex) in the beginning of a block
33
// and mythread_mutex_unlock(&mutex) at the end of the block. "break"
34
// may be used to unlock the mutex and jump out of the block.
35
// mythread_sync blocks may be nested.
36
//
37
// Example:
38
//
39
//     mythread_sync(mutex) {
40
//         foo();
41
//         if (some_error)
42
//             break; // Skips bar()
43
//         bar();
44
//     }
45
//
46
// At least GCC optimizes the loops completely away so it doesn't slow
47
// things down at all compared to plain mythread_mutex_lock(&mutex)
48
// and mythread_mutex_unlock(&mutex) calls.
49
//
50
#define mythread_sync(mutex) mythread_sync_helper1(mutex, __LINE__)
51
#define mythread_sync_helper1(mutex, line) mythread_sync_helper2(mutex, line)
52
#define mythread_sync_helper2(mutex, line) \
53
  for (unsigned int mythread_i_ ## line = 0; \
54
      mythread_i_ ## line \
55
        ? (mythread_mutex_unlock(&(mutex)), 0) \
56
        : (mythread_mutex_lock(&(mutex)), 1); \
57
      mythread_i_ ## line = 1) \
58
    for (unsigned int mythread_j_ ## line = 0; \
59
        !mythread_j_ ## line; \
60
        mythread_j_ ## line = 1)
61
#endif
62
63
64
#if !defined(MYTHREAD_ENABLED)
65
66
//////////////////
67
// No threading //
68
//////////////////
69
70
// Calls the given function once. This isn't thread safe.
71
#define mythread_once(func) \
72
do { \
73
  static bool once_ = false; \
74
  if (!once_) { \
75
    func(); \
76
    once_ = true; \
77
  } \
78
} while (0)
79
80
81
#if !(defined(_WIN32) && !defined(__CYGWIN__)) \
82
    && (!defined(__wasm__) || defined(__EMSCRIPTEN__))
83
// Use sigprocmask() to set the signal mask in single-threaded programs.
84
#include <signal.h>
85
86
static inline void
87
mythread_sigmask(int how, const sigset_t *restrict set,
88
    sigset_t *restrict oset)
89
{
90
  int ret = sigprocmask(how, set, oset);
91
  assert(ret == 0);
92
  (void)ret;
93
}
94
#endif
95
96
97
#elif defined(MYTHREAD_POSIX)
98
99
////////////////////
100
// Using pthreads //
101
////////////////////
102
103
#include <pthread.h>
104
#include <signal.h>
105
#include <time.h>
106
#include <errno.h>
107
108
// If clock_gettime() isn't available, use gettimeofday() from <sys/time.h>
109
// as a fallback. gettimeofday() is in SUSv2 and thus is supported on all
110
// relevant POSIX systems.
111
#ifndef HAVE_CLOCK_GETTIME
112
# include <sys/time.h>
113
#endif
114
115
// MinGW-w64 with winpthreads:
116
//
117
// NOTE: Typical builds with MinGW-w64 don't use this code (MYTHREAD_POSIX).
118
// Instead, native Windows threading APIs are used (MYTHREAD_VISTA or
119
// MYTHREAD_WIN95).
120
//
121
// MinGW-w64 has _sigset_t (an integer type) in <sys/types.h>.
122
// If _POSIX was #defined, the header would add the alias sigset_t too.
123
// Let's keep this working even without _POSIX.
124
//
125
// There are no functions that actually do something with sigset_t
126
// because signals barely exist on Windows. The sigfillset macro below
127
// is just to silence warnings. There is no sigfillset() in MinGW-w64.
128
#ifdef __MINGW32__
129
# include <sys/types.h>
130
# define sigset_t _sigset_t
131
# define sigfillset(set_ptr) do { *(set_ptr) = 0; } while (0)
132
#endif
133
134
#define MYTHREAD_RET_TYPE void *
135
#define MYTHREAD_RET_VALUE NULL
136
137
typedef pthread_t mythread;
138
typedef pthread_mutex_t mythread_mutex;
139
140
typedef struct {
141
  pthread_cond_t cond;
142
#ifdef HAVE_CLOCK_GETTIME
143
  // Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with
144
  // the condition variable.
145
  clockid_t clk_id;
146
#endif
147
} mythread_cond;
148
149
typedef struct timespec mythread_condtime;
150
151
152
// Calls the given function once in a thread-safe way.
153
#define mythread_once(func) \
154
  do { \
155
    static pthread_once_t once_ = PTHREAD_ONCE_INIT; \
156
    pthread_once(&once_, &func); \
157
  } while (0)
158
159
160
// Use pthread_sigmask() to set the signal mask in multi-threaded programs.
161
// Do nothing on OpenVMS since it lacks pthread_sigmask().
162
// Do nothing on MinGW-w64 too to silence warnings (its pthread_sigmask()
163
// is #defined to 0 so it's a no-op).
164
static inline void
165
mythread_sigmask(int how, const sigset_t *restrict set,
166
    sigset_t *restrict oset)
167
0
{
168
0
#if defined(__VMS) || defined(__MINGW32__)
169
0
  (void)how;
170
0
  (void)set;
171
0
  (void)oset;
172
0
#else
173
0
  int ret = pthread_sigmask(how, set, oset);
174
0
  assert(ret == 0);
175
0
  (void)ret;
176
0
#endif
177
0
}
Unexecuted instantiation: common.c:mythread_sigmask
Unexecuted instantiation: stream_encoder.c:mythread_sigmask
Unexecuted instantiation: stream_flags_encoder.c:mythread_sigmask
Unexecuted instantiation: crc32_fast.c:mythread_sigmask
Unexecuted instantiation: lzma_encoder_presets.c:mythread_sigmask
Unexecuted instantiation: block_util.c:mythread_sigmask
Unexecuted instantiation: filter_common.c:mythread_sigmask
Unexecuted instantiation: index.c:mythread_sigmask
Unexecuted instantiation: stream_flags_common.c:mythread_sigmask
Unexecuted instantiation: vli_size.c:mythread_sigmask
Unexecuted instantiation: block_encoder.c:mythread_sigmask
Unexecuted instantiation: block_header_encoder.c:mythread_sigmask
Unexecuted instantiation: filter_encoder.c:mythread_sigmask
Unexecuted instantiation: filter_flags_encoder.c:mythread_sigmask
Unexecuted instantiation: index_encoder.c:mythread_sigmask
Unexecuted instantiation: vli_encoder.c:mythread_sigmask
Unexecuted instantiation: check.c:mythread_sigmask
Unexecuted instantiation: crc64_fast.c:mythread_sigmask
Unexecuted instantiation: sha256.c:mythread_sigmask
Unexecuted instantiation: lzma_encoder.c:mythread_sigmask
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_sigmask
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_sigmask
Unexecuted instantiation: fastpos_table.c:mythread_sigmask
Unexecuted instantiation: lzma2_encoder.c:mythread_sigmask
Unexecuted instantiation: price_table.c:mythread_sigmask
Unexecuted instantiation: delta_common.c:mythread_sigmask
Unexecuted instantiation: delta_encoder.c:mythread_sigmask
Unexecuted instantiation: simple_encoder.c:mythread_sigmask
Unexecuted instantiation: x86.c:mythread_sigmask
Unexecuted instantiation: powerpc.c:mythread_sigmask
Unexecuted instantiation: ia64.c:mythread_sigmask
Unexecuted instantiation: arm.c:mythread_sigmask
Unexecuted instantiation: armthumb.c:mythread_sigmask
Unexecuted instantiation: arm64.c:mythread_sigmask
Unexecuted instantiation: sparc.c:mythread_sigmask
Unexecuted instantiation: riscv.c:mythread_sigmask
Unexecuted instantiation: lz_encoder.c:mythread_sigmask
Unexecuted instantiation: lz_encoder_mf.c:mythread_sigmask
Unexecuted instantiation: simple_coder.c:mythread_sigmask
178
179
180
// Creates a new thread with all signals blocked. Returns zero on success
181
// and non-zero on error.
182
static inline int
183
mythread_create(mythread *thread, void *(*func)(void *arg), void *arg)
184
0
{
185
0
  sigset_t old;
186
0
  sigset_t all;
187
0
  sigfillset(&all);
188
0
189
0
  mythread_sigmask(SIG_SETMASK, &all, &old);
190
0
  const int ret = pthread_create(thread, NULL, func, arg);
191
0
  mythread_sigmask(SIG_SETMASK, &old, NULL);
192
0
193
0
  return ret;
194
0
}
Unexecuted instantiation: common.c:mythread_create
Unexecuted instantiation: stream_encoder.c:mythread_create
Unexecuted instantiation: stream_flags_encoder.c:mythread_create
Unexecuted instantiation: crc32_fast.c:mythread_create
Unexecuted instantiation: lzma_encoder_presets.c:mythread_create
Unexecuted instantiation: block_util.c:mythread_create
Unexecuted instantiation: filter_common.c:mythread_create
Unexecuted instantiation: index.c:mythread_create
Unexecuted instantiation: stream_flags_common.c:mythread_create
Unexecuted instantiation: vli_size.c:mythread_create
Unexecuted instantiation: block_encoder.c:mythread_create
Unexecuted instantiation: block_header_encoder.c:mythread_create
Unexecuted instantiation: filter_encoder.c:mythread_create
Unexecuted instantiation: filter_flags_encoder.c:mythread_create
Unexecuted instantiation: index_encoder.c:mythread_create
Unexecuted instantiation: vli_encoder.c:mythread_create
Unexecuted instantiation: check.c:mythread_create
Unexecuted instantiation: crc64_fast.c:mythread_create
Unexecuted instantiation: sha256.c:mythread_create
Unexecuted instantiation: lzma_encoder.c:mythread_create
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_create
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_create
Unexecuted instantiation: fastpos_table.c:mythread_create
Unexecuted instantiation: lzma2_encoder.c:mythread_create
Unexecuted instantiation: price_table.c:mythread_create
Unexecuted instantiation: delta_common.c:mythread_create
Unexecuted instantiation: delta_encoder.c:mythread_create
Unexecuted instantiation: simple_encoder.c:mythread_create
Unexecuted instantiation: x86.c:mythread_create
Unexecuted instantiation: powerpc.c:mythread_create
Unexecuted instantiation: ia64.c:mythread_create
Unexecuted instantiation: arm.c:mythread_create
Unexecuted instantiation: armthumb.c:mythread_create
Unexecuted instantiation: arm64.c:mythread_create
Unexecuted instantiation: sparc.c:mythread_create
Unexecuted instantiation: riscv.c:mythread_create
Unexecuted instantiation: lz_encoder.c:mythread_create
Unexecuted instantiation: lz_encoder_mf.c:mythread_create
Unexecuted instantiation: simple_coder.c:mythread_create
195
196
// Joins a thread. Returns zero on success and non-zero on error.
197
static inline int
198
mythread_join(mythread thread)
199
0
{
200
0
  return pthread_join(thread, NULL);
201
0
}
Unexecuted instantiation: common.c:mythread_join
Unexecuted instantiation: stream_encoder.c:mythread_join
Unexecuted instantiation: stream_flags_encoder.c:mythread_join
Unexecuted instantiation: crc32_fast.c:mythread_join
Unexecuted instantiation: lzma_encoder_presets.c:mythread_join
Unexecuted instantiation: block_util.c:mythread_join
Unexecuted instantiation: filter_common.c:mythread_join
Unexecuted instantiation: index.c:mythread_join
Unexecuted instantiation: stream_flags_common.c:mythread_join
Unexecuted instantiation: vli_size.c:mythread_join
Unexecuted instantiation: block_encoder.c:mythread_join
Unexecuted instantiation: block_header_encoder.c:mythread_join
Unexecuted instantiation: filter_encoder.c:mythread_join
Unexecuted instantiation: filter_flags_encoder.c:mythread_join
Unexecuted instantiation: index_encoder.c:mythread_join
Unexecuted instantiation: vli_encoder.c:mythread_join
Unexecuted instantiation: check.c:mythread_join
Unexecuted instantiation: crc64_fast.c:mythread_join
Unexecuted instantiation: sha256.c:mythread_join
Unexecuted instantiation: lzma_encoder.c:mythread_join
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_join
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_join
Unexecuted instantiation: fastpos_table.c:mythread_join
Unexecuted instantiation: lzma2_encoder.c:mythread_join
Unexecuted instantiation: price_table.c:mythread_join
Unexecuted instantiation: delta_common.c:mythread_join
Unexecuted instantiation: delta_encoder.c:mythread_join
Unexecuted instantiation: simple_encoder.c:mythread_join
Unexecuted instantiation: x86.c:mythread_join
Unexecuted instantiation: powerpc.c:mythread_join
Unexecuted instantiation: ia64.c:mythread_join
Unexecuted instantiation: arm.c:mythread_join
Unexecuted instantiation: armthumb.c:mythread_join
Unexecuted instantiation: arm64.c:mythread_join
Unexecuted instantiation: sparc.c:mythread_join
Unexecuted instantiation: riscv.c:mythread_join
Unexecuted instantiation: lz_encoder.c:mythread_join
Unexecuted instantiation: lz_encoder_mf.c:mythread_join
Unexecuted instantiation: simple_coder.c:mythread_join
202
203
204
// Initializes a mutex. Returns zero on success and non-zero on error.
205
static inline int
206
mythread_mutex_init(mythread_mutex *mutex)
207
0
{
208
0
  return pthread_mutex_init(mutex, NULL);
209
0
}
Unexecuted instantiation: common.c:mythread_mutex_init
Unexecuted instantiation: stream_encoder.c:mythread_mutex_init
Unexecuted instantiation: stream_flags_encoder.c:mythread_mutex_init
Unexecuted instantiation: crc32_fast.c:mythread_mutex_init
Unexecuted instantiation: lzma_encoder_presets.c:mythread_mutex_init
Unexecuted instantiation: block_util.c:mythread_mutex_init
Unexecuted instantiation: filter_common.c:mythread_mutex_init
Unexecuted instantiation: index.c:mythread_mutex_init
Unexecuted instantiation: stream_flags_common.c:mythread_mutex_init
Unexecuted instantiation: vli_size.c:mythread_mutex_init
Unexecuted instantiation: block_encoder.c:mythread_mutex_init
Unexecuted instantiation: block_header_encoder.c:mythread_mutex_init
Unexecuted instantiation: filter_encoder.c:mythread_mutex_init
Unexecuted instantiation: filter_flags_encoder.c:mythread_mutex_init
Unexecuted instantiation: index_encoder.c:mythread_mutex_init
Unexecuted instantiation: vli_encoder.c:mythread_mutex_init
Unexecuted instantiation: check.c:mythread_mutex_init
Unexecuted instantiation: crc64_fast.c:mythread_mutex_init
Unexecuted instantiation: sha256.c:mythread_mutex_init
Unexecuted instantiation: lzma_encoder.c:mythread_mutex_init
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_mutex_init
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_mutex_init
Unexecuted instantiation: fastpos_table.c:mythread_mutex_init
Unexecuted instantiation: lzma2_encoder.c:mythread_mutex_init
Unexecuted instantiation: price_table.c:mythread_mutex_init
Unexecuted instantiation: delta_common.c:mythread_mutex_init
Unexecuted instantiation: delta_encoder.c:mythread_mutex_init
Unexecuted instantiation: simple_encoder.c:mythread_mutex_init
Unexecuted instantiation: x86.c:mythread_mutex_init
Unexecuted instantiation: powerpc.c:mythread_mutex_init
Unexecuted instantiation: ia64.c:mythread_mutex_init
Unexecuted instantiation: arm.c:mythread_mutex_init
Unexecuted instantiation: armthumb.c:mythread_mutex_init
Unexecuted instantiation: arm64.c:mythread_mutex_init
Unexecuted instantiation: sparc.c:mythread_mutex_init
Unexecuted instantiation: riscv.c:mythread_mutex_init
Unexecuted instantiation: lz_encoder.c:mythread_mutex_init
Unexecuted instantiation: lz_encoder_mf.c:mythread_mutex_init
Unexecuted instantiation: simple_coder.c:mythread_mutex_init
210
211
static inline void
212
mythread_mutex_destroy(mythread_mutex *mutex)
213
0
{
214
0
  int ret = pthread_mutex_destroy(mutex);
215
0
  assert(ret == 0);
216
0
  (void)ret;
217
0
}
Unexecuted instantiation: common.c:mythread_mutex_destroy
Unexecuted instantiation: stream_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: stream_flags_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: crc32_fast.c:mythread_mutex_destroy
Unexecuted instantiation: lzma_encoder_presets.c:mythread_mutex_destroy
Unexecuted instantiation: block_util.c:mythread_mutex_destroy
Unexecuted instantiation: filter_common.c:mythread_mutex_destroy
Unexecuted instantiation: index.c:mythread_mutex_destroy
Unexecuted instantiation: stream_flags_common.c:mythread_mutex_destroy
Unexecuted instantiation: vli_size.c:mythread_mutex_destroy
Unexecuted instantiation: block_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: block_header_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: filter_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: filter_flags_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: index_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: vli_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: check.c:mythread_mutex_destroy
Unexecuted instantiation: crc64_fast.c:mythread_mutex_destroy
Unexecuted instantiation: sha256.c:mythread_mutex_destroy
Unexecuted instantiation: lzma_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_mutex_destroy
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_mutex_destroy
Unexecuted instantiation: fastpos_table.c:mythread_mutex_destroy
Unexecuted instantiation: lzma2_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: price_table.c:mythread_mutex_destroy
Unexecuted instantiation: delta_common.c:mythread_mutex_destroy
Unexecuted instantiation: delta_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: simple_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: x86.c:mythread_mutex_destroy
Unexecuted instantiation: powerpc.c:mythread_mutex_destroy
Unexecuted instantiation: ia64.c:mythread_mutex_destroy
Unexecuted instantiation: arm.c:mythread_mutex_destroy
Unexecuted instantiation: armthumb.c:mythread_mutex_destroy
Unexecuted instantiation: arm64.c:mythread_mutex_destroy
Unexecuted instantiation: sparc.c:mythread_mutex_destroy
Unexecuted instantiation: riscv.c:mythread_mutex_destroy
Unexecuted instantiation: lz_encoder.c:mythread_mutex_destroy
Unexecuted instantiation: lz_encoder_mf.c:mythread_mutex_destroy
Unexecuted instantiation: simple_coder.c:mythread_mutex_destroy
218
219
static inline void
220
mythread_mutex_lock(mythread_mutex *mutex)
221
0
{
222
0
  int ret = pthread_mutex_lock(mutex);
223
0
  assert(ret == 0);
224
0
  (void)ret;
225
0
}
Unexecuted instantiation: common.c:mythread_mutex_lock
Unexecuted instantiation: stream_encoder.c:mythread_mutex_lock
Unexecuted instantiation: stream_flags_encoder.c:mythread_mutex_lock
Unexecuted instantiation: crc32_fast.c:mythread_mutex_lock
Unexecuted instantiation: lzma_encoder_presets.c:mythread_mutex_lock
Unexecuted instantiation: block_util.c:mythread_mutex_lock
Unexecuted instantiation: filter_common.c:mythread_mutex_lock
Unexecuted instantiation: index.c:mythread_mutex_lock
Unexecuted instantiation: stream_flags_common.c:mythread_mutex_lock
Unexecuted instantiation: vli_size.c:mythread_mutex_lock
Unexecuted instantiation: block_encoder.c:mythread_mutex_lock
Unexecuted instantiation: block_header_encoder.c:mythread_mutex_lock
Unexecuted instantiation: filter_encoder.c:mythread_mutex_lock
Unexecuted instantiation: filter_flags_encoder.c:mythread_mutex_lock
Unexecuted instantiation: index_encoder.c:mythread_mutex_lock
Unexecuted instantiation: vli_encoder.c:mythread_mutex_lock
Unexecuted instantiation: check.c:mythread_mutex_lock
Unexecuted instantiation: crc64_fast.c:mythread_mutex_lock
Unexecuted instantiation: sha256.c:mythread_mutex_lock
Unexecuted instantiation: lzma_encoder.c:mythread_mutex_lock
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_mutex_lock
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_mutex_lock
Unexecuted instantiation: fastpos_table.c:mythread_mutex_lock
Unexecuted instantiation: lzma2_encoder.c:mythread_mutex_lock
Unexecuted instantiation: price_table.c:mythread_mutex_lock
Unexecuted instantiation: delta_common.c:mythread_mutex_lock
Unexecuted instantiation: delta_encoder.c:mythread_mutex_lock
Unexecuted instantiation: simple_encoder.c:mythread_mutex_lock
Unexecuted instantiation: x86.c:mythread_mutex_lock
Unexecuted instantiation: powerpc.c:mythread_mutex_lock
Unexecuted instantiation: ia64.c:mythread_mutex_lock
Unexecuted instantiation: arm.c:mythread_mutex_lock
Unexecuted instantiation: armthumb.c:mythread_mutex_lock
Unexecuted instantiation: arm64.c:mythread_mutex_lock
Unexecuted instantiation: sparc.c:mythread_mutex_lock
Unexecuted instantiation: riscv.c:mythread_mutex_lock
Unexecuted instantiation: lz_encoder.c:mythread_mutex_lock
Unexecuted instantiation: lz_encoder_mf.c:mythread_mutex_lock
Unexecuted instantiation: simple_coder.c:mythread_mutex_lock
226
227
static inline void
228
mythread_mutex_unlock(mythread_mutex *mutex)
229
0
{
230
0
  int ret = pthread_mutex_unlock(mutex);
231
0
  assert(ret == 0);
232
0
  (void)ret;
233
0
}
Unexecuted instantiation: common.c:mythread_mutex_unlock
Unexecuted instantiation: stream_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: stream_flags_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: crc32_fast.c:mythread_mutex_unlock
Unexecuted instantiation: lzma_encoder_presets.c:mythread_mutex_unlock
Unexecuted instantiation: block_util.c:mythread_mutex_unlock
Unexecuted instantiation: filter_common.c:mythread_mutex_unlock
Unexecuted instantiation: index.c:mythread_mutex_unlock
Unexecuted instantiation: stream_flags_common.c:mythread_mutex_unlock
Unexecuted instantiation: vli_size.c:mythread_mutex_unlock
Unexecuted instantiation: block_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: block_header_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: filter_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: filter_flags_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: index_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: vli_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: check.c:mythread_mutex_unlock
Unexecuted instantiation: crc64_fast.c:mythread_mutex_unlock
Unexecuted instantiation: sha256.c:mythread_mutex_unlock
Unexecuted instantiation: lzma_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_mutex_unlock
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_mutex_unlock
Unexecuted instantiation: fastpos_table.c:mythread_mutex_unlock
Unexecuted instantiation: lzma2_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: price_table.c:mythread_mutex_unlock
Unexecuted instantiation: delta_common.c:mythread_mutex_unlock
Unexecuted instantiation: delta_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: simple_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: x86.c:mythread_mutex_unlock
Unexecuted instantiation: powerpc.c:mythread_mutex_unlock
Unexecuted instantiation: ia64.c:mythread_mutex_unlock
Unexecuted instantiation: arm.c:mythread_mutex_unlock
Unexecuted instantiation: armthumb.c:mythread_mutex_unlock
Unexecuted instantiation: arm64.c:mythread_mutex_unlock
Unexecuted instantiation: sparc.c:mythread_mutex_unlock
Unexecuted instantiation: riscv.c:mythread_mutex_unlock
Unexecuted instantiation: lz_encoder.c:mythread_mutex_unlock
Unexecuted instantiation: lz_encoder_mf.c:mythread_mutex_unlock
Unexecuted instantiation: simple_coder.c:mythread_mutex_unlock
234
235
236
// Initializes a condition variable.
237
//
238
// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the
239
// timeout in pthread_cond_timedwait() work correctly also if system time
240
// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available
241
// everywhere while the default CLOCK_REALTIME is, so the default is
242
// used if CLOCK_MONOTONIC isn't available.
243
//
244
// If clock_gettime() isn't available at all, gettimeofday() will be used.
245
static inline int
246
mythread_cond_init(mythread_cond *mycond)
247
0
{
248
0
#ifdef HAVE_CLOCK_GETTIME
249
0
# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
250
0
    defined(HAVE_CLOCK_MONOTONIC)
251
0
  struct timespec ts;
252
0
  pthread_condattr_t condattr;
253
0
254
0
  // POSIX doesn't seem to *require* that pthread_condattr_setclock()
255
0
  // will fail if given an unsupported clock ID. Test that
256
0
  // CLOCK_MONOTONIC really is supported using clock_gettime().
257
0
  if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0
258
0
      && pthread_condattr_init(&condattr) == 0) {
259
0
    int ret = pthread_condattr_setclock(
260
0
        &condattr, CLOCK_MONOTONIC);
261
0
    if (ret == 0)
262
0
      ret = pthread_cond_init(&mycond->cond, &condattr);
263
0
264
0
    pthread_condattr_destroy(&condattr);
265
0
266
0
    if (ret == 0) {
267
0
      mycond->clk_id = CLOCK_MONOTONIC;
268
0
      return 0;
269
0
    }
270
0
  }
271
0
272
0
  // If anything above fails, fall back to the default CLOCK_REALTIME.
273
0
  // POSIX requires that all implementations of clock_gettime() must
274
0
  // support at least CLOCK_REALTIME.
275
0
# endif
276
0
277
0
  mycond->clk_id = CLOCK_REALTIME;
278
0
#endif
279
0
280
0
  return pthread_cond_init(&mycond->cond, NULL);
281
0
}
Unexecuted instantiation: common.c:mythread_cond_init
Unexecuted instantiation: stream_encoder.c:mythread_cond_init
Unexecuted instantiation: stream_flags_encoder.c:mythread_cond_init
Unexecuted instantiation: crc32_fast.c:mythread_cond_init
Unexecuted instantiation: lzma_encoder_presets.c:mythread_cond_init
Unexecuted instantiation: block_util.c:mythread_cond_init
Unexecuted instantiation: filter_common.c:mythread_cond_init
Unexecuted instantiation: index.c:mythread_cond_init
Unexecuted instantiation: stream_flags_common.c:mythread_cond_init
Unexecuted instantiation: vli_size.c:mythread_cond_init
Unexecuted instantiation: block_encoder.c:mythread_cond_init
Unexecuted instantiation: block_header_encoder.c:mythread_cond_init
Unexecuted instantiation: filter_encoder.c:mythread_cond_init
Unexecuted instantiation: filter_flags_encoder.c:mythread_cond_init
Unexecuted instantiation: index_encoder.c:mythread_cond_init
Unexecuted instantiation: vli_encoder.c:mythread_cond_init
Unexecuted instantiation: check.c:mythread_cond_init
Unexecuted instantiation: crc64_fast.c:mythread_cond_init
Unexecuted instantiation: sha256.c:mythread_cond_init
Unexecuted instantiation: lzma_encoder.c:mythread_cond_init
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_cond_init
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_cond_init
Unexecuted instantiation: fastpos_table.c:mythread_cond_init
Unexecuted instantiation: lzma2_encoder.c:mythread_cond_init
Unexecuted instantiation: price_table.c:mythread_cond_init
Unexecuted instantiation: delta_common.c:mythread_cond_init
Unexecuted instantiation: delta_encoder.c:mythread_cond_init
Unexecuted instantiation: simple_encoder.c:mythread_cond_init
Unexecuted instantiation: x86.c:mythread_cond_init
Unexecuted instantiation: powerpc.c:mythread_cond_init
Unexecuted instantiation: ia64.c:mythread_cond_init
Unexecuted instantiation: arm.c:mythread_cond_init
Unexecuted instantiation: armthumb.c:mythread_cond_init
Unexecuted instantiation: arm64.c:mythread_cond_init
Unexecuted instantiation: sparc.c:mythread_cond_init
Unexecuted instantiation: riscv.c:mythread_cond_init
Unexecuted instantiation: lz_encoder.c:mythread_cond_init
Unexecuted instantiation: lz_encoder_mf.c:mythread_cond_init
Unexecuted instantiation: simple_coder.c:mythread_cond_init
282
283
static inline void
284
mythread_cond_destroy(mythread_cond *cond)
285
0
{
286
0
  int ret = pthread_cond_destroy(&cond->cond);
287
0
  assert(ret == 0);
288
0
  (void)ret;
289
0
}
Unexecuted instantiation: common.c:mythread_cond_destroy
Unexecuted instantiation: stream_encoder.c:mythread_cond_destroy
Unexecuted instantiation: stream_flags_encoder.c:mythread_cond_destroy
Unexecuted instantiation: crc32_fast.c:mythread_cond_destroy
Unexecuted instantiation: lzma_encoder_presets.c:mythread_cond_destroy
Unexecuted instantiation: block_util.c:mythread_cond_destroy
Unexecuted instantiation: filter_common.c:mythread_cond_destroy
Unexecuted instantiation: index.c:mythread_cond_destroy
Unexecuted instantiation: stream_flags_common.c:mythread_cond_destroy
Unexecuted instantiation: vli_size.c:mythread_cond_destroy
Unexecuted instantiation: block_encoder.c:mythread_cond_destroy
Unexecuted instantiation: block_header_encoder.c:mythread_cond_destroy
Unexecuted instantiation: filter_encoder.c:mythread_cond_destroy
Unexecuted instantiation: filter_flags_encoder.c:mythread_cond_destroy
Unexecuted instantiation: index_encoder.c:mythread_cond_destroy
Unexecuted instantiation: vli_encoder.c:mythread_cond_destroy
Unexecuted instantiation: check.c:mythread_cond_destroy
Unexecuted instantiation: crc64_fast.c:mythread_cond_destroy
Unexecuted instantiation: sha256.c:mythread_cond_destroy
Unexecuted instantiation: lzma_encoder.c:mythread_cond_destroy
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_cond_destroy
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_cond_destroy
Unexecuted instantiation: fastpos_table.c:mythread_cond_destroy
Unexecuted instantiation: lzma2_encoder.c:mythread_cond_destroy
Unexecuted instantiation: price_table.c:mythread_cond_destroy
Unexecuted instantiation: delta_common.c:mythread_cond_destroy
Unexecuted instantiation: delta_encoder.c:mythread_cond_destroy
Unexecuted instantiation: simple_encoder.c:mythread_cond_destroy
Unexecuted instantiation: x86.c:mythread_cond_destroy
Unexecuted instantiation: powerpc.c:mythread_cond_destroy
Unexecuted instantiation: ia64.c:mythread_cond_destroy
Unexecuted instantiation: arm.c:mythread_cond_destroy
Unexecuted instantiation: armthumb.c:mythread_cond_destroy
Unexecuted instantiation: arm64.c:mythread_cond_destroy
Unexecuted instantiation: sparc.c:mythread_cond_destroy
Unexecuted instantiation: riscv.c:mythread_cond_destroy
Unexecuted instantiation: lz_encoder.c:mythread_cond_destroy
Unexecuted instantiation: lz_encoder_mf.c:mythread_cond_destroy
Unexecuted instantiation: simple_coder.c:mythread_cond_destroy
290
291
static inline void
292
mythread_cond_signal(mythread_cond *cond)
293
0
{
294
0
  int ret = pthread_cond_signal(&cond->cond);
295
0
  assert(ret == 0);
296
0
  (void)ret;
297
0
}
Unexecuted instantiation: common.c:mythread_cond_signal
Unexecuted instantiation: stream_encoder.c:mythread_cond_signal
Unexecuted instantiation: stream_flags_encoder.c:mythread_cond_signal
Unexecuted instantiation: crc32_fast.c:mythread_cond_signal
Unexecuted instantiation: lzma_encoder_presets.c:mythread_cond_signal
Unexecuted instantiation: block_util.c:mythread_cond_signal
Unexecuted instantiation: filter_common.c:mythread_cond_signal
Unexecuted instantiation: index.c:mythread_cond_signal
Unexecuted instantiation: stream_flags_common.c:mythread_cond_signal
Unexecuted instantiation: vli_size.c:mythread_cond_signal
Unexecuted instantiation: block_encoder.c:mythread_cond_signal
Unexecuted instantiation: block_header_encoder.c:mythread_cond_signal
Unexecuted instantiation: filter_encoder.c:mythread_cond_signal
Unexecuted instantiation: filter_flags_encoder.c:mythread_cond_signal
Unexecuted instantiation: index_encoder.c:mythread_cond_signal
Unexecuted instantiation: vli_encoder.c:mythread_cond_signal
Unexecuted instantiation: check.c:mythread_cond_signal
Unexecuted instantiation: crc64_fast.c:mythread_cond_signal
Unexecuted instantiation: sha256.c:mythread_cond_signal
Unexecuted instantiation: lzma_encoder.c:mythread_cond_signal
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_cond_signal
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_cond_signal
Unexecuted instantiation: fastpos_table.c:mythread_cond_signal
Unexecuted instantiation: lzma2_encoder.c:mythread_cond_signal
Unexecuted instantiation: price_table.c:mythread_cond_signal
Unexecuted instantiation: delta_common.c:mythread_cond_signal
Unexecuted instantiation: delta_encoder.c:mythread_cond_signal
Unexecuted instantiation: simple_encoder.c:mythread_cond_signal
Unexecuted instantiation: x86.c:mythread_cond_signal
Unexecuted instantiation: powerpc.c:mythread_cond_signal
Unexecuted instantiation: ia64.c:mythread_cond_signal
Unexecuted instantiation: arm.c:mythread_cond_signal
Unexecuted instantiation: armthumb.c:mythread_cond_signal
Unexecuted instantiation: arm64.c:mythread_cond_signal
Unexecuted instantiation: sparc.c:mythread_cond_signal
Unexecuted instantiation: riscv.c:mythread_cond_signal
Unexecuted instantiation: lz_encoder.c:mythread_cond_signal
Unexecuted instantiation: lz_encoder_mf.c:mythread_cond_signal
Unexecuted instantiation: simple_coder.c:mythread_cond_signal
298
299
static inline void
300
mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
301
0
{
302
0
  int ret = pthread_cond_wait(&cond->cond, mutex);
303
0
  assert(ret == 0);
304
0
  (void)ret;
305
0
}
Unexecuted instantiation: common.c:mythread_cond_wait
Unexecuted instantiation: stream_encoder.c:mythread_cond_wait
Unexecuted instantiation: stream_flags_encoder.c:mythread_cond_wait
Unexecuted instantiation: crc32_fast.c:mythread_cond_wait
Unexecuted instantiation: lzma_encoder_presets.c:mythread_cond_wait
Unexecuted instantiation: block_util.c:mythread_cond_wait
Unexecuted instantiation: filter_common.c:mythread_cond_wait
Unexecuted instantiation: index.c:mythread_cond_wait
Unexecuted instantiation: stream_flags_common.c:mythread_cond_wait
Unexecuted instantiation: vli_size.c:mythread_cond_wait
Unexecuted instantiation: block_encoder.c:mythread_cond_wait
Unexecuted instantiation: block_header_encoder.c:mythread_cond_wait
Unexecuted instantiation: filter_encoder.c:mythread_cond_wait
Unexecuted instantiation: filter_flags_encoder.c:mythread_cond_wait
Unexecuted instantiation: index_encoder.c:mythread_cond_wait
Unexecuted instantiation: vli_encoder.c:mythread_cond_wait
Unexecuted instantiation: check.c:mythread_cond_wait
Unexecuted instantiation: crc64_fast.c:mythread_cond_wait
Unexecuted instantiation: sha256.c:mythread_cond_wait
Unexecuted instantiation: lzma_encoder.c:mythread_cond_wait
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_cond_wait
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_cond_wait
Unexecuted instantiation: fastpos_table.c:mythread_cond_wait
Unexecuted instantiation: lzma2_encoder.c:mythread_cond_wait
Unexecuted instantiation: price_table.c:mythread_cond_wait
Unexecuted instantiation: delta_common.c:mythread_cond_wait
Unexecuted instantiation: delta_encoder.c:mythread_cond_wait
Unexecuted instantiation: simple_encoder.c:mythread_cond_wait
Unexecuted instantiation: x86.c:mythread_cond_wait
Unexecuted instantiation: powerpc.c:mythread_cond_wait
Unexecuted instantiation: ia64.c:mythread_cond_wait
Unexecuted instantiation: arm.c:mythread_cond_wait
Unexecuted instantiation: armthumb.c:mythread_cond_wait
Unexecuted instantiation: arm64.c:mythread_cond_wait
Unexecuted instantiation: sparc.c:mythread_cond_wait
Unexecuted instantiation: riscv.c:mythread_cond_wait
Unexecuted instantiation: lz_encoder.c:mythread_cond_wait
Unexecuted instantiation: lz_encoder_mf.c:mythread_cond_wait
Unexecuted instantiation: simple_coder.c:mythread_cond_wait
306
307
// Waits on a condition or until a timeout expires. If the timeout expires,
308
// non-zero is returned, otherwise zero is returned.
309
static inline int
310
mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
311
    const mythread_condtime *condtime)
312
0
{
313
0
  int ret = pthread_cond_timedwait(&cond->cond, mutex, condtime);
314
0
  assert(ret == 0 || ret == ETIMEDOUT);
315
0
  return ret;
316
0
}
Unexecuted instantiation: common.c:mythread_cond_timedwait
Unexecuted instantiation: stream_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: stream_flags_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: crc32_fast.c:mythread_cond_timedwait
Unexecuted instantiation: lzma_encoder_presets.c:mythread_cond_timedwait
Unexecuted instantiation: block_util.c:mythread_cond_timedwait
Unexecuted instantiation: filter_common.c:mythread_cond_timedwait
Unexecuted instantiation: index.c:mythread_cond_timedwait
Unexecuted instantiation: stream_flags_common.c:mythread_cond_timedwait
Unexecuted instantiation: vli_size.c:mythread_cond_timedwait
Unexecuted instantiation: block_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: block_header_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: filter_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: filter_flags_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: index_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: vli_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: check.c:mythread_cond_timedwait
Unexecuted instantiation: crc64_fast.c:mythread_cond_timedwait
Unexecuted instantiation: sha256.c:mythread_cond_timedwait
Unexecuted instantiation: lzma_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_cond_timedwait
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_cond_timedwait
Unexecuted instantiation: fastpos_table.c:mythread_cond_timedwait
Unexecuted instantiation: lzma2_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: price_table.c:mythread_cond_timedwait
Unexecuted instantiation: delta_common.c:mythread_cond_timedwait
Unexecuted instantiation: delta_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: simple_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: x86.c:mythread_cond_timedwait
Unexecuted instantiation: powerpc.c:mythread_cond_timedwait
Unexecuted instantiation: ia64.c:mythread_cond_timedwait
Unexecuted instantiation: arm.c:mythread_cond_timedwait
Unexecuted instantiation: armthumb.c:mythread_cond_timedwait
Unexecuted instantiation: arm64.c:mythread_cond_timedwait
Unexecuted instantiation: sparc.c:mythread_cond_timedwait
Unexecuted instantiation: riscv.c:mythread_cond_timedwait
Unexecuted instantiation: lz_encoder.c:mythread_cond_timedwait
Unexecuted instantiation: lz_encoder_mf.c:mythread_cond_timedwait
Unexecuted instantiation: simple_coder.c:mythread_cond_timedwait
317
318
// Sets condtime to the absolute time that is timeout_ms milliseconds
319
// in the future. The type of the clock to use is taken from cond.
320
static inline void
321
mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
322
    uint32_t timeout_ms)
323
0
{
324
0
  condtime->tv_sec = (time_t)(timeout_ms / 1000);
325
0
  condtime->tv_nsec = (long)((timeout_ms % 1000) * 1000000);
326
0
327
0
#ifdef HAVE_CLOCK_GETTIME
328
0
  struct timespec now;
329
0
  int ret = clock_gettime(cond->clk_id, &now);
330
0
  assert(ret == 0);
331
0
  (void)ret;
332
0
333
0
  condtime->tv_sec += now.tv_sec;
334
0
  condtime->tv_nsec += now.tv_nsec;
335
0
#else
336
0
  (void)cond;
337
0
338
0
  struct timeval now;
339
0
  gettimeofday(&now, NULL);
340
0
341
0
  condtime->tv_sec += now.tv_sec;
342
0
  condtime->tv_nsec += now.tv_usec * 1000L;
343
0
#endif
344
0
345
0
  // tv_nsec must stay in the range [0, 999_999_999].
346
0
  if (condtime->tv_nsec >= 1000000000L) {
347
0
    condtime->tv_nsec -= 1000000000L;
348
0
    ++condtime->tv_sec;
349
0
  }
350
0
}
Unexecuted instantiation: common.c:mythread_condtime_set
Unexecuted instantiation: stream_encoder.c:mythread_condtime_set
Unexecuted instantiation: stream_flags_encoder.c:mythread_condtime_set
Unexecuted instantiation: crc32_fast.c:mythread_condtime_set
Unexecuted instantiation: lzma_encoder_presets.c:mythread_condtime_set
Unexecuted instantiation: block_util.c:mythread_condtime_set
Unexecuted instantiation: filter_common.c:mythread_condtime_set
Unexecuted instantiation: index.c:mythread_condtime_set
Unexecuted instantiation: stream_flags_common.c:mythread_condtime_set
Unexecuted instantiation: vli_size.c:mythread_condtime_set
Unexecuted instantiation: block_encoder.c:mythread_condtime_set
Unexecuted instantiation: block_header_encoder.c:mythread_condtime_set
Unexecuted instantiation: filter_encoder.c:mythread_condtime_set
Unexecuted instantiation: filter_flags_encoder.c:mythread_condtime_set
Unexecuted instantiation: index_encoder.c:mythread_condtime_set
Unexecuted instantiation: vli_encoder.c:mythread_condtime_set
Unexecuted instantiation: check.c:mythread_condtime_set
Unexecuted instantiation: crc64_fast.c:mythread_condtime_set
Unexecuted instantiation: sha256.c:mythread_condtime_set
Unexecuted instantiation: lzma_encoder.c:mythread_condtime_set
Unexecuted instantiation: lzma_encoder_optimum_fast.c:mythread_condtime_set
Unexecuted instantiation: lzma_encoder_optimum_normal.c:mythread_condtime_set
Unexecuted instantiation: fastpos_table.c:mythread_condtime_set
Unexecuted instantiation: lzma2_encoder.c:mythread_condtime_set
Unexecuted instantiation: price_table.c:mythread_condtime_set
Unexecuted instantiation: delta_common.c:mythread_condtime_set
Unexecuted instantiation: delta_encoder.c:mythread_condtime_set
Unexecuted instantiation: simple_encoder.c:mythread_condtime_set
Unexecuted instantiation: x86.c:mythread_condtime_set
Unexecuted instantiation: powerpc.c:mythread_condtime_set
Unexecuted instantiation: ia64.c:mythread_condtime_set
Unexecuted instantiation: arm.c:mythread_condtime_set
Unexecuted instantiation: armthumb.c:mythread_condtime_set
Unexecuted instantiation: arm64.c:mythread_condtime_set
Unexecuted instantiation: sparc.c:mythread_condtime_set
Unexecuted instantiation: riscv.c:mythread_condtime_set
Unexecuted instantiation: lz_encoder.c:mythread_condtime_set
Unexecuted instantiation: lz_encoder_mf.c:mythread_condtime_set
Unexecuted instantiation: simple_coder.c:mythread_condtime_set
351
352
353
#elif defined(MYTHREAD_WIN95) || defined(MYTHREAD_VISTA)
354
355
/////////////////////
356
// Windows threads //
357
/////////////////////
358
359
#define WIN32_LEAN_AND_MEAN
360
#ifdef MYTHREAD_VISTA
361
# undef _WIN32_WINNT
362
# define _WIN32_WINNT 0x0600
363
#endif
364
#include <windows.h>
365
#include <process.h>
366
367
#define MYTHREAD_RET_TYPE unsigned int __stdcall
368
#define MYTHREAD_RET_VALUE 0
369
370
typedef HANDLE mythread;
371
typedef CRITICAL_SECTION mythread_mutex;
372
373
#ifdef MYTHREAD_WIN95
374
typedef HANDLE mythread_cond;
375
#else
376
typedef CONDITION_VARIABLE mythread_cond;
377
#endif
378
379
typedef struct {
380
  // Tick count (milliseconds) in the beginning of the timeout.
381
  // NOTE: This is 32 bits so it wraps around after 49.7 days.
382
  // Multi-day timeouts may not work as expected.
383
  DWORD start;
384
385
  // Length of the timeout in milliseconds. The timeout expires
386
  // when the current tick count minus "start" is equal or greater
387
  // than "timeout".
388
  DWORD timeout;
389
} mythread_condtime;
390
391
392
// mythread_once() is only available with Vista threads.
393
#ifdef MYTHREAD_VISTA
394
#define mythread_once(func) \
395
  do { \
396
    static INIT_ONCE once_ = INIT_ONCE_STATIC_INIT; \
397
    BOOL pending_; \
398
    if (!InitOnceBeginInitialize(&once_, 0, &pending_, NULL)) \
399
      abort(); \
400
    if (pending_) { \
401
      func(); \
402
      if (!InitOnceComplete(&once_, 0, NULL)) \
403
        abort(); \
404
    } \
405
  } while (0)
406
#endif
407
408
409
// mythread_sigmask() isn't available on Windows. Even a dummy version would
410
// make no sense because the other POSIX signal functions are missing anyway.
411
412
413
static inline int
414
mythread_create(mythread *thread,
415
    unsigned int (__stdcall *func)(void *arg), void *arg)
416
{
417
  uintptr_t ret = _beginthreadex(NULL, 0, func, arg, 0, NULL);
418
  if (ret == 0)
419
    return -1;
420
421
  *thread = (HANDLE)ret;
422
  return 0;
423
}
424
425
static inline int
426
mythread_join(mythread thread)
427
{
428
  int ret = 0;
429
430
  if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0)
431
    ret = -1;
432
433
  if (!CloseHandle(thread))
434
    ret = -1;
435
436
  return ret;
437
}
438
439
440
static inline int
441
mythread_mutex_init(mythread_mutex *mutex)
442
{
443
  InitializeCriticalSection(mutex);
444
  return 0;
445
}
446
447
static inline void
448
mythread_mutex_destroy(mythread_mutex *mutex)
449
{
450
  DeleteCriticalSection(mutex);
451
}
452
453
static inline void
454
mythread_mutex_lock(mythread_mutex *mutex)
455
{
456
  EnterCriticalSection(mutex);
457
}
458
459
static inline void
460
mythread_mutex_unlock(mythread_mutex *mutex)
461
{
462
  LeaveCriticalSection(mutex);
463
}
464
465
466
static inline int
467
mythread_cond_init(mythread_cond *cond)
468
{
469
#ifdef MYTHREAD_WIN95
470
  *cond = CreateEvent(NULL, FALSE, FALSE, NULL);
471
  return *cond == NULL ? -1 : 0;
472
#else
473
  InitializeConditionVariable(cond);
474
  return 0;
475
#endif
476
}
477
478
static inline void
479
mythread_cond_destroy(mythread_cond *cond)
480
{
481
#ifdef MYTHREAD_WIN95
482
  CloseHandle(*cond);
483
#else
484
  (void)cond;
485
#endif
486
}
487
488
static inline void
489
mythread_cond_signal(mythread_cond *cond)
490
{
491
#ifdef MYTHREAD_WIN95
492
  SetEvent(*cond);
493
#else
494
  WakeConditionVariable(cond);
495
#endif
496
}
497
498
static inline void
499
mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
500
{
501
#ifdef MYTHREAD_WIN95
502
  LeaveCriticalSection(mutex);
503
  WaitForSingleObject(*cond, INFINITE);
504
  EnterCriticalSection(mutex);
505
#else
506
  BOOL ret = SleepConditionVariableCS(cond, mutex, INFINITE);
507
  assert(ret);
508
  (void)ret;
509
#endif
510
}
511
512
static inline int
513
mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
514
    const mythread_condtime *condtime)
515
{
516
#ifdef MYTHREAD_WIN95
517
  LeaveCriticalSection(mutex);
518
#endif
519
520
  DWORD elapsed = GetTickCount() - condtime->start;
521
  DWORD timeout = elapsed >= condtime->timeout
522
      ? 0 : condtime->timeout - elapsed;
523
524
#ifdef MYTHREAD_WIN95
525
  DWORD ret = WaitForSingleObject(*cond, timeout);
526
  assert(ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT);
527
528
  EnterCriticalSection(mutex);
529
530
  return ret == WAIT_TIMEOUT;
531
#else
532
  BOOL ret = SleepConditionVariableCS(cond, mutex, timeout);
533
  assert(ret || GetLastError() == ERROR_TIMEOUT);
534
  return !ret;
535
#endif
536
}
537
538
static inline void
539
mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
540
    uint32_t timeout)
541
{
542
  (void)cond;
543
  condtime->start = GetTickCount();
544
  condtime->timeout = timeout;
545
}
546
547
#endif
548
549
#endif