xref: /freebsd/sys/contrib/zstd/lib/common/threading.c (revision 2b9c00cb6bd9392645dc8afca59cf57c42df4e2d)
10c16b537SWarner Losh /**
20c16b537SWarner Losh  * Copyright (c) 2016 Tino Reichardt
30c16b537SWarner Losh  * All rights reserved.
40c16b537SWarner Losh  *
50c16b537SWarner Losh  * This source code is licensed under both the BSD-style license (found in the
60c16b537SWarner Losh  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
70c16b537SWarner Losh  * in the COPYING file in the root directory of this source tree).
80c16b537SWarner Losh  *
90c16b537SWarner Losh  * You can contact the author at:
100c16b537SWarner Losh  * - zstdmt source repository: https://github.com/mcmilk/zstdmt
110c16b537SWarner Losh  */
120c16b537SWarner Losh 
130c16b537SWarner Losh /**
140c16b537SWarner Losh  * This file will hold wrapper for systems, which do not support pthreads
150c16b537SWarner Losh  */
160c16b537SWarner Losh 
17*2b9c00cbSConrad Meyer /* create fake symbol to avoid empty translation unit warning */
18*2b9c00cbSConrad Meyer int g_ZSTD_threading_useless_symbol;
190c16b537SWarner Losh 
200c16b537SWarner Losh #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
210c16b537SWarner Losh 
220c16b537SWarner Losh /**
230c16b537SWarner Losh  * Windows minimalist Pthread Wrapper, based on :
240c16b537SWarner Losh  * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
250c16b537SWarner Losh  */
260c16b537SWarner Losh 
270c16b537SWarner Losh 
280c16b537SWarner Losh /* ===  Dependencies  === */
290c16b537SWarner Losh #include <process.h>
300c16b537SWarner Losh #include <errno.h>
310c16b537SWarner Losh #include "threading.h"
320c16b537SWarner Losh 
330c16b537SWarner Losh 
340c16b537SWarner Losh /* ===  Implementation  === */
350c16b537SWarner Losh 
360c16b537SWarner Losh static unsigned __stdcall worker(void *arg)
370c16b537SWarner Losh {
380c16b537SWarner Losh     ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
390c16b537SWarner Losh     thread->arg = thread->start_routine(thread->arg);
400c16b537SWarner Losh     return 0;
410c16b537SWarner Losh }
420c16b537SWarner Losh 
430c16b537SWarner Losh int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
440c16b537SWarner Losh             void* (*start_routine) (void*), void* arg)
450c16b537SWarner Losh {
460c16b537SWarner Losh     (void)unused;
470c16b537SWarner Losh     thread->arg = arg;
480c16b537SWarner Losh     thread->start_routine = start_routine;
490c16b537SWarner Losh     thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
500c16b537SWarner Losh 
510c16b537SWarner Losh     if (!thread->handle)
520c16b537SWarner Losh         return errno;
530c16b537SWarner Losh     else
540c16b537SWarner Losh         return 0;
550c16b537SWarner Losh }
560c16b537SWarner Losh 
570c16b537SWarner Losh int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
580c16b537SWarner Losh {
590c16b537SWarner Losh     DWORD result;
600c16b537SWarner Losh 
610c16b537SWarner Losh     if (!thread.handle) return 0;
620c16b537SWarner Losh 
630c16b537SWarner Losh     result = WaitForSingleObject(thread.handle, INFINITE);
640c16b537SWarner Losh     switch (result) {
650c16b537SWarner Losh     case WAIT_OBJECT_0:
660c16b537SWarner Losh         if (value_ptr) *value_ptr = thread.arg;
670c16b537SWarner Losh         return 0;
680c16b537SWarner Losh     case WAIT_ABANDONED:
690c16b537SWarner Losh         return EINVAL;
700c16b537SWarner Losh     default:
710c16b537SWarner Losh         return GetLastError();
720c16b537SWarner Losh     }
730c16b537SWarner Losh }
740c16b537SWarner Losh 
750c16b537SWarner Losh #endif   /* ZSTD_MULTITHREAD */
76