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
66UWORD32 ithread_get_handle_size(void)
67{
68    return sizeof(pthread_t);
69}
70
71UWORD32 ithread_get_mutex_lock_size(void)
72{
73    return sizeof(pthread_mutex_t);
74}
75
76
77WORD32 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
83WORD32 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
90WORD32 ithread_get_mutex_struct_size(void)
91{
92    return(sizeof(pthread_mutex_t));
93}
94WORD32 ithread_mutex_init(void *mutex)
95{
96    return pthread_mutex_init((pthread_mutex_t *) mutex, NULL);
97}
98
99WORD32 ithread_mutex_destroy(void *mutex)
100{
101    return pthread_mutex_destroy((pthread_mutex_t *) mutex);
102}
103
104WORD32 ithread_mutex_lock(void *mutex)
105{
106    return pthread_mutex_lock((pthread_mutex_t *)mutex);
107}
108
109WORD32 ithread_mutex_unlock(void *mutex)
110{
111    return pthread_mutex_unlock((pthread_mutex_t *)mutex);
112}
113
114void ithread_yield(void)
115{
116    sched_yield();
117}
118
119void ithread_sleep(UWORD32 u4_time)
120{
121    usleep(u4_time * 1000 * 1000);
122}
123
124void ithread_msleep(UWORD32 u4_time_ms)
125{
126    usleep(u4_time_ms * 1000);
127}
128
129void ithread_usleep(UWORD32 u4_time_us)
130{
131    usleep(u4_time_us);
132}
133
134UWORD32 ithread_get_sem_struct_size(void)
135{
136    return(sizeof(sem_t));
137}
138
139
140WORD32 ithread_sem_init(void *sem,WORD32 pshared,UWORD32 value)
141{
142    return sem_init((sem_t *)sem,pshared,value);
143}
144
145WORD32 ithread_sem_post(void *sem)
146{
147    return sem_post((sem_t *)sem);
148}
149
150
151WORD32 ithread_sem_wait(void *sem)
152{
153    return sem_wait((sem_t *)sem);
154}
155
156
157WORD32 ithread_sem_destroy(void *sem)
158{
159    return sem_destroy((sem_t *)sem);
160}
161
162void 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}
175WORD32 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