1 /*
2 * Copyright © 2014 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Wei Lin<wei.w.lin@intel.com>
26 * Yuting Yang<yuting.yang@intel.com>
27 */
28
29 #include "os_utilities.h"
30 #include "os_util_debug.h"
31 #include <fcntl.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <time.h>
35 #include <sys/stat.h>
36 #include <dlfcn.h>
37 #include <math.h>
38
39 #include <sys/ipc.h>
40 #include <sys/types.h>
41 #include <sys/sem.h>
42 #include <signal.h>
43 #include "string.h"
44 #include <unistd.h>
45
46 INT32 GenOsMemAllocCounter;
47 #define GENOS_MEMNINJA_ALLOC_MESSAGE(ptr, size) \
48 GENOS_OS_VERBOSEMESSAGE( \
49 "<MemNinjaSysAllocPtr memPtr = \"%d\" size = \"%d\" memType = \"Sys\"/>.", ptr, size); \
50 GENOS_OS_VERBOSEMESSAGE( \
51 "<MemNinjaSysLastFuncCall memPtr = \"%d\" functionName = \"%s\" file = \"%s\" " \
52 "memType = \"Sys\" line = \"%d\"/>.", ptr, __func__, __FILE__, __LINE__);
53
54 #define GENOS_MEMNINJA_FREE_MESSAGE(ptr) \
55 GENOS_OS_VERBOSEMESSAGE("GenOsMemAllocCounter = %d, Addr = 0x%x.", GenOsMemAllocCounter, ptr); \
56 GENOS_OS_VERBOSEMESSAGE("<MemNinjaSysFreePtr memPtr = \"%d\" memType = \"Sys\"/>.", ptr);
57
58 #define _aligned_malloc(size, alignment) aligned_alloc(alignment, size)
59 #define _aligned_free(ptr) free(ptr)
60
GENOS_AlignedAllocMemory(SIZE_T size,SIZE_T alignment)61 PVOID GENOS_AlignedAllocMemory(SIZE_T size, SIZE_T alignment)
62 {
63 PVOID ptr;
64
65 ptr = _aligned_malloc(size, alignment);
66
67 GENOS_OS_ASSERT(ptr != NULL);
68
69 if (ptr != NULL) {
70 GENOS_MEMNINJA_ALLOC_MESSAGE(ptr, size);
71 GenOsMemAllocCounter++;
72 }
73
74 return ptr;
75 }
76
GENOS_AlignedFreeMemory(PVOID ptr)77 VOID GENOS_AlignedFreeMemory(PVOID ptr)
78 {
79 GENOS_OS_ASSERT(ptr != NULL);
80
81 if (ptr != NULL) {
82 GenOsMemAllocCounter--;
83
84 GENOS_MEMNINJA_FREE_MESSAGE(ptr);
85
86 _aligned_free(ptr);
87 }
88 }
89
GENOS_AllocMemory(SIZE_T size)90 PVOID GENOS_AllocMemory(SIZE_T size)
91 {
92 PVOID ptr;
93
94 ptr = malloc(size);
95
96 GENOS_OS_ASSERT(ptr != NULL);
97
98 if (ptr != NULL) {
99 GENOS_MEMNINJA_ALLOC_MESSAGE(ptr, size);
100 GenOsMemAllocCounter++;
101 }
102
103 return ptr;
104 }
105
GENOS_AllocAndZeroMemory(SIZE_T size)106 PVOID GENOS_AllocAndZeroMemory(SIZE_T size)
107 {
108 PVOID ptr;
109
110 ptr = malloc(size);
111
112 GENOS_OS_ASSERT(ptr != NULL);
113
114 if (ptr != NULL) {
115 GENOS_ZeroMemory(ptr, size);
116
117 GENOS_MEMNINJA_ALLOC_MESSAGE(ptr, size);
118
119 GenOsMemAllocCounter++;
120 }
121
122 return ptr;
123 }
124
GENOS_FreeMemory(PVOID ptr)125 VOID GENOS_FreeMemory(PVOID ptr)
126 {
127 if (ptr != NULL) {
128 GenOsMemAllocCounter--;
129
130 GENOS_MEMNINJA_FREE_MESSAGE(ptr);
131
132 free(ptr);
133 }
134 }
135
GENOS_ZeroMemory(PVOID pDestination,SIZE_T stLength)136 VOID GENOS_ZeroMemory(PVOID pDestination, SIZE_T stLength)
137 {
138 GENOS_OS_ASSERT(pDestination != NULL);
139
140 if (pDestination != NULL) {
141 memset(pDestination, 0, stLength);
142 }
143 }
144
GENOS_FillMemory(PVOID pDestination,SIZE_T stLength,UINT8 bFill)145 VOID GENOS_FillMemory(PVOID pDestination, SIZE_T stLength, UINT8 bFill)
146 {
147 GENOS_OS_ASSERT(pDestination != NULL);
148
149 if (pDestination != NULL) {
150 memset(pDestination, bFill, stLength);
151 }
152 }
153
GENOS_SecureStrcat(PCHAR strDestination,SIZE_T numberOfElements,const PCCHAR strSource)154 GENOS_STATUS GENOS_SecureStrcat(PCHAR strDestination, SIZE_T numberOfElements,
155 const PCCHAR strSource)
156 {
157 if ((strDestination == NULL) || (strSource == NULL)) {
158 return GENOS_STATUS_INVALID_PARAMETER;
159 }
160
161 if (strnlen(strDestination, numberOfElements) == numberOfElements) {
162 return GENOS_STATUS_INVALID_PARAMETER;
163 }
164
165 if ((strlen(strDestination) + strlen(strSource)) >= numberOfElements) {
166 return GENOS_STATUS_INVALID_PARAMETER;
167 }
168
169 strcat(strDestination, strSource);
170 return GENOS_STATUS_SUCCESS;
171 }
172
GENOS_SecureStrtok(PCHAR strToken,PCCHAR strDelimit,PCHAR * contex)173 PCHAR GENOS_SecureStrtok(PCHAR strToken, PCCHAR strDelimit, PCHAR * contex)
174 {
175 return strtok_r(strToken, strDelimit, contex);
176 }
177
GENOS_SecureStrcpy(PCHAR strDestination,SIZE_T numberOfElements,const PCCHAR strSource)178 GENOS_STATUS GENOS_SecureStrcpy(PCHAR strDestination, SIZE_T numberOfElements,
179 const PCCHAR strSource)
180 {
181 if ((strDestination == NULL) || (strSource == NULL)) {
182 return GENOS_STATUS_INVALID_PARAMETER;
183 }
184
185 if (numberOfElements <= strlen(strSource)) {
186 return GENOS_STATUS_INVALID_PARAMETER;
187 }
188
189 strcpy(strDestination, strSource);
190
191 return GENOS_STATUS_SUCCESS;
192 }
193
GENOS_SecureMemcpy(PVOID pDestination,SIZE_T dstLength,PCVOID pSource,SIZE_T srcLength)194 GENOS_STATUS GENOS_SecureMemcpy(PVOID pDestination, SIZE_T dstLength,
195 PCVOID pSource, SIZE_T srcLength)
196 {
197 if ((pDestination == NULL) || (pSource == NULL)) {
198 return GENOS_STATUS_INVALID_PARAMETER;
199 }
200
201 if (dstLength < srcLength) {
202 return GENOS_STATUS_INVALID_PARAMETER;
203 }
204
205 memcpy(pDestination, pSource, srcLength);
206
207 return GENOS_STATUS_SUCCESS;
208 }
209
GENOS_SecureStringPrint(PCHAR buffer,SIZE_T bufSize,SIZE_T length,const PCCHAR format,...)210 INT32 GENOS_SecureStringPrint(PCHAR buffer, SIZE_T bufSize, SIZE_T length,
211 const PCCHAR format, ...)
212 {
213 INT32 iRet = -1;
214 va_list var_args;
215
216 if ((buffer == NULL) || (format == NULL) || (bufSize < length)) {
217 return iRet;
218 }
219
220 va_start(var_args, format);
221
222 iRet = vsnprintf(buffer, length, format, var_args);
223
224 va_end(var_args);
225
226 return iRet;
227 }
228
GENOS_SecureVStringPrint(PCHAR buffer,SIZE_T bufSize,SIZE_T length,const PCCHAR format,va_list var_args)229 GENOS_STATUS GENOS_SecureVStringPrint(PCHAR buffer, SIZE_T bufSize,
230 SIZE_T length, const PCCHAR format,
231 va_list var_args)
232 {
233 if ((buffer == NULL) || (format == NULL) || (bufSize < length)) {
234 return GENOS_STATUS_INVALID_PARAMETER;
235 }
236
237 vsnprintf(buffer, length, format, var_args);
238
239 return GENOS_STATUS_SUCCESS;
240 }
241
GENOS_CloseHandle(HANDLE hObject)242 BOOL GENOS_CloseHandle(HANDLE hObject)
243 {
244 BOOL iRet = FALSE;
245
246 if (hObject != 0) {
247 close((INT32) hObject);
248 iRet = TRUE;
249 }
250
251 return iRet;
252 }
253
GENOS_LoadLibrary(const PCCHAR lpLibFileName,PHMODULE phModule)254 GENOS_STATUS GENOS_LoadLibrary(const PCCHAR lpLibFileName, PHMODULE phModule)
255 {
256 if (lpLibFileName == NULL) {
257 return GENOS_STATUS_INVALID_PARAMETER;
258 }
259
260 *phModule = dlopen((const PCHAR)lpLibFileName, RTLD_LAZY);
261
262 return ((*phModule !=
263 NULL) ? GENOS_STATUS_SUCCESS :
264 GENOS_STATUS_LOAD_LIBRARY_FAILED);
265 }
266
GENOS_FreeLibrary(HMODULE hLibModule)267 BOOL GENOS_FreeLibrary(HMODULE hLibModule)
268 {
269 UINT32 iRet = 10;
270
271 if (hLibModule != NULL) {
272 iRet = dlclose(hLibModule);
273 }
274 return (iRet == 0) ? TRUE : FALSE;
275 }
276
GENOS_GetProcAddress(HMODULE hModule,PCCHAR lpProcName)277 PVOID GENOS_GetProcAddress(HMODULE hModule, PCCHAR lpProcName)
278 {
279 PVOID pSym = NULL;
280
281 if (hModule == NULL || lpProcName == NULL) {
282 GENOS_OS_ASSERTMESSAGE("Invalid parameter.");
283 } else {
284 pSym = dlsym(hModule, lpProcName);
285 }
286
287 return pSym;
288 }
289
GENOS_QueryPerformanceFrequency(PUINT64 pFrequency)290 BOOL GENOS_QueryPerformanceFrequency(PUINT64 pFrequency)
291 {
292 struct timespec Res;
293 INT32 iRet;
294
295 if (pFrequency == NULL) {
296 return FALSE;
297 }
298
299 if ((iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0) {
300 return FALSE;
301 }
302 if (Res.tv_sec != 0) {
303 return FALSE;
304 }
305 *pFrequency = (UINT64) ((1000 * 1000 * 1000) / Res.tv_nsec);
306
307 return TRUE;
308 }
309
GENOS_QueryPerformanceCounter(PUINT64 pPerformanceCount)310 BOOL GENOS_QueryPerformanceCounter(PUINT64 pPerformanceCount)
311 {
312 struct timespec Res;
313 struct timespec t;
314 INT32 iRet;
315
316 if (pPerformanceCount == NULL) {
317 return FALSE;
318 }
319 if ((iRet = clock_getres(CLOCK_MONOTONIC, &Res)) != 0) {
320 return FALSE;
321 }
322 if (Res.tv_sec != 0) {
323 return FALSE;
324 }
325 if ((iRet = clock_gettime(CLOCK_MONOTONIC, &t)) != 0) {
326 return FALSE;
327 }
328 *pPerformanceCount =
329 (UINT64) ((1000 * 1000 * 1000 * t.tv_sec +
330 t.tv_nsec) / Res.tv_nsec);
331
332 return TRUE;
333 }
334
GENOS_Sleep(UINT32 mSec)335 VOID GENOS_Sleep(UINT32 mSec)
336 {
337 usleep(1000 * mSec);
338 }
339
GENOS_CreateThread(PVOID ThreadFunction,PVOID ThreadData)340 GENOS_THREADHANDLE GENOS_CreateThread(PVOID ThreadFunction, PVOID ThreadData)
341 {
342 GENOS_THREADHANDLE Thread;
343
344 if (0 !=
345 pthread_create(&Thread, NULL, (VOID * (*)(PVOID)) ThreadFunction,
346 ThreadData)) {
347 Thread = 0;
348 }
349
350 return Thread;
351 }
352
GENOS_CreateMutex()353 PGENOS_MUTEX GENOS_CreateMutex()
354 {
355 PGENOS_MUTEX pMutex;
356
357 pMutex = (PGENOS_MUTEX) GENOS_AllocMemory(sizeof(*pMutex));
358 if (pMutex != NULL) {
359 if (pthread_mutex_init(pMutex, NULL)) {
360 pMutex = NULL;
361 }
362 }
363
364 return pMutex;
365 }
366
GENOS_DestroyMutex(PGENOS_MUTEX pMutex)367 HRESULT GENOS_DestroyMutex(PGENOS_MUTEX pMutex)
368 {
369 HRESULT hr = S_OK;
370
371 if (pMutex) {
372 if (pthread_mutex_destroy(pMutex)) {
373 hr = E_FAIL;
374 }
375 GENOS_FreeMemory(pMutex);
376 }
377
378 return hr;
379 }
380
GENOS_LockMutex(PGENOS_MUTEX pMutex)381 HRESULT GENOS_LockMutex(PGENOS_MUTEX pMutex)
382 {
383 HRESULT hr = S_OK;
384
385 if (pthread_mutex_lock(pMutex)) {
386 hr = E_FAIL;
387 }
388
389 return hr;
390 }
391
GENOS_UnlockMutex(PGENOS_MUTEX pMutex)392 HRESULT GENOS_UnlockMutex(PGENOS_MUTEX pMutex)
393 {
394 HRESULT hr = S_OK;
395
396 if (pthread_mutex_unlock(pMutex)) {
397 hr = E_FAIL;
398 }
399
400 return hr;
401 }
402
GENOS_CreateSemaphore(UINT uiInitialCount,UINT uiMaximumCount)403 PGENOS_SEMAPHORE GENOS_CreateSemaphore(UINT uiInitialCount, UINT uiMaximumCount)
404 {
405 PGENOS_SEMAPHORE pSemaphore = NULL;
406
407 pSemaphore = (PGENOS_SEMAPHORE) GENOS_AllocMemory(sizeof(*pSemaphore));
408 if (sem_init(pSemaphore, 0, uiInitialCount)) {
409 pSemaphore = NULL;
410 }
411
412 return pSemaphore;
413 }
414
GENOS_DestroySemaphore(PGENOS_SEMAPHORE pSemaphore)415 HRESULT GENOS_DestroySemaphore(PGENOS_SEMAPHORE pSemaphore)
416 {
417 GENOS_SafeFreeMemory(pSemaphore);
418
419 return S_OK;
420 }
421
GENOS_WaitSemaphore(PGENOS_SEMAPHORE pSemaphore,UINT uiMilliseconds)422 HRESULT GENOS_WaitSemaphore(PGENOS_SEMAPHORE pSemaphore, UINT uiMilliseconds)
423 {
424 HRESULT hr = S_OK;
425
426 if (uiMilliseconds == INFINITE) {
427 if (sem_wait(pSemaphore)) {
428 hr = E_FAIL;
429 }
430 } else {
431 struct timespec time = {
432 (LONG) uiMilliseconds / 1000000,
433 ((LONG) uiMilliseconds % 1000000) * 1000
434 };
435
436 if (sem_timedwait(pSemaphore, &time)) {
437 hr = E_FAIL;
438 }
439 }
440
441 return hr;
442 }
443
GENOS_PostSemaphore(PGENOS_SEMAPHORE pSemaphore,UINT uiPostCount)444 HRESULT GENOS_PostSemaphore(PGENOS_SEMAPHORE pSemaphore, UINT uiPostCount)
445 {
446 HRESULT hr = S_OK;
447
448 if (uiPostCount > 0) {
449 while (uiPostCount--) {
450 if (sem_post(pSemaphore)) {
451 hr = E_FAIL;
452 break;
453 }
454 }
455 } else {
456 hr = E_FAIL;
457 }
458
459 return hr;
460 }
461
GENOS_StatusToOsResult(GENOS_STATUS eStatus)462 VAStatus GENOS_StatusToOsResult(GENOS_STATUS eStatus)
463 {
464 switch (eStatus) {
465 case GENOS_STATUS_SUCCESS:
466 return VA_STATUS_SUCCESS;
467 case GENOS_STATUS_NO_SPACE:
468 return VA_STATUS_ERROR_ALLOCATION_FAILED;
469 case GENOS_STATUS_INVALID_PARAMETER:
470 return VA_STATUS_ERROR_INVALID_PARAMETER;
471 case GENOS_STATUS_INVALID_HANDLE:
472 return VA_STATUS_ERROR_INVALID_BUFFER;
473 case GENOS_STATUS_NULL_POINTER:
474 return VA_STATUS_ERROR_INVALID_CONTEXT;
475 default:
476 return VA_STATUS_ERROR_OPERATION_FAILED;
477 }
478
479 return VA_STATUS_ERROR_OPERATION_FAILED;
480 }
481
OsResultToGENOS_Status(VAStatus eResult)482 GENOS_STATUS OsResultToGENOS_Status(VAStatus eResult)
483 {
484 switch (eResult) {
485 case VA_STATUS_SUCCESS:
486 return GENOS_STATUS_SUCCESS;
487 case VA_STATUS_ERROR_ALLOCATION_FAILED:
488 return GENOS_STATUS_NO_SPACE;
489 case VA_STATUS_ERROR_INVALID_PARAMETER:
490 return GENOS_STATUS_INVALID_PARAMETER;
491 case VA_STATUS_ERROR_INVALID_BUFFER:
492 return GENOS_STATUS_INVALID_HANDLE;
493 case VA_STATUS_ERROR_INVALID_CONTEXT:
494 return GENOS_STATUS_NULL_POINTER;
495 default:
496 return GENOS_STATUS_UNKNOWN;
497 }
498
499 return GENOS_STATUS_UNKNOWN;
500 }
501