eal/windows: add interrupt thread skeleton
[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 #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 SYNCHRONIZATION_BARRIER pthread_barrier_t;
32
33 #define pthread_barrier_init(barrier, attr, count) \
34         InitializeSynchronizationBarrier(barrier, count, -1)
35 #define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier, \
36         SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
37 #define pthread_barrier_destroy(barrier) \
38         DeleteSynchronizationBarrier(barrier)
39 #define pthread_cancel(thread) TerminateThread((HANDLE) thread, 0)
40
41 /* pthread function overrides */
42 #define pthread_self() \
43         ((pthread_t)GetCurrentThreadId())
44
45
46 static inline int
47 pthread_equal(pthread_t t1, pthread_t t2)
48 {
49         return t1 == t2;
50 }
51
52 static inline int
53 pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
54                         rte_cpuset_t *cpuset)
55 {
56         DWORD_PTR ret = 0;
57         HANDLE thread_handle;
58
59         if (cpuset == NULL || cpuset_size == 0)
60                 return -1;
61
62         thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
63         if (thread_handle == NULL) {
64                 RTE_LOG_WIN32_ERR("OpenThread()");
65                 return -1;
66         }
67
68         ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
69         if (ret == 0) {
70                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
71                 goto close_handle;
72         }
73
74 close_handle:
75         if (CloseHandle(thread_handle) == 0) {
76                 RTE_LOG_WIN32_ERR("CloseHandle()");
77                 return -1;
78         }
79         return (ret == 0) ? -1 : 0;
80 }
81
82 static inline int
83 pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
84                         rte_cpuset_t *cpuset)
85 {
86         /* Workaround for the lack of a GetThreadAffinityMask()
87          *API in Windows
88          */
89         DWORD_PTR prev_affinity_mask;
90         HANDLE thread_handle;
91         DWORD_PTR ret = 0;
92
93         if (cpuset == NULL || cpuset_size == 0)
94                 return -1;
95
96         thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
97         if (thread_handle == NULL) {
98                 RTE_LOG_WIN32_ERR("OpenThread()");
99                 return -1;
100         }
101
102         /* obtain previous mask by setting dummy mask */
103         prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
104         if (prev_affinity_mask == 0) {
105                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
106                 goto close_handle;
107         }
108
109         /* set it back! */
110         ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
111         if (ret == 0) {
112                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
113                 goto close_handle;
114         }
115
116         memset(cpuset, 0, cpuset_size);
117         *cpuset->_bits = prev_affinity_mask;
118
119 close_handle:
120         if (CloseHandle(thread_handle) == 0) {
121                 RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
122                 return -1;
123         }
124         return (ret == 0) ? -1 : 0;
125 }
126
127 static inline int
128 pthread_create(void *threadid, const void *threadattr, void *threadfunc,
129                 void *args)
130 {
131         RTE_SET_USED(threadattr);
132         HANDLE hThread;
133         hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc,
134                 args, 0, (LPDWORD)threadid);
135         if (hThread) {
136                 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
137                 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
138         }
139         return ((hThread != NULL) ? 0 : E_FAIL);
140 }
141
142 static inline int
143 pthread_join(__rte_unused pthread_t thread,
144         __rte_unused void **value_ptr)
145 {
146         return 0;
147 }
148
149 #ifdef __cplusplus
150 }
151 #endif
152
153 #endif /* _PTHREAD_H_ */