xref: /freebsd/sys/contrib/zstd/lib/common/threading.c (revision 6419bb52)
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, 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>
34 
35 
36 /* ===  Implementation  === */
37 
38 static unsigned __stdcall worker(void *arg)
39 {
40     ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
41     thread->arg = thread->start_routine(thread->arg);
42     return 0;
43 }
44 
45 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
46             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 
59 int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
60 {
61     DWORD result;
62 
63     if (!thread.handle) return 0;
64 
65     result = WaitForSingleObject(thread.handle, INFINITE);
66     switch (result) {
67     case WAIT_OBJECT_0:
68         if (value_ptr) *value_ptr = thread.arg;
69         return 0;
70     case WAIT_ABANDONED:
71         return EINVAL;
72     default:
73         return GetLastError();
74     }
75 }
76 
77 #endif   /* ZSTD_MULTITHREAD */
78 
79 #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
80 
81 #include <stdlib.h>
82 
83 int 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 
91 int 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 
102 int 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 
110 int 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
122