1 /******************************************************************************
2  *
3  * Copyright (C) 2015 The Android Open Source Project
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  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*****************************************************************************/
21 /*                                                                           */
22 /*  File Name         : ithread.c                                            */
23 /*                                                                           */
24 /*  Description       : Contains abstraction for threads, mutex and semaphores*/
25 /*                                                                           */
26 /*  List of Functions :                                                      */
27 /*                                                                           */
28 /*  Issues / Problems : None                                                 */
29 /*                                                                           */
30 /*  Revision History  :                                                      */
31 /*                                                                           */
32 /*         DD MM YYYY   Author(s)       Changes                              */
33 /*         07 09 2012   Harish          Initial Version                      */
34 /*****************************************************************************/
35 /*****************************************************************************/
36 /* File Includes                                                             */
37 /*****************************************************************************/
38 #include <string.h>
39 #include "ih264_typedefs.h"
40 
41 
42 
43 #include "ithread.h"
44 #include <sys/types.h>
45 
46 
47 #define UNUSED(x) ((void)(x))
48 
49 //#define PTHREAD_AFFINITY
50 //#define SYSCALL_AFFINITY
51 
52 #ifdef PTHREAD_AFFINITY
53 #define _GNU_SOURCE
54 #define __USE_GNU
55 #endif
56 
57 #include <pthread.h>
58 #include <sched.h>
59 #include <semaphore.h>
60 #include <unistd.h>
61 #ifdef PTHREAD_AFFINITY
62 #include <sys/prctl.h>
63 #endif
64 
65 
ithread_get_handle_size(void)66 UWORD32 ithread_get_handle_size(void)
67 {
68     return sizeof(pthread_t);
69 }
70 
ithread_get_mutex_lock_size(void)71 UWORD32 ithread_get_mutex_lock_size(void)
72 {
73     return sizeof(pthread_mutex_t);
74 }
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     UNUSED(attribute);
80     return pthread_create((pthread_t *)thread_handle, NULL,(void *(*)(void *)) strt, argument);
81 }
82 
ithread_join(void * thread_handle,void ** val_ptr)83 WORD32 ithread_join(void *thread_handle, void ** val_ptr)
84 {
85     UNUSED(val_ptr);
86     pthread_t *pthread_handle   = (pthread_t *)thread_handle;
87     return pthread_join(*pthread_handle, NULL);
88 }
89 
ithread_get_mutex_struct_size(void)90 WORD32 ithread_get_mutex_struct_size(void)
91 {
92     return(sizeof(pthread_mutex_t));
93 }
ithread_mutex_init(void * mutex)94 WORD32 ithread_mutex_init(void *mutex)
95 {
96     return pthread_mutex_init((pthread_mutex_t *) mutex, NULL);
97 }
98 
ithread_mutex_destroy(void * mutex)99 WORD32 ithread_mutex_destroy(void *mutex)
100 {
101     return pthread_mutex_destroy((pthread_mutex_t *) mutex);
102 }
103 
ithread_mutex_lock(void * mutex)104 WORD32 ithread_mutex_lock(void *mutex)
105 {
106     return pthread_mutex_lock((pthread_mutex_t *)mutex);
107 }
108 
ithread_mutex_unlock(void * mutex)109 WORD32 ithread_mutex_unlock(void *mutex)
110 {
111     return pthread_mutex_unlock((pthread_mutex_t *)mutex);
112 }
113 
ithread_yield(void)114 void ithread_yield(void)
115 {
116     sched_yield();
117 }
118 
ithread_sleep(UWORD32 u4_time)119 void ithread_sleep(UWORD32 u4_time)
120 {
121     usleep(u4_time * 1000 * 1000);
122 }
123 
ithread_msleep(UWORD32 u4_time_ms)124 void ithread_msleep(UWORD32 u4_time_ms)
125 {
126     usleep(u4_time_ms * 1000);
127 }
128 
ithread_usleep(UWORD32 u4_time_us)129 void ithread_usleep(UWORD32 u4_time_us)
130 {
131     usleep(u4_time_us);
132 }
133 
ithread_get_sem_struct_size(void)134 UWORD32 ithread_get_sem_struct_size(void)
135 {
136     return(sizeof(sem_t));
137 }
138 
139 
ithread_sem_init(void * sem,WORD32 pshared,UWORD32 value)140 WORD32 ithread_sem_init(void *sem,WORD32 pshared,UWORD32 value)
141 {
142     return sem_init((sem_t *)sem,pshared,value);
143 }
144 
ithread_sem_post(void * sem)145 WORD32 ithread_sem_post(void *sem)
146 {
147     return sem_post((sem_t *)sem);
148 }
149 
150 
ithread_sem_wait(void * sem)151 WORD32 ithread_sem_wait(void *sem)
152 {
153     return sem_wait((sem_t *)sem);
154 }
155 
156 
ithread_sem_destroy(void * sem)157 WORD32 ithread_sem_destroy(void *sem)
158 {
159     return sem_destroy((sem_t *)sem);
160 }
161 
ithread_set_name(CHAR * pc_thread_name)162 void ithread_set_name(CHAR *pc_thread_name)
163 {
164 
165 #ifndef WIN32
166 #ifndef QNX
167 #ifndef IOS
168     UNUSED(pc_thread_name);
169 //prctl(PR_SET_NAME, (unsigned long)pu1_thread_name, 0, 0, 0);
170 #endif
171 #endif
172 #endif
173 
174 }
ithread_set_affinity(WORD32 core_id)175 WORD32 ithread_set_affinity(WORD32 core_id)
176 {
177 #ifdef PTHREAD_AFFINITY
178     cpu_set_t cpuset;
179     int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
180     pthread_t cur_thread = pthread_self();
181 
182     if (core_id >= num_cores)
183         return -1;
184 
185     CPU_ZERO(&cpuset);
186     CPU_SET(core_id, &cpuset);
187 
188     return pthread_setaffinity_np(cur_thread, sizeof(cpu_set_t), &cpuset);
189 
190 #elif SYSCALL_AFFINITY
191     WORD32 i4_sys_res;
192     UNUSED(core_id);
193 
194     pid_t pid = gettid();
195 
196 
197     i4_sys_res = syscall(__NR_sched_setaffinity, pid, sizeof(i4_mask), &i4_mask);
198     if (i4_sys_res)
199     {
200         //WORD32 err;
201         //err = errno;
202         //perror("Error in setaffinity syscall PERROR : ");
203         //LOG_ERROR("Error in the syscall setaffinity: mask=0x%x err=0x%x", i4_mask, i4_sys_res);
204         return -1;
205     }
206 #else
207     UNUSED(core_id);
208 #endif
209     return 1;
210 
211 }
212