blob: 482664bd9adacb8588934639c6ba051a9c0cc62b [file] [log] [blame]
Yann Collet3b9d4342016-12-31 16:32:19 +01001/**
2 * Copyright (c) 2016 Tino Reichardt
3 * All rights reserved.
4 *
Yann Collete9dc2042017-08-31 11:24:54 -07005 * 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).
Yann Collet3b9d4342016-12-31 16:32:19 +01008 *
9 * You can contact the author at:
10 * - zstdmt source repository: https://github.com/mcmilk/zstdmt
11 */
12
13/**
Yann Collet0f984d92017-01-19 14:05:07 -080014 * This file will hold wrapper for systems, which do not support pthreads
Yann Collet3b9d4342016-12-31 16:32:19 +010015 */
16
Nick Terrell24382452019-10-18 12:33:45 -070017#include "threading.h"
18
Josh Sorefa880ca22019-04-12 14:18:11 -040019/* create fake symbol to avoid empty translation unit warning */
20int g_ZSTD_threading_useless_symbol;
cyan49735fba09f2017-01-20 12:23:30 -080021
Yann Collet0f984d92017-01-19 14:05:07 -080022#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
Yann Collet3b9d4342016-12-31 16:32:19 +010023
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>
Yann Collet3b9d4342016-12-31 16:32:19 +010033
34
35/* === Implementation === */
36
37static unsigned __stdcall worker(void *arg)
38{
Nick Terrell6c41adf2017-09-27 11:16:24 -070039 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
Yann Collet3b9d4342016-12-31 16:32:19 +010040 thread->arg = thread->start_routine(thread->arg);
41 return 0;
42}
43
Nick Terrell6c41adf2017-09-27 11:16:24 -070044int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
Yann Collet3b9d4342016-12-31 16:32:19 +010045 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
Nick Terrell6c41adf2017-09-27 11:16:24 -070058int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
Yann Collet3b9d4342016-12-31 16:32:19 +010059{
60 DWORD result;
61
Nick Terrell6c41adf2017-09-27 11:16:24 -070062 if (!thread.handle) return 0;
Yann Collet3b9d4342016-12-31 16:32:19 +010063
Nick Terrell6c41adf2017-09-27 11:16:24 -070064 result = WaitForSingleObject(thread.handle, INFINITE);
Yann Collet3b9d4342016-12-31 16:32:19 +010065 switch (result) {
66 case WAIT_OBJECT_0:
Nick Terrell6c41adf2017-09-27 11:16:24 -070067 if (value_ptr) *value_ptr = thread.arg;
Yann Collet3b9d4342016-12-31 16:32:19 +010068 return 0;
69 case WAIT_ABANDONED:
70 return EINVAL;
71 default:
72 return GetLastError();
73 }
74}
75
Yann Collet0f984d92017-01-19 14:05:07 -080076#endif /* ZSTD_MULTITHREAD */
Nick Terrell24382452019-10-18 12:33:45 -070077
78#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
79
80#include <stdlib.h>
81
82int 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
90int 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
101int 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
109int 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