• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 /*****************************************************************************/
19 /*                                                                           */
20 /*  File Name         : ithread.c                                            */
21 /*                                                                           */
22 /*  Description       : Contains abstraction for threads, mutex and semaphores*/
23 /*                                                                           */
24 /*  List of Functions :                                                      */
25 /*                                                                           */
26 /*  Issues / Problems : None                                                 */
27 /*                                                                           */
28 /*  Revision History  :                                                      */
29 /*                                                                           */
30 /*         DD MM YYYY   Author(s)       Changes                              */
31 /*         07 09 2012   Harish          Initial Version                      */
32 /*****************************************************************************/
33 /*****************************************************************************/
34 /* File Includes                                                             */
35 /*****************************************************************************/
36 #include <string.h>
37 #include "ihevc_typedefs.h"
38 #include "ithread.h"
39 #include <sys/types.h>
40 
41 #ifndef X86_MSVC
42 //#define PTHREAD_AFFINITY
43 //#define SYSCALL_AFFINITY
44 
45 #ifdef PTHREAD_AFFINITY
46 #define _GNU_SOURCE
47 #define __USE_GNU
48 #endif
49 
50 #include <pthread.h>
51 #include <sched.h>
52 #include <semaphore.h>
53 #include <unistd.h>
54 
55 
56 #endif
57 
58 
59 
60 
61 #ifdef X86_MSVC
62 
63 #include <windows.h>
64 #define SEM_MAX_COUNT       100
65 #define SEM_INCREMENT_COUNT 1
66 
ithread_get_handle_size(void)67 UWORD32 ithread_get_handle_size(void)
68 {
69     return (sizeof(HANDLE));
70 }
71 
ithread_get_mutex_lock_size(void)72 UWORD32 ithread_get_mutex_lock_size(void)
73 {
74     return (sizeof(HANDLE));
75 }
76 
ithread_create(void * thread_handle,void * attribute,void * strt,void * argument)77 WORD32 ithread_create(void *thread_handle, void *attribute, void *strt, void *argument)
78 {
79     HANDLE *ppv_thread_handle;
80     HANDLE thread_handle_value;
81 
82     if(0 == thread_handle)
83         return -1;
84 
85     ppv_thread_handle = (HANDLE *)thread_handle;
86     thread_handle_value = (void *)CreateThread
87                     (NULL,                              /* Attributes      */
88                      1024 * 128,                        /* Stack size      */
89                      (LPTHREAD_START_ROUTINE)strt,      /* Thread function */
90                      argument,                          /* Parameters      */
91                      0,                                 /* Creation flags  */
92                      NULL);                             /* Thread ID       */
93     *ppv_thread_handle = (HANDLE)thread_handle_value;
94 
95     return 0;
96 }
97 
ithread_join(void * thread_handle,void ** val_ptr)98 WORD32 ithread_join(void *thread_handle, void **val_ptr)
99 {
100     HANDLE *ppv_thread_handle;
101     HANDLE thread_handle_value;
102 
103     if(0 == thread_handle)
104         return -1;
105 
106     ppv_thread_handle = (HANDLE *)thread_handle;
107     thread_handle_value = *ppv_thread_handle;
108 
109     if(WAIT_OBJECT_0 == WaitForSingleObject(thread_handle_value, INFINITE))
110     {
111         CloseHandle(thread_handle_value);
112     }
113 
114     return 0;
115 }
116 
ithread_exit(void * thread_handle)117 void ithread_exit(void *thread_handle)
118 {
119     HANDLE *ppv_thread_handle;
120     HANDLE thread_handle_value;
121     DWORD thread_exit_code;
122 
123     if(0 == thread_handle)
124         return;
125 
126     ppv_thread_handle = (HANDLE *)thread_handle;
127     thread_handle_value = *ppv_thread_handle;
128     /* Get exit code for thread. If the return value is 0, means thread is busy */
129     if(0 != GetExitCodeThread(thread_handle_value, &thread_exit_code))
130     {
131         TerminateThread(thread_handle_value, thread_exit_code);
132     }
133 
134     return;
135 }
136 
ithread_get_mutex_struct_size(void)137 WORD32 ithread_get_mutex_struct_size(void)
138 {
139     return (sizeof(HANDLE));
140 }
141 
ithread_mutex_init(void * mutex)142 WORD32 ithread_mutex_init(void *mutex)
143 {
144     HANDLE *ppv_mutex_handle;
145     HANDLE mutex_handle_value;
146 
147     if(0 == mutex)
148         return -1;
149 
150     ppv_mutex_handle = (HANDLE *)mutex;
151     mutex_handle_value = CreateSemaphore(NULL, 1, 1, NULL);
152     *ppv_mutex_handle = mutex_handle_value;
153     return 0;
154 }
155 
ithread_mutex_destroy(void * mutex)156 WORD32 ithread_mutex_destroy(void *mutex)
157 {
158     HANDLE *ppv_mutex_handle;
159     HANDLE mutex_handle_value;
160 
161     if(0 == mutex)
162         return -1;
163 
164     ppv_mutex_handle = (HANDLE *)mutex;
165     mutex_handle_value = *ppv_mutex_handle;
166     CloseHandle(mutex_handle_value);
167     return 0;
168 }
169 
ithread_mutex_lock(void * mutex)170 WORD32 ithread_mutex_lock(void *mutex)
171 {
172     HANDLE *ppv_mutex_handle;
173     HANDLE mutex_handle_value;
174     DWORD  result = 0;
175 
176     if(0 == mutex)
177         return -1;
178 
179     ppv_mutex_handle = (HANDLE *)mutex;
180     mutex_handle_value = *ppv_mutex_handle;
181     result = WaitForSingleObject(mutex_handle_value, INFINITE);
182 
183     if(WAIT_OBJECT_0 == result)
184         return 0;
185 
186     return 1;
187 
188 }
189 
ithread_mutex_unlock(void * mutex)190 WORD32 ithread_mutex_unlock(void *mutex)
191 {
192     HANDLE *ppv_mutex_handle;
193     HANDLE mutex_handle_value;
194     DWORD  result = 0;
195 
196     if(0 == mutex)
197         return -1;
198 
199     ppv_mutex_handle = (HANDLE *)mutex;
200     mutex_handle_value = *ppv_mutex_handle;
201     result = ReleaseSemaphore(mutex_handle_value, 1, NULL);
202 
203     if(0 == result)
204         return -1;
205 
206     return 0;
207 }
208 
ithread_yield(void)209 void ithread_yield(void) { }
210 
ithread_usleep(UWORD32 u4_time_us)211 void ithread_usleep(UWORD32 u4_time_us)
212 {
213     UWORD32 u4_time_ms = u4_time_us / 1000;
214     Sleep(u4_time_ms);
215 }
216 
ithread_msleep(UWORD32 u4_time_ms)217 void ithread_msleep(UWORD32 u4_time_ms)
218 {
219     Sleep(u4_time_ms);
220 }
221 
222 
ithread_sleep(UWORD32 u4_time)223 void ithread_sleep(UWORD32 u4_time)
224 {
225     UWORD32 u4_time_ms = u4_time * 1000;
226     Sleep(u4_time_ms);
227 }
228 
ithread_get_sem_struct_size(void)229 UWORD32 ithread_get_sem_struct_size(void)
230 {
231     return (sizeof(HANDLE));
232 }
233 
ithread_sem_init(void * sem,WORD32 pshared,UWORD32 value)234 WORD32 ithread_sem_init(void *sem, WORD32 pshared, UWORD32 value)
235 {
236     HANDLE *sem_handle = (HANDLE *)sem;
237     HANDLE sem_handle_value;
238 
239     if(0 == sem)
240         return -1;
241 
242     sem_handle_value = CreateSemaphore(NULL,  /* Security Attribute*/
243                                        value,  /* Initial count     */
244                                        SEM_MAX_COUNT, /* Max value         */
245                                        NULL);        /* Name, not used    */
246     *sem_handle = sem_handle_value;
247     return 0;
248 }
249 
ithread_sem_post(void * sem)250 WORD32 ithread_sem_post(void *sem)
251 {
252     HANDLE *sem_handle = (HANDLE *)sem;
253     HANDLE sem_handle_value;
254 
255     if(0 == sem)
256         return -1;
257 
258     sem_handle_value = *sem_handle;
259 
260     /* Post on Semaphore by releasing the lock on mutex */
261     if(ReleaseSemaphore(sem_handle_value, SEM_INCREMENT_COUNT, NULL))
262         return 0;
263 
264     return -1;
265 }
266 
ithread_sem_wait(void * sem)267 WORD32 ithread_sem_wait(void *sem)
268 {
269     DWORD          result = 0;
270     HANDLE *sem_handle = (HANDLE *)sem;
271     HANDLE sem_handle_value;
272 
273     if(0 == sem)
274         return -1;
275 
276     sem_handle_value = *sem_handle;
277 
278     /* Wait on Semaphore object infinitly */
279     result = WaitForSingleObject(sem_handle_value, INFINITE);
280 
281     /* If lock on semaphore is acquired, return SUCCESS */
282     if(WAIT_OBJECT_0 == result)
283         return 0;
284 
285     /* If call timeouts, return FAILURE */
286     if(WAIT_TIMEOUT == result)
287         return -1;
288 
289     return 0;
290 }
291 
ithread_sem_destroy(void * sem)292 WORD32 ithread_sem_destroy(void *sem)
293 {
294     HANDLE *sem_handle = (HANDLE *)sem;
295     HANDLE sem_handle_value;
296 
297     if(0 == sem)
298         return -1;
299 
300     sem_handle_value = *sem_handle;
301 
302     if(FALSE == CloseHandle(sem_handle_value))
303     {
304         return -1;
305     }
306     return 0;
307 }
308 
ithread_set_affinity(WORD32 core_id)309 WORD32 ithread_set_affinity(WORD32 core_id)
310 {
311     return 1;
312 }
313 
314 #else
ithread_get_handle_size(void)315 UWORD32 ithread_get_handle_size(void)
316 {
317     return sizeof(pthread_t);
318 }
319 
ithread_get_mutex_lock_size(void)320 UWORD32 ithread_get_mutex_lock_size(void)
321 {
322     return sizeof(pthread_mutex_t);
323 }
324 
325 
ithread_create(void * thread_handle,void * attribute,void * strt,void * argument)326 WORD32 ithread_create(void *thread_handle, void *attribute, void *strt, void *argument)
327 {
328     return pthread_create((pthread_t *)thread_handle, attribute, (void * (*)(void *))strt, argument);
329 }
330 
ithread_join(void * thread_handle,void ** val_ptr)331 WORD32 ithread_join(void *thread_handle, void **val_ptr)
332 {
333     pthread_t *pthread_handle   = (pthread_t *)thread_handle;
334     return pthread_join(*pthread_handle, val_ptr);
335 }
336 
ithread_exit(void * val_ptr)337 void ithread_exit(void *val_ptr)
338 {
339     return pthread_exit(val_ptr);
340 }
341 
ithread_get_mutex_struct_size(void)342 WORD32 ithread_get_mutex_struct_size(void)
343 {
344     return (sizeof(pthread_mutex_t));
345 }
ithread_mutex_init(void * mutex)346 WORD32 ithread_mutex_init(void *mutex)
347 {
348     return pthread_mutex_init((pthread_mutex_t *)mutex, NULL);
349 }
350 
ithread_mutex_destroy(void * mutex)351 WORD32 ithread_mutex_destroy(void *mutex)
352 {
353     return pthread_mutex_destroy((pthread_mutex_t *)mutex);
354 }
355 
ithread_mutex_lock(void * mutex)356 WORD32 ithread_mutex_lock(void *mutex)
357 {
358     return pthread_mutex_lock((pthread_mutex_t *)mutex);
359 }
360 
ithread_mutex_unlock(void * mutex)361 WORD32 ithread_mutex_unlock(void *mutex)
362 {
363     return pthread_mutex_unlock((pthread_mutex_t *)mutex);
364 }
365 
ithread_yield(void)366 void ithread_yield(void)
367 {
368     sched_yield();
369 }
370 
ithread_sleep(UWORD32 u4_time)371 void ithread_sleep(UWORD32 u4_time)
372 {
373     usleep(u4_time * 1000 * 1000);
374 }
375 
ithread_msleep(UWORD32 u4_time_ms)376 void ithread_msleep(UWORD32 u4_time_ms)
377 {
378     usleep(u4_time_ms * 1000);
379 }
380 
ithread_usleep(UWORD32 u4_time_us)381 void ithread_usleep(UWORD32 u4_time_us)
382 {
383     usleep(u4_time_us);
384 }
385 
ithread_get_sem_struct_size(void)386 UWORD32 ithread_get_sem_struct_size(void)
387 {
388     return (sizeof(sem_t));
389 }
390 
391 
ithread_sem_init(void * sem,WORD32 pshared,UWORD32 value)392 WORD32 ithread_sem_init(void *sem, WORD32 pshared, UWORD32 value)
393 {
394     return sem_init((sem_t *)sem, pshared, value);
395 }
396 
ithread_sem_post(void * sem)397 WORD32 ithread_sem_post(void *sem)
398 {
399     return sem_post((sem_t *)sem);
400 }
401 
402 
ithread_sem_wait(void * sem)403 WORD32 ithread_sem_wait(void *sem)
404 {
405     return sem_wait((sem_t *)sem);
406 }
407 
408 
ithread_sem_destroy(void * sem)409 WORD32 ithread_sem_destroy(void *sem)
410 {
411     return sem_destroy((sem_t *)sem);
412 }
413 
414 
ithread_set_affinity(WORD32 core_id)415 WORD32 ithread_set_affinity(WORD32 core_id)
416 {
417 
418 #ifdef PTHREAD_AFFINITY
419     cpu_set_t cpuset;
420     int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
421     pthread_t cur_thread = pthread_self();
422 
423     if(core_id >= num_cores)
424         return -1;
425 
426     CPU_ZERO(&cpuset);
427     CPU_SET(core_id, &cpuset);
428 
429     return pthread_setaffinity_np(cur_thread, sizeof(cpu_set_t), &cpuset);
430 
431 #elif SYSCALL_AFFINITY
432     WORD32 i4_sys_res;
433 
434     pid_t pid = gettid();
435 
436 
437     i4_sys_res = syscall(__NR_sched_setaffinity, pid, sizeof(i4_mask), &i4_mask);
438     if(i4_sys_res)
439     {
440         //WORD32 err;
441         //err = errno;
442         //perror("Error in setaffinity syscall PERROR : ");
443         //LOG_ERROR("Error in the syscall setaffinity: mask=0x%x err=0x%x", i4_mask, i4_sys_res);
444         return -1;
445     }
446 #endif
447 
448     return core_id;
449 
450 }
451 #endif
452