xref: /freebsd/sys/contrib/zstd/lib/common/threading.c (revision 0c16b53773565120a8f80a31a0af2ef56ccd368e)
1*0c16b537SWarner Losh /**
2*0c16b537SWarner Losh  * Copyright (c) 2016 Tino Reichardt
3*0c16b537SWarner Losh  * All rights reserved.
4*0c16b537SWarner Losh  *
5*0c16b537SWarner Losh  * This source code is licensed under both the BSD-style license (found in the
6*0c16b537SWarner Losh  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*0c16b537SWarner Losh  * in the COPYING file in the root directory of this source tree).
8*0c16b537SWarner Losh  *
9*0c16b537SWarner Losh  * You can contact the author at:
10*0c16b537SWarner Losh  * - zstdmt source repository: https://github.com/mcmilk/zstdmt
11*0c16b537SWarner Losh  */
12*0c16b537SWarner Losh 
13*0c16b537SWarner Losh /**
14*0c16b537SWarner Losh  * This file will hold wrapper for systems, which do not support pthreads
15*0c16b537SWarner Losh  */
16*0c16b537SWarner Losh 
17*0c16b537SWarner Losh /* create fake symbol to avoid empty trnaslation unit warning */
18*0c16b537SWarner Losh int g_ZSTD_threading_useles_symbol;
19*0c16b537SWarner Losh 
20*0c16b537SWarner Losh #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
21*0c16b537SWarner Losh 
22*0c16b537SWarner Losh /**
23*0c16b537SWarner Losh  * Windows minimalist Pthread Wrapper, based on :
24*0c16b537SWarner Losh  * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
25*0c16b537SWarner Losh  */
26*0c16b537SWarner Losh 
27*0c16b537SWarner Losh 
28*0c16b537SWarner Losh /* ===  Dependencies  === */
29*0c16b537SWarner Losh #include <process.h>
30*0c16b537SWarner Losh #include <errno.h>
31*0c16b537SWarner Losh #include "threading.h"
32*0c16b537SWarner Losh 
33*0c16b537SWarner Losh 
34*0c16b537SWarner Losh /* ===  Implementation  === */
35*0c16b537SWarner Losh 
36*0c16b537SWarner Losh static unsigned __stdcall worker(void *arg)
37*0c16b537SWarner Losh {
38*0c16b537SWarner Losh     ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
39*0c16b537SWarner Losh     thread->arg = thread->start_routine(thread->arg);
40*0c16b537SWarner Losh     return 0;
41*0c16b537SWarner Losh }
42*0c16b537SWarner Losh 
43*0c16b537SWarner Losh int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
44*0c16b537SWarner Losh             void* (*start_routine) (void*), void* arg)
45*0c16b537SWarner Losh {
46*0c16b537SWarner Losh     (void)unused;
47*0c16b537SWarner Losh     thread->arg = arg;
48*0c16b537SWarner Losh     thread->start_routine = start_routine;
49*0c16b537SWarner Losh     thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
50*0c16b537SWarner Losh 
51*0c16b537SWarner Losh     if (!thread->handle)
52*0c16b537SWarner Losh         return errno;
53*0c16b537SWarner Losh     else
54*0c16b537SWarner Losh         return 0;
55*0c16b537SWarner Losh }
56*0c16b537SWarner Losh 
57*0c16b537SWarner Losh int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
58*0c16b537SWarner Losh {
59*0c16b537SWarner Losh     DWORD result;
60*0c16b537SWarner Losh 
61*0c16b537SWarner Losh     if (!thread.handle) return 0;
62*0c16b537SWarner Losh 
63*0c16b537SWarner Losh     result = WaitForSingleObject(thread.handle, INFINITE);
64*0c16b537SWarner Losh     switch (result) {
65*0c16b537SWarner Losh     case WAIT_OBJECT_0:
66*0c16b537SWarner Losh         if (value_ptr) *value_ptr = thread.arg;
67*0c16b537SWarner Losh         return 0;
68*0c16b537SWarner Losh     case WAIT_ABANDONED:
69*0c16b537SWarner Losh         return EINVAL;
70*0c16b537SWarner Losh     default:
71*0c16b537SWarner Losh         return GetLastError();
72*0c16b537SWarner Losh     }
73*0c16b537SWarner Losh }
74*0c16b537SWarner Losh 
75*0c16b537SWarner Losh #endif   /* ZSTD_MULTITHREAD */
76