e2274cf4e928c286e336b0d73bbf4636d1689dca
[dpdk.git] / lib / librte_eal / windows / include / pthread.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #ifndef _PTHREAD_H_
6 #define _PTHREAD_H_
7
8 #include <stdint.h>
9
10 /**
11  * This file is required to support the common code in eal_common_proc.c,
12  * eal_common_thread.c and common\include\rte_per_lcore.h as Microsoft libc
13  * does not contain pthread.h. This may be removed in future releases.
14  */
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 #include <windows.h>
20 #include <rte_common.h>
21
22 #define PTHREAD_BARRIER_SERIAL_THREAD TRUE
23
24 /* defining pthread_t type on Windows since there is no in Microsoft libc*/
25 typedef uintptr_t pthread_t;
26
27 /* defining pthread_attr_t type on Windows since there is no in Microsoft libc*/
28 typedef void *pthread_attr_t;
29
30 typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
31
32 #define pthread_barrier_init(barrier, attr, count) \
33         InitializeSynchronizationBarrier(barrier, count, -1)
34 #define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier, \
35         SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
36 #define pthread_barrier_destroy(barrier) \
37         DeleteSynchronizationBarrier(barrier)
38 #define pthread_cancel(thread) TerminateThread((HANDLE) thread, 0)
39
40 /* pthread function overrides */
41 #define pthread_self() \
42         ((pthread_t)GetCurrentThreadId())
43 #define pthread_setaffinity_np(thread, size, cpuset) \
44         eal_set_thread_affinity_mask(thread, (unsigned long *) cpuset)
45 #define pthread_getaffinity_np(thread, size, cpuset) \
46         eal_get_thread_affinity_mask(thread, (unsigned long *) cpuset)
47 #define pthread_create(threadid, threadattr, threadfunc, args) \
48         eal_create_thread(threadid, threadattr, threadfunc, args)
49
50 static inline int
51 eal_set_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
52 {
53         SetThreadAffinityMask((HANDLE) threadid, *cpuset);
54         return 0;
55 }
56
57 static inline int
58 eal_get_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
59 {
60         /* Workaround for the lack of a GetThreadAffinityMask()
61          *API in Windows
62          */
63                 /* obtain previous mask by setting dummy mask */
64         DWORD dwprevaffinitymask =
65                 SetThreadAffinityMask((HANDLE) threadid, 0x1);
66         /* set it back! */
67         SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask);
68         *cpuset = dwprevaffinitymask;
69         return 0;
70 }
71
72 static inline int
73 eal_create_thread(void *threadid, const void *threadattr, void *threadfunc,
74                 void *args)
75 {
76         RTE_SET_USED(threadattr);
77         HANDLE hThread;
78         hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc,
79                 args, 0, (LPDWORD)threadid);
80         if (hThread) {
81                 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
82                 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
83         }
84         return ((hThread != NULL) ? 0 : E_FAIL);
85 }
86
87 static inline int
88 pthread_join(__rte_unused pthread_t thread,
89         __rte_unused void **value_ptr)
90 {
91         return 0;
92 }
93
94 #ifdef __cplusplus
95 }
96 #endif
97
98 #endif /* _PTHREAD_H_ */