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