blob: e2edb313ebff123517b361df87bcb05bca2c74f1 [file] [log] [blame]
Yann Collet3b9d4342016-12-31 16:32:19 +01001/**
2 * Copyright (c) 2016 Tino Reichardt
3 * All rights reserved.
4 *
Nick Terrellac58c8d2020-03-26 15:19:05 -07005 * You can contact the author at:
6 * - zstdmt source repository: https://github.com/mcmilk/zstdmt
7 *
Yann Collete9dc2042017-08-31 11:24:54 -07008 * 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).
Nick Terrellac58c8d2020-03-26 15:19:05 -070011 * You may select, at your option, one of the above-listed licenses.
Yann Collet3b9d4342016-12-31 16:32:19 +010012 */
13
14/**
Yann Collet0f984d92017-01-19 14:05:07 -080015 * This file will hold wrapper for systems, which do not support pthreads
Yann Collet3b9d4342016-12-31 16:32:19 +010016 */
17
Nick Terrell24382452019-10-18 12:33:45 -070018#include "threading.h"
19
Josh Sorefa880ca22019-04-12 14:18:11 -040020/* create fake symbol to avoid empty translation unit warning */
21int g_ZSTD_threading_useless_symbol;
cyan49735fba09f2017-01-20 12:23:30 -080022
Yann Collet0f984d92017-01-19 14:05:07 -080023#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
Yann Collet3b9d4342016-12-31 16:32:19 +010024
25/**
26 * Windows minimalist Pthread Wrapper, based on :
27 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
28 */
29
30
31/* === Dependencies === */
32#include <process.h>
33#include <errno.h>
Yann Collet3b9d4342016-12-31 16:32:19 +010034
35
36/* === Implementation === */
37
38static unsigned __stdcall worker(void *arg)
39{
Nick Terrell6c41adf2017-09-27 11:16:24 -070040 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
Yann Collet3b9d4342016-12-31 16:32:19 +010041 thread->arg = thread->start_routine(thread->arg);
42 return 0;
43}
44
Nick Terrell6c41adf2017-09-27 11:16:24 -070045int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
Yann Collet3b9d4342016-12-31 16:32:19 +010046 void* (*start_routine) (void*), void* arg)
47{
48 (void)unused;
49 thread->arg = arg;
50 thread->start_routine = start_routine;
51 thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
52
53 if (!thread->handle)
54 return errno;
55 else
56 return 0;
57}
58
Nick Terrell6c41adf2017-09-27 11:16:24 -070059int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
Yann Collet3b9d4342016-12-31 16:32:19 +010060{
61 DWORD result;
62
Nick Terrell6c41adf2017-09-27 11:16:24 -070063 if (!thread.handle) return 0;
Yann Collet3b9d4342016-12-31 16:32:19 +010064
Nick Terrell6c41adf2017-09-27 11:16:24 -070065 result = WaitForSingleObject(thread.handle, INFINITE);
Yann Collet3b9d4342016-12-31 16:32:19 +010066 switch (result) {
67 case WAIT_OBJECT_0:
Nick Terrell6c41adf2017-09-27 11:16:24 -070068 if (value_ptr) *value_ptr = thread.arg;
Yann Collet3b9d4342016-12-31 16:32:19 +010069 return 0;
70 case WAIT_ABANDONED:
71 return EINVAL;
72 default:
73 return GetLastError();
74 }
75}
76
Yann Collet0f984d92017-01-19 14:05:07 -080077#endif /* ZSTD_MULTITHREAD */
Nick Terrell24382452019-10-18 12:33:45 -070078
79#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
80
81#include <stdlib.h>
82
83int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
84{
85 *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
86 if (!*mutex)
87 return 1;
88 return pthread_mutex_init(*mutex, attr);
89}
90
91int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
92{
93 if (!*mutex)
94 return 0;
95 {
96 int const ret = pthread_mutex_destroy(*mutex);
97 free(*mutex);
98 return ret;
99 }
100}
101
102int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
103{
104 *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
105 if (!*cond)
106 return 1;
107 return pthread_cond_init(*cond, attr);
108}
109
110int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
111{
112 if (!*cond)
113 return 0;
114 {
115 int const ret = pthread_cond_destroy(*cond);
116 free(*cond);
117 return ret;
118 }
119}
120
121#endif