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 "iv_datatypedef.h"
40 #include "ithread.h"
41 #include <sys/types.h>
42
43 //#define PTHREAD_AFFINITY
44 //#define SYSCALL_AFFINITY
45
46 #ifdef PTHREAD_AFFINITY
47 #define _GNU_SOURCE
48 #define __USE_GNU
49 #endif
50
51 #include <pthread.h>
52 #include <sched.h>
53 #include <semaphore.h>
54 #include <unistd.h>
55
56 #ifdef SYSCALL_AFFINITY
57 #include <sys/syscall.h>
58 #endif
59
ithread_get_handle_size(void)60 UWORD32 ithread_get_handle_size(void)
61 {
62 return sizeof(pthread_t);
63 }
64
ithread_get_mutex_lock_size(void)65 UWORD32 ithread_get_mutex_lock_size(void)
66 {
67 return sizeof(pthread_mutex_t);
68 }
69
ithread_create(void * thread_handle,void * attribute,void * strt,void * argument)70 WORD32 ithread_create(void *thread_handle, void *attribute, void *strt, void *argument)
71 {
72 ((void)(attribute));
73 return pthread_create((pthread_t *)thread_handle, NULL,(void *(*)(void *)) strt, argument);
74 }
75
ithread_join(void * thread_handle,void ** val_ptr)76 WORD32 ithread_join(void *thread_handle, void ** val_ptr)
77 {
78 pthread_t *pthread_handle = (pthread_t *)thread_handle;
79 ((void)(val_ptr));
80 return pthread_join(*pthread_handle, NULL);
81 }
82
ithread_exit(void * val_ptr)83 void ithread_exit(void *val_ptr)
84 {
85 return pthread_exit(val_ptr);
86 }
87
ithread_get_mutex_struct_size(void)88 WORD32 ithread_get_mutex_struct_size(void)
89 {
90 return(sizeof(pthread_mutex_t));
91 }
ithread_mutex_init(void * mutex)92 WORD32 ithread_mutex_init(void *mutex)
93 {
94 return pthread_mutex_init((pthread_mutex_t *) mutex, NULL);
95 }
96
ithread_mutex_destroy(void * mutex)97 WORD32 ithread_mutex_destroy(void *mutex)
98 {
99 return pthread_mutex_destroy((pthread_mutex_t *) mutex);
100 }
101
ithread_mutex_lock(void * mutex)102 WORD32 ithread_mutex_lock(void *mutex)
103 {
104 return pthread_mutex_lock((pthread_mutex_t *)mutex);
105 }
106
ithread_mutex_unlock(void * mutex)107 WORD32 ithread_mutex_unlock(void *mutex)
108 {
109 return pthread_mutex_unlock((pthread_mutex_t *)mutex);
110 }
111
ithread_yield(void)112 void ithread_yield(void)
113 {
114 sched_yield();
115 }
116
ithread_sleep(UWORD32 u4_time)117 void ithread_sleep(UWORD32 u4_time)
118 {
119 usleep(u4_time * 1000 * 1000);
120 }
121
ithread_msleep(UWORD32 u4_time_ms)122 void ithread_msleep(UWORD32 u4_time_ms)
123 {
124 usleep(u4_time_ms * 1000);
125 }
126
ithread_usleep(UWORD32 u4_time_us)127 void ithread_usleep(UWORD32 u4_time_us)
128 {
129 usleep(u4_time_us);
130 }
131
ithread_get_sem_struct_size(void)132 UWORD32 ithread_get_sem_struct_size(void)
133 {
134 return(sizeof(sem_t));
135 }
136
ithread_sem_init(void * sem,WORD32 pshared,UWORD32 value)137 WORD32 ithread_sem_init(void *sem,WORD32 pshared,UWORD32 value)
138 {
139 return sem_init((sem_t *)sem,pshared,value);
140 }
141
ithread_sem_post(void * sem)142 WORD32 ithread_sem_post(void *sem)
143 {
144 return sem_post((sem_t *)sem);
145 }
146
ithread_sem_wait(void * sem)147 WORD32 ithread_sem_wait(void *sem)
148 {
149 return sem_wait((sem_t *)sem);
150 }
151
ithread_sem_destroy(void * sem)152 WORD32 ithread_sem_destroy(void *sem)
153 {
154 return sem_destroy((sem_t *)sem);
155 }
156
ithread_set_affinity(WORD32 core_id)157 WORD32 ithread_set_affinity(WORD32 core_id)
158 {
159 #ifdef PTHREAD_AFFINITY
160 cpu_set_t cpuset;
161 int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
162 pthread_t cur_thread = pthread_self();
163
164 if (core_id >= num_cores)
165 return -1;
166
167 CPU_ZERO(&cpuset);
168 CPU_SET(core_id, &cpuset);
169
170 return pthread_setaffinity_np(cur_thread, sizeof(cpu_set_t), &cpuset);
171
172 #elif SYSCALL_AFFINITY
173 WORD32 i4_sys_res;
174
175 pid_t pid = gettid();
176
177
178 i4_sys_res = syscall(__NR_sched_setaffinity, pid, sizeof(i4_mask), &i4_mask);
179 if (i4_sys_res)
180 {
181 //WORD32 err;
182 //err = errno;
183 //perror("Error in setaffinity syscall PERROR : ");
184 //LOG_ERROR("Error in the syscall setaffinity: mask=0x%x err=0x%x", i4_mask, i4_sys_res);
185 return -1;
186 }
187 #endif
188 ((void)(core_id));
189 return 1;
190
191 }
192