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