• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HWE_OSDEP_H
17 #define HWE_OSDEP_H
18 
19 #include <stdlib.h>
20 #include <limits.h>
21 #include "hwe_type.h"
22 #if defined(_WIN32)
23 #include <process.h>
24 #include <windows.h>
25 #include <time.h>
26 #else
27 #include <sched.h>
28 #include <pthread.h>
29 #include <sys/time.h>
30 #include <sys/prctl.h>
31 #endif
32 #include "hwe_source_record.h"
33 
34 #define HWE_FILE __FILE__
35 #define HWE_LINE __LINE__
36 
37 // kernel type enumeration
38 #if HWE_ARM_AARCH64
39 typedef enum HWE_Kernel {
40     KERNEL_TYPE_C = 0,
41     KERNEL_TYPE_NEON,
42     KERNEL_TYPE_TOTAL // total type number of kernel
43 } HWE_KernelType;
44 #elif HWE_ARM_AARCH32
45 typedef enum HWE_Kernel {
46     KERNEL_TYPE_C = 0,
47     KERNEL_TYPE_NEON,
48     KERNEL_TYPE_TOTAL // total type number of kernel
49 } HWE_KernelType;
50 #elif HWE_X86_64
51 typedef enum HWE_Kernel {
52     KERNEL_TYPE_C = 0,
53     KERNEL_TYPE_ASM,
54     KERNEL_TYPE_TOTAL,
55     KERNEL_TYPE_SSE2,
56     KERNEL_TYPE_SSE4,
57     KERNEL_TYPE_AVX,
58     KERNEL_TYPE_AVX2
59 } HWE_KernelType;
60 #elif HWE_X86_32
61 typedef enum HWE_Kernel {
62     KERNEL_TYPE_C = 0,
63     KERNEL_TYPE_INTRINSICS,
64     KERNEL_TYPE_TOTAL  // total type number of kernel
65 } HWE_KernelType;
66 #else
67 typedef enum HWE_Kernel {
68     KERNEL_TYPE_C = 0,
69     KERNEL_TYPE_ASM,
70     KERNEL_TYPE_TOTAL  // total type number of kernel
71 } HWE_KernelType;
72 #endif
73 
74 HWE_KernelType HWE_DetectSimdCapibility(void);
75 
76 #ifdef __ICL
77 #define inline __inline
78 #endif
79 
80 #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
81 #define HWE_INLINE __attribute__((always_inline)) inline
82 #else
83 #ifdef __ICL
84 #define HWE_INLINE __forceinline
85 #else
86 #define HWE_INLINE __inline
87 #endif
88 #endif
89 
90 
91 #if defined(_WIN32)
92 #define HWE_SPIN_COUNT 0
93 #define HWE_PTHREAD_MUTEX_INITIALIZER \
94     {                                 \
95         0                             \
96     }
97 
98 typedef CRITICAL_SECTION HWE_PthreadMutex;
99 typedef struct HWE_PthreadCond {
100     void *ptr;
101 } HWE_PthreadCond;
102 typedef struct HWE_Pthread {
103     void *handle;
104     void *(*func)(void *arg);
105     void *arg;
106     void *ret;
107     signed char isInit;
108 } HWE_Pthread;
109 typedef struct HWE_Win32ThreadControl {
110     HWE_PthreadMutex staticMutex;
111     void(WINAPI *condBroadcast)(HWE_PthreadCond *cond);
112     void(WINAPI *condInit)(HWE_PthreadCond *cond);
113     void(WINAPI *condSignal)(HWE_PthreadCond *cond);
114     BOOL(WINAPI *condWait)(HWE_PthreadCond *cond, HWE_PthreadMutex *mutex, DWORD milliseconds);
115 } HWE_Win32ThreadControl;
116 typedef struct HWE_Win32Cond {
117     HWE_PthreadMutex mtxBroadcast;
118     HWE_PthreadMutex mtxWaiterCount;
119     volatile int32_t waiterCount;
120     HANDLE semaphore;
121     HANDLE waitersDone;
122     volatile int32_t isBroadcast;
123 } HWE_Win32Cond;
124 
125 int32_t HWE_PthreadMutexInit(HWE_PthreadMutex *mutex);
126 int32_t HWE_PthreadMutexLock(HWE_PthreadMutex *mutex);
127 int32_t HWE_PthreadMutexUnLock(HWE_PthreadMutex *mutex);
128 int32_t HWE_PthreadMutexDestroy(HWE_PthreadMutex *mutex);
129 int32_t HWE_PthreadCondInit(HWE_PthreadCond *cond);
130 int32_t HWE_PthreadCondDestroy(HWE_PthreadCond *cond);
131 int32_t HWE_PthreadCondWait(HWE_PthreadCond *cond, HWE_PthreadMutex *mutex);
132 int32_t HWE_PthreadCondSignal(HWE_PthreadCond *cond);
133 int32_t HWE_PthreadCondBroadcast(HWE_PthreadCond *cond);
134 int32_t HWE_PthreadJoin(HWE_Pthread thread);
135 #else
136 typedef struct HWE_PthreadMutexType {
137     signed char isInit;
138     pthread_mutex_t mutex;
139 } HWE_PthreadMutex;
140 
141 typedef struct HWE_PthreadCondType {
142     signed char isInit;
143     pthread_cond_t cond;
144 } HWE_PthreadCond;
145 
146 typedef struct HWE_PthreadType {
147     signed char isInit;
148     pthread_t thread;
149 } HWE_Pthread;
150 
151 // detect cpu simd capibility
152 
HWE_PthreadMutexInit(HWE_PthreadMutex * mutex)153 static HWE_INLINE int32_t HWE_PthreadMutexInit(HWE_PthreadMutex *mutex)
154 {
155     int32_t ret = pthread_mutex_init(&mutex->mutex, nullptr);
156     mutex->isInit = (ret == 0) ? TRUE : FALSE;
157     if (mutex->isInit) {
158         RecordInitMutexCount();
159     }
160     return ret;
161 }
162 
HWE_PthreadMutexLock(HWE_PthreadMutex * mutex)163 static HWE_INLINE int32_t HWE_PthreadMutexLock(HWE_PthreadMutex *mutex)
164 {
165     return mutex->isInit ? pthread_mutex_lock(&mutex->mutex) : -1;
166 }
167 
HWE_PthreadMutexUnLock(HWE_PthreadMutex * mutex)168 static HWE_INLINE int32_t HWE_PthreadMutexUnLock(HWE_PthreadMutex *mutex)
169 {
170     return mutex->isInit ? pthread_mutex_unlock(&mutex->mutex) : -1;
171 }
172 
HWE_PthreadMutexDestroy(HWE_PthreadMutex * mutex)173 static HWE_INLINE int32_t HWE_PthreadMutexDestroy(HWE_PthreadMutex *mutex)
174 {
175     if (mutex->isInit) {
176         mutex->isInit = 0;
177         RecordDestoryMutexCount();
178         return pthread_mutex_destroy(&mutex->mutex);
179     } else {
180         return -1;
181     }
182 }
183 
HWE_PthreadCondInit(HWE_PthreadCond * cond)184 static HWE_INLINE int32_t HWE_PthreadCondInit(HWE_PthreadCond *cond)
185 {
186     int32_t ret = pthread_cond_init(&cond->cond, nullptr);
187     cond->isInit = (ret == 0) ? TRUE : FALSE;
188     if (cond->isInit) {
189         RecordInitCondCount();
190     }
191     return ret;
192 }
193 
HWE_PthreadCondDestroy(HWE_PthreadCond * cond)194 static HWE_INLINE int32_t HWE_PthreadCondDestroy(HWE_PthreadCond *cond)
195 {
196     if (cond->isInit) {
197         cond->isInit = 0;
198         RecordDestoryCondCount();
199         return pthread_cond_destroy(&cond->cond);
200     } else {
201         return -1;
202     }
203 }
204 
HWE_PthreadCondWait(HWE_PthreadCond * cond,HWE_PthreadMutex * mutex)205 static HWE_INLINE int32_t HWE_PthreadCondWait(HWE_PthreadCond *cond, HWE_PthreadMutex *mutex)
206 {
207     return (cond->isInit && mutex->isInit) ? pthread_cond_wait(&cond->cond, &mutex->mutex) : -1;
208 }
209 
HWE_PthreadCondSignal(HWE_PthreadCond * cond)210 static HWE_INLINE int32_t HWE_PthreadCondSignal(HWE_PthreadCond *cond)
211 {
212     return cond->isInit ? pthread_cond_signal(&cond->cond) : -1;
213 }
214 
HWE_PthreadCondBroadcast(HWE_PthreadCond * cond)215 static HWE_INLINE int32_t HWE_PthreadCondBroadcast(HWE_PthreadCond *cond)
216 {
217     return cond->isInit ? pthread_cond_broadcast(&cond->cond) : -1;
218 }
219 
HWE_PthreadJoin(HWE_Pthread thread)220 static HWE_INLINE int32_t HWE_PthreadJoin(HWE_Pthread thread)
221 {
222     if (thread.isInit) {
223         thread.isInit = 0;
224         RecordDestoryThreadCount();
225         return pthread_join(thread.thread, nullptr);
226     } else {
227         return -1;
228     }
229 }
230 
231 #endif
232 
233 int32_t HWE_SetThreadAffinityMask(const HWE_Pthread *thread, uint32_t cpuNum, const uint32_t *cpuIdxArray);
234 int32_t HWE_SetThreadPriority(const HWE_Pthread *thread, int32_t schedPriority);
235 
HWE_Malloc(size_t size)236 static HWE_INLINE void *HWE_Malloc(size_t size)
237 {
238     if (size == 0 || size >= INT_MAX) {
239         return nullptr;
240     }
241 
242     void *p = malloc(size);
243 
244     if (p != nullptr) {
245         RecordMallocMemCount();
246         return p;
247     } else {
248         return nullptr;
249     }
250 }
251 
252 #ifdef _WIN32
HWE_GetCurrentTime(void)253 static HWE_INLINE uint64_t HWE_GetCurrentTime(void)
254 {
255     clock_t time = clock();
256     return (uint64_t)time;
257 }
258 #else
259 #define TIME_FACTOR 1000000
HWE_GetCurrentTime(void)260 static HWE_INLINE uint64_t HWE_GetCurrentTime(void)
261 {
262     uint64_t time;
263     struct timeval t;
264     gettimeofday(&t, nullptr);
265 
266     time = (uint64_t)t.tv_sec * TIME_FACTOR + (uint64_t)t.tv_usec;
267     return time;
268 }
269 #endif
270 #endif