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_ */ 193