eal/windows: fix interrupt thread ID
[dpdk.git] / lib / 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 #include <sched.h>
10
11 /**
12  * This file is required to support the common code in eal_common_proc.c,
13  * eal_common_thread.c and common\include\rte_per_lcore.h as Microsoft libc
14  * does not contain pthread.h. This may be removed in future releases.
15  */
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 #include <rte_common.h>
21 #include <rte_windows.h>
22
23 #define PTHREAD_BARRIER_SERIAL_THREAD TRUE
24
25 /* defining pthread_t type on Windows since there is no in Microsoft libc*/
26 typedef uintptr_t pthread_t;
27
28 /* defining pthread_attr_t type on Windows since there is no in Microsoft libc*/
29 typedef void *pthread_attr_t;
30
31 typedef void *pthread_mutexattr_t;
32
33 typedef CRITICAL_SECTION pthread_mutex_t;
34
35 typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
36
37 #define pthread_barrier_init(barrier, attr, count) \
38         !InitializeSynchronizationBarrier(barrier, count, -1)
39 #define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier, \
40         SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
41 #define pthread_barrier_destroy(barrier) \
42         !DeleteSynchronizationBarrier(barrier)
43 #define pthread_cancel(thread) !TerminateThread((HANDLE) thread, 0)
44
45 /* pthread function overrides */
46 #define pthread_self() \
47         ((pthread_t)GetCurrentThreadId())
48
49
50 static inline int
51 pthread_equal(pthread_t t1, pthread_t t2)
52 {
53         return t1 == t2;
54 }
55
56 static inline int
57 pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
58                         rte_cpuset_t *cpuset)
59 {
60         DWORD_PTR ret = 0;
61         HANDLE thread_handle;
62
63         if (cpuset == NULL || cpuset_size == 0)
64                 return -1;
65
66         thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
67         if (thread_handle == NULL) {
68                 RTE_LOG_WIN32_ERR("OpenThread()");
69                 return -1;
70         }
71
72         ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
73         if (ret == 0) {
74                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
75                 goto close_handle;
76         }
77
78 close_handle:
79         if (CloseHandle(thread_handle) == 0) {
80                 RTE_LOG_WIN32_ERR("CloseHandle()");
81                 return -1;
82         }
83         return (ret == 0) ? -1 : 0;
84 }
85
86 static inline int
87 pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
88                         rte_cpuset_t *cpuset)
89 {
90         /* Workaround for the lack of a GetThreadAffinityMask()
91          *API in Windows
92          */
93         DWORD_PTR prev_affinity_mask;
94         HANDLE thread_handle;
95         DWORD_PTR ret = 0;
96
97         if (cpuset == NULL || cpuset_size == 0)
98                 return -1;
99
100         thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
101         if (thread_handle == NULL) {
102                 RTE_LOG_WIN32_ERR("OpenThread()");
103                 return -1;
104         }
105
106         /* obtain previous mask by setting dummy mask */
107         prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
108         if (prev_affinity_mask == 0) {
109                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
110                 goto close_handle;
111         }
112
113         /* set it back! */
114         ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
115         if (ret == 0) {
116                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
117                 goto close_handle;
118         }
119
120         memset(cpuset, 0, cpuset_size);
121         *cpuset->_bits = prev_affinity_mask;
122
123 close_handle:
124         if (CloseHandle(thread_handle) == 0) {
125                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
126                 return -1;
127         }
128         return (ret == 0) ? -1 : 0;
129 }
130
131 static inline int
132 pthread_create(void *threadid, const void *threadattr, void *threadfunc,
133                 void *args)
134 {
135         RTE_SET_USED(threadattr);
136         HANDLE hThread;
137         hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc,
138                 args, 0, (LPDWORD)threadid);
139         if (hThread) {
140                 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
141                 SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL);
142         }
143         return ((hThread != NULL) ? 0 : E_FAIL);
144 }
145
146 static inline int
147 pthread_detach(__rte_unused pthread_t thread)
148 {
149         return 0;
150 }
151
152 static inline int
153 pthread_join(__rte_unused pthread_t thread,
154         __rte_unused void **value_ptr)
155 {
156         return 0;
157 }
158
159 static inline int
160 pthread_mutex_init(pthread_mutex_t *mutex,
161                    __rte_unused pthread_mutexattr_t *attr)
162 {
163         InitializeCriticalSection(mutex);
164         return 0;
165 }
166
167 static inline int
168 pthread_mutex_lock(pthread_mutex_t *mutex)
169 {
170         EnterCriticalSection(mutex);
171         return 0;
172 }
173
174 static inline int
175 pthread_mutex_unlock(pthread_mutex_t *mutex)
176 {
177         LeaveCriticalSection(mutex);
178         return 0;
179 }
180
181 static inline int
182 pthread_mutex_destroy(pthread_mutex_t *mutex)
183 {
184         DeleteCriticalSection(mutex);
185         return 0;
186 }
187
188 #ifdef __cplusplus
189 }
190 #endif
191
192 #endif /* _PTHREAD_H_ */