blob: 6c7182d1c92e0c3415ade5526b3a42d354722c7a [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 2009-2012 Broadcom Corporation
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**
21** Name gki_linux_pthreads.c
22**
23** Function pthreads version of Linux GKI. This version is used for
24** settop projects that already use pthreads and not pth.
25**
26*****************************************************************************/
27
Sharvil Nanavati10aecea2014-05-28 17:09:46 -070028#include <assert.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080029#include <sys/times.h>
30
The Android Open Source Project5738f832012-12-12 16:00:35 -080031#include "gki_int.h"
32#include "bt_utils.h"
33
34#define LOG_TAG "GKI_LINUX"
35
36#include <utils/Log.h>
Sharvil Nanavati10aecea2014-05-28 17:09:46 -070037#include <hardware/bluetooth.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080038
39/*****************************************************************************
40** Constants & Macros
41******************************************************************************/
42
The Android Open Source Project5738f832012-12-12 16:00:35 -080043#define SCHED_NORMAL 0
44#define SCHED_FIFO 1
45#define SCHED_RR 2
46#define SCHED_BATCH 3
47
48#define NANOSEC_PER_MILLISEC (1000000)
49#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
50
Sharvil Nanavati10aecea2014-05-28 17:09:46 -070051#define WAKE_LOCK_ID "bluedroid_timer"
The Android Open Source Project5738f832012-12-12 16:00:35 -080052
53#if GKI_DYNAMIC_MEMORY == FALSE
54tGKI_CB gki_cb;
55#endif
56
The Android Open Source Project5738f832012-12-12 16:00:35 -080057#ifndef GKI_SHUTDOWN_EVT
58#define GKI_SHUTDOWN_EVT APPL_EVT_7
59#endif
60
The Android Open Source Project5738f832012-12-12 16:00:35 -080061/*****************************************************************************
62** Local type definitions
63******************************************************************************/
64
The Android Open Source Project5738f832012-12-12 16:00:35 -080065typedef struct
66{
67 UINT8 task_id; /* GKI task id */
68 TASKPTR task_entry; /* Task entry function*/
69 UINT32 params; /* Extra params to pass to task entry function */
70} gki_pthread_info_t;
71
Sharvil Nanavati10aecea2014-05-28 17:09:46 -070072// Alarm service structure used to pass up via JNI to the bluetooth
73// app in order to create a wakeable Alarm.
74typedef struct {
75 int32_t num_ticks;
76 uint32_t alarm_cnt;
77 bool wakelock;
78} alarm_service_t;
The Android Open Source Project5738f832012-12-12 16:00:35 -080079
80/*****************************************************************************
81** Static variables
82******************************************************************************/
83
The Android Open Source Project5738f832012-12-12 16:00:35 -080084gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
85
Sharvil Nanavati10aecea2014-05-28 17:09:46 -070086// Only a single alarm is used to wake bluedroid.
87// NOTE: Must be manipulated with the GKI_disable() lock held.
88static alarm_service_t alarm_service;
89
90// If the next wakeup time is less than this threshold, we should acquire
91// a wakelock instead of setting a wake alarm so we're not bouncing in
92// and out of suspend frequently.
93static const uint32_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 3000;
94
The Android Open Source Project5738f832012-12-12 16:00:35 -080095/*****************************************************************************
96** Static functions
97******************************************************************************/
98
99/*****************************************************************************
100** Externs
101******************************************************************************/
102
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700103extern bt_os_callouts_t *bt_os_callouts;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800104
105/*****************************************************************************
106** Functions
107******************************************************************************/
108
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700109/** Callback from Java thread after alarm from AlarmService fires. */
110static void bt_alarm_cb(void *data) {
111 alarm_service_t *alarm_service = (alarm_service_t *)data;
112 GKI_timer_update(alarm_service->num_ticks);
113}
114
115/** NOTE: This is only called on init and may be called without the GKI_disable()
116 * lock held.
117 */
118static void alarm_service_init() {
119 alarm_service.num_ticks = 0;
120 alarm_service.alarm_cnt = 0;
121 alarm_service.wakelock = false;
122}
123
124/** Requests an alarm from AlarmService to fire when the next
125 * timer in the timer queue is set to expire. Only takes a wakelock
126 * if the timer tick expiration is a short interval in the future
127 * and releases the wakelock if the timer is a longer interval
128 * or if there are no more timers in the queue.
129 *
130 * NOTE: Must be called with GKI_disable() lock held.
131 */
132void alarm_service_reschedule() {
133 int32_t ticks_till_next_exp = GKI_ready_to_sleep();
134
135 assert(ticks_till_next_exp >= 0);
136
137 // No more timers remaining. Release wakelock if we're holding one.
138 if (ticks_till_next_exp == 0) {
139 if (alarm_service.wakelock) {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700140 ALOGV("%s releasing wake lock.", __func__);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700141 alarm_service.wakelock = false;
142 int rc = bt_os_callouts->release_wake_lock(WAKE_LOCK_ID);
143 if (rc != BT_STATUS_SUCCESS) {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700144 ALOGE("%s unable to release wake lock with no timers: %d", __func__, rc);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700145 }
146 }
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700147 ALOGV("%s no more alarms.", __func__);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700148 return;
149 }
150
151 alarm_service.num_ticks = ticks_till_next_exp;
152 alarm_service.alarm_cnt++;
153
154 uint64_t ticks_in_millis = GKI_TICKS_TO_MS(ticks_till_next_exp);
155 if (ticks_in_millis <= TIMER_INTERVAL_FOR_WAKELOCK_IN_MS) {
156 // The next deadline is close, just take a wakelock and set a regular (non-wake) timer.
157 int rc = bt_os_callouts->acquire_wake_lock(WAKE_LOCK_ID);
158 if (rc != BT_STATUS_SUCCESS) {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700159 ALOGE("%s unable to acquire wake lock: %d", __func__, rc);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700160 return;
161 }
162 alarm_service.wakelock = true;
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700163 ALOGV("%s acquired wake lock, setting short alarm (%lldms).", __func__, ticks_in_millis);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700164 if (!bt_os_callouts->set_wake_alarm(ticks_in_millis, false, bt_alarm_cb, &alarm_service)) {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700165 ALOGE("%s unable to set short alarm.", __func__);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700166 }
167 } else {
168 // The deadline is far away, set a wake alarm and release wakelock if we're holding it.
169 if (!bt_os_callouts->set_wake_alarm(ticks_in_millis, true, bt_alarm_cb, &alarm_service)) {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700170 ALOGE("%s unable to set long alarm, releasing wake lock anyway.", __func__);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700171 } else {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700172 ALOGV("%s set long alarm (%lldms), releasing wake lock.", __func__, ticks_in_millis);
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700173 }
174 alarm_service.wakelock = false;
175 bt_os_callouts->release_wake_lock(WAKE_LOCK_ID);
176 }
177}
178
The Android Open Source Project5738f832012-12-12 16:00:35 -0800179
180/*****************************************************************************
181**
182** Function gki_task_entry
183**
184** Description GKI pthread callback
185**
186** Returns void
187**
188*******************************************************************************/
Sharvil Nanavati6449e492014-06-06 01:26:23 -0700189static void gki_task_entry(UINT32 params)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800190{
191 gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
192 gki_cb.os.thread_id[p_pthread_info->task_id] = pthread_self();
193
194 prctl(PR_SET_NAME, (unsigned long)gki_cb.com.OSTName[p_pthread_info->task_id], 0, 0, 0);
195
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700196 ALOGI("gki_task_entry task_id=%i [%s] starting\n", p_pthread_info->task_id,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800197 gki_cb.com.OSTName[p_pthread_info->task_id]);
198
199 /* Call the actual thread entry point */
200 (p_pthread_info->task_entry)(p_pthread_info->params);
201
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700202 ALOGI("gki_task task_id=%i [%s] terminating\n", p_pthread_info->task_id,
The Android Open Source Project5738f832012-12-12 16:00:35 -0800203 gki_cb.com.OSTName[p_pthread_info->task_id]);
204
205 pthread_exit(0); /* GKI tasks have no return value */
206}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800207
208/*******************************************************************************
209**
210** Function GKI_init
211**
212** Description This function is called once at startup to initialize
213** all the timer structures.
214**
215** Returns void
216**
217*******************************************************************************/
218
219void GKI_init(void)
220{
221 pthread_mutexattr_t attr;
222 tGKI_OS *p_os;
223
224 memset (&gki_cb, 0, sizeof (gki_cb));
225
226 gki_buffer_init();
227 gki_timers_init();
Sharvil Nanavati10aecea2014-05-28 17:09:46 -0700228 alarm_service_init();
229
The Android Open Source Project5738f832012-12-12 16:00:35 -0800230 gki_cb.com.OSTicks = (UINT32) times(0);
231
232 pthread_mutexattr_init(&attr);
233
234#ifndef __CYGWIN__
235 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
236#endif
237 p_os = &gki_cb.os;
238 pthread_mutex_init(&p_os->GKI_mutex, &attr);
239 /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
240#if (GKI_DEBUG == TRUE)
241 pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
242#endif
243 /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
244 /* pthread_cond_init (&thread_delay_cond, NULL); */
245
The Android Open Source Project5738f832012-12-12 16:00:35 -0800246}
247
248
249/*******************************************************************************
250**
251** Function GKI_get_os_tick_count
252**
253** Description This function is called to retrieve the native OS system tick.
254**
255** Returns Tick count of native OS.
256**
257*******************************************************************************/
258UINT32 GKI_get_os_tick_count(void)
259{
Sharvil Nanavati6449e492014-06-06 01:26:23 -0700260 return gki_cb.com.OSTicks;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800261}
262
263/*******************************************************************************
264**
265** Function GKI_create_task
266**
267** Description This function is called to create a new OSS task.
268**
269** Parameters: task_entry - (input) pointer to the entry function of the task
270** task_id - (input) Task id is mapped to priority
271** taskname - (input) name given to the task
272** stack - (input) pointer to the top of the stack (highest memory location)
273** stacksize - (input) size of the stack allocated for the task
274**
275** Returns GKI_SUCCESS if all OK, GKI_FAILURE if any problem
276**
277** NOTE This function take some parameters that may not be needed
278** by your particular OS. They are here for compatability
279** of the function prototype.
280**
281*******************************************************************************/
282UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize)
283{
284 UINT16 i;
285 UINT8 *p;
286 struct sched_param param;
287 int policy, ret = 0;
288 pthread_attr_t attr1;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800289 UNUSED(stack);
290 UNUSED(stacksize);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800291
292 GKI_TRACE( "GKI_create_task %x %d %s %x %d", (int)task_entry, (int)task_id,
293 (char*) taskname, (int) stack, (int)stacksize);
294
295 if (task_id >= GKI_MAX_TASKS)
296 {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700297 ALOGE("Error! task ID > max task allowed");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800298 return (GKI_FAILURE);
299 }
300
301
302 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
303 gki_cb.com.OSTName[task_id] = taskname;
304 gki_cb.com.OSWaitTmr[task_id] = 0;
305 gki_cb.com.OSWaitEvt[task_id] = 0;
306
307 /* Initialize mutex and condition variable objects for events and timeouts */
Narayan Kamatha90d3432014-03-05 16:04:31 +0000308 pthread_condattr_t cond_attr;
309 pthread_condattr_init(&cond_attr);
310 pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
311
The Android Open Source Project5738f832012-12-12 16:00:35 -0800312 pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
Narayan Kamatha90d3432014-03-05 16:04:31 +0000313 pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], &cond_attr);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800314 pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
315 pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);
316
317 pthread_attr_init(&attr1);
318 /* by default, pthread creates a joinable thread */
319#if ( FALSE == GKI_PTHREAD_JOINABLE )
320 pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
321
322 GKI_TRACE("GKI creating task %i\n", task_id);
323#else
324 GKI_TRACE("GKI creating JOINABLE task %i\n", task_id);
325#endif
326
327 /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
328 /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
329 gki_pthread_info[task_id].task_id = task_id;
330 gki_pthread_info[task_id].task_entry = task_entry;
331 gki_pthread_info[task_id].params = 0;
332
333 ret = pthread_create( &gki_cb.os.thread_id[task_id],
334 &attr1,
335 (void *)gki_task_entry,
336 &gki_pthread_info[task_id]);
337
338 if (ret != 0)
339 {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700340 ALOGE("pthread_create failed(%d), %s!", ret, taskname);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800341 return GKI_FAILURE;
342 }
343
344 if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param)==0)
345 {
346#if (GKI_LINUX_BASE_POLICY!=GKI_SCHED_NORMAL)
347#if defined(PBS_SQL_TASK)
348 if (task_id == PBS_SQL_TASK)
349 {
350 GKI_TRACE("PBS SQL lowest priority task");
351 policy = SCHED_NORMAL;
352 }
353 else
354#endif
355#endif
356 {
357 /* check if define in gki_int.h is correct for this compile environment! */
358 policy = GKI_LINUX_BASE_POLICY;
Sharvil Nanavatibcfbc242014-01-22 00:04:45 -0800359#if (GKI_LINUX_BASE_POLICY != GKI_SCHED_NORMAL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800360 param.sched_priority = GKI_LINUX_BASE_PRIORITY - task_id - 2;
Sharvil Nanavatibcfbc242014-01-22 00:04:45 -0800361#else
362 param.sched_priority = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800363#endif
364 }
365 pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
366 }
367
368 GKI_TRACE( "Leaving GKI_create_task %x %d %x %s %x %d\n",
369 (int)task_entry,
370 (int)task_id,
371 (int)gki_cb.os.thread_id[task_id],
372 (char*)taskname,
373 (int)stack,
374 (int)stacksize);
375
376 return (GKI_SUCCESS);
377}
378
379void GKI_destroy_task(UINT8 task_id)
380{
381#if ( FALSE == GKI_PTHREAD_JOINABLE )
382 int i = 0;
383#else
384 int result;
385#endif
386 if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
387 {
388 gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
389
390 /* paranoi settings, make sure that we do not execute any mailbox events */
391 gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
392 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
393
394#if (GKI_NUM_TIMERS > 0)
395 gki_cb.com.OSTaskTmr0R[task_id] = 0;
396 gki_cb.com.OSTaskTmr0 [task_id] = 0;
397#endif
398
399#if (GKI_NUM_TIMERS > 1)
400 gki_cb.com.OSTaskTmr1R[task_id] = 0;
401 gki_cb.com.OSTaskTmr1 [task_id] = 0;
402#endif
403
404#if (GKI_NUM_TIMERS > 2)
405 gki_cb.com.OSTaskTmr2R[task_id] = 0;
406 gki_cb.com.OSTaskTmr2 [task_id] = 0;
407#endif
408
409#if (GKI_NUM_TIMERS > 3)
410 gki_cb.com.OSTaskTmr3R[task_id] = 0;
411 gki_cb.com.OSTaskTmr3 [task_id] = 0;
412#endif
413
414 GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
415
416#if ( FALSE == GKI_PTHREAD_JOINABLE )
417 i = 0;
418
419 while ((gki_cb.com.OSWaitEvt[task_id] != 0) && (++i < 10))
420 usleep(100 * 1000);
421#else
422 result = pthread_join( gki_cb.os.thread_id[task_id], NULL );
423 if ( result < 0 )
424 {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700425 ALOGE( "pthread_join() FAILED: result: %d", result );
The Android Open Source Project5738f832012-12-12 16:00:35 -0800426 }
427#endif
428 GKI_exit_task(task_id);
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700429 ALOGI( "GKI_shutdown(): task [%s] terminated\n", gki_cb.com.OSTName[task_id]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800430 }
431}
432
433
434/*******************************************************************************
435**
436** Function GKI_task_self_cleanup
437**
438** Description This function is used in the case when the calling thread
439** is exiting itself. The GKI_destroy_task function can not be
440** used in this case due to the pthread_join call. The function
441** cleans up GKI control block associated to the terminating
442** thread.
443**
444** Parameters: task_id - (input) Task id is used for sanity check to
445** make sure the calling thread is in the right
446** context.
447**
448** Returns None
449**
450*******************************************************************************/
451void GKI_task_self_cleanup(UINT8 task_id)
452{
453 UINT8 my_task_id = GKI_get_taskid();
454
455 if (task_id != my_task_id)
456 {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700457 ALOGE("%s: Wrong context - current task %d is not the given task id %d",\
The Android Open Source Project5738f832012-12-12 16:00:35 -0800458 __FUNCTION__, my_task_id, task_id);
459 return;
460 }
461
462 if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
463 {
464 /* paranoi settings, make sure that we do not execute any mailbox events */
465 gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
466 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
467
468#if (GKI_NUM_TIMERS > 0)
469 gki_cb.com.OSTaskTmr0R[task_id] = 0;
470 gki_cb.com.OSTaskTmr0 [task_id] = 0;
471#endif
472
473#if (GKI_NUM_TIMERS > 1)
474 gki_cb.com.OSTaskTmr1R[task_id] = 0;
475 gki_cb.com.OSTaskTmr1 [task_id] = 0;
476#endif
477
478#if (GKI_NUM_TIMERS > 2)
479 gki_cb.com.OSTaskTmr2R[task_id] = 0;
480 gki_cb.com.OSTaskTmr2 [task_id] = 0;
481#endif
482
483#if (GKI_NUM_TIMERS > 3)
484 gki_cb.com.OSTaskTmr3R[task_id] = 0;
485 gki_cb.com.OSTaskTmr3 [task_id] = 0;
486#endif
487
488 GKI_exit_task(task_id);
489
490 /* Calling pthread_detach here to mark the thread as detached.
491 Once the thread terminates, the system can reclaim its resources
492 without waiting for another thread to join with.
493 */
494 pthread_detach(gki_cb.os.thread_id[task_id]);
495 }
496}
497
498/*******************************************************************************
499**
500** Function GKI_shutdown
501**
502** Description shutdowns the GKI tasks/threads in from max task id to 0 and frees
503** pthread resources!
504** IMPORTANT: in case of join method, GKI_shutdown must be called outside
505** a GKI thread context!
506**
507** Returns void
508**
509*******************************************************************************/
510
511void GKI_shutdown(void)
512{
513 UINT8 task_id;
514#if ( FALSE == GKI_PTHREAD_JOINABLE )
515 int i = 0;
516#else
517 int result;
518#endif
519
520#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
521 gki_dealloc_free_queue();
522#endif
523
524 /* release threads and set as TASK_DEAD. going from low to high priority fixes
525 * GKI_exception problem due to btu->hci sleep request events */
526 for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
527 {
528 if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
529 {
530 gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
531
532 /* paranoi settings, make sure that we do not execute any mailbox events */
533 gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
534 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
535 GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
536
537#if ( FALSE == GKI_PTHREAD_JOINABLE )
538 i = 0;
539
540 while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
541 usleep(100 * 1000);
542#else
543 result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
544
545 if ( result < 0 )
546 {
547 ALOGE( "pthread_join() FAILED: result: %d", result );
548 }
549#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -0800550 GKI_exit_task(task_id - 1);
551 }
552 }
553
554 /* Destroy mutex and condition variable objects */
555 pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
556
557 /* pthread_mutex_destroy(&GKI_sched_mutex); */
558#if (GKI_DEBUG == TRUE)
559 pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
560#endif
561 /* pthread_mutex_destroy(&thread_delay_mutex);
562 pthread_cond_destroy (&thread_delay_cond); */
563#if ( FALSE == GKI_PTHREAD_JOINABLE )
564 i = 0;
565#endif
566
The Android Open Source Project5738f832012-12-12 16:00:35 -0800567}
568
The Android Open Source Project5738f832012-12-12 16:00:35 -0800569/*****************************************************************************
570**
571** Function gki_set_timer_scheduling
572**
573** Description helper function to set scheduling policy and priority of btdl
574**
575** Returns void
576**
577*******************************************************************************/
578
579static void gki_set_timer_scheduling( void )
580{
581 pid_t main_pid = getpid();
582 struct sched_param param;
583 int policy;
584
585 policy = sched_getscheduler(main_pid);
586
587 if ( policy != -1 )
588 {
589 GKI_TRACE("gki_set_timer_scheduling(()::scheduler current policy: %d", policy);
590
591 /* ensure highest priority in the system + 2 to allow space for read threads */
592 param.sched_priority = GKI_LINUX_TIMER_TICK_PRIORITY;
593
594 if ( 0!=sched_setscheduler(main_pid, GKI_LINUX_TIMER_POLICY, &param ) )
595 {
596 GKI_TRACE("sched_setscheduler() failed with error: %d", errno);
597 }
598 }
599 else
600 {
601 GKI_TRACE( "getscheduler failed: %d", errno);
602 }
603}
604
605
606/*****************************************************************************
607**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800608** Function GKI_run
609**
610** Description Main GKI loop
611**
612** Returns
613**
614*******************************************************************************/
615
Sharvil Nanavatib5382482014-06-29 18:10:15 -0700616void GKI_run(void)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800617{
The Android Open Source Project5738f832012-12-12 16:00:35 -0800618 /* adjust btld scheduling scheme now */
619 gki_set_timer_scheduling();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800620 GKI_TRACE( "GKI_run(): Start/Stop GKI_timer_update_registered!" );
The Android Open Source Project5738f832012-12-12 16:00:35 -0800621}
622
623
624/*******************************************************************************
625**
626** Function GKI_stop
627**
628** Description This function is called to stop
629** the tasks and timers when the system is being stopped
630**
631** Returns void
632**
633** NOTE This function is NOT called by the Broadcom stack and
634** profiles. If you want to use it in your own implementation,
635** put specific code here.
636**
637*******************************************************************************/
638
639void GKI_stop (void)
640{
641 UINT8 task_id;
642
643 /* gki_queue_timer_cback(FALSE); */
644 /* TODO - add code here if needed*/
645
646 for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
647 {
648 if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
649 {
650 GKI_exit_task(task_id);
651 }
652 }
653}
654
655
656/*******************************************************************************
657**
658** Function GKI_wait
659**
660** Description This function is called by tasks to wait for a specific
661** event or set of events. The task may specify the duration
662** that it wants to wait for, or 0 if infinite.
663**
664** Parameters: flag - (input) the event or set of events to wait for
665** timeout - (input) the duration that the task wants to wait
666** for the specific events (in system ticks)
667**
668**
669** Returns the event mask of received events or zero if timeout
670**
671*******************************************************************************/
672UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
673{
674 UINT16 evt;
675 UINT8 rtask;
676 struct timespec abstime = { 0, 0 };
677
678 int sec;
679 int nano_sec;
680
681 rtask = GKI_get_taskid();
682
683 GKI_TRACE("GKI_wait %d %x %d", (int)rtask, (int)flag, (int)timeout);
684
685 gki_cb.com.OSWaitForEvt[rtask] = flag;
686
687 /* protect OSWaitEvt[rtask] from modification from an other thread */
688 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
689
690 if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
691 {
692 if (timeout)
693 {
694 clock_gettime(CLOCK_MONOTONIC, &abstime);
695
696 /* add timeout */
697 sec = timeout / 1000;
698 nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
699 abstime.tv_nsec += nano_sec;
700 if (abstime.tv_nsec > NSEC_PER_SEC)
701 {
702 abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
703 abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
704 }
705 abstime.tv_sec += sec;
706
Narayan Kamatha90d3432014-03-05 16:04:31 +0000707 pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
The Android Open Source Project5738f832012-12-12 16:00:35 -0800708 &gki_cb.os.thread_evt_mutex[rtask], &abstime);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800709 }
710 else
711 {
712 pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
713 }
714
715 /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
716 e.g. it looks like it is implemented as a counter in which case multiple cond_signal
717 should NOT be lost! */
718
719 /* we are waking up after waiting for some events, so refresh variables
720 no need to call GKI_disable() here as we know that we will have some events as we've been waking
721 up after condition pending or timeout */
722
723 if (gki_cb.com.OSTaskQFirst[rtask][0])
724 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
725 if (gki_cb.com.OSTaskQFirst[rtask][1])
726 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
727 if (gki_cb.com.OSTaskQFirst[rtask][2])
728 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
729 if (gki_cb.com.OSTaskQFirst[rtask][3])
730 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
731
732 if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
733 {
734 gki_cb.com.OSWaitEvt[rtask] = 0;
735 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
736 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
737 return (EVENT_MASK(GKI_SHUTDOWN_EVT));
738 }
739 }
740
741 /* Clear the wait for event mask */
742 gki_cb.com.OSWaitForEvt[rtask] = 0;
743
744 /* Return only those bits which user wants... */
745 evt = gki_cb.com.OSWaitEvt[rtask] & flag;
746
747 /* Clear only those bits which user wants... */
748 gki_cb.com.OSWaitEvt[rtask] &= ~flag;
749
750 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
751 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
752
753 GKI_TRACE("GKI_wait %d %x %d %x done", (int)rtask, (int)flag, (int)timeout, (int)evt);
754 return (evt);
755}
756
757
758/*******************************************************************************
759**
760** Function GKI_delay
761**
762** Description This function is called by tasks to sleep unconditionally
763** for a specified amount of time. The duration is in milliseconds
764**
765** Parameters: timeout - (input) the duration in milliseconds
766**
767** Returns void
768**
769*******************************************************************************/
770
771void GKI_delay (UINT32 timeout)
772{
773 UINT8 rtask = GKI_get_taskid();
774 struct timespec delay;
775 int err;
776
777 GKI_TRACE("GKI_delay %d %d", (int)rtask, (int)timeout);
778
779 delay.tv_sec = timeout / 1000;
780 delay.tv_nsec = 1000 * 1000 * (timeout%1000);
781
782 /* [u]sleep can't be used because it uses SIGALRM */
783
784 do {
785 err = nanosleep(&delay, &delay);
786 } while (err < 0 && errno ==EINTR);
787
788 /* Check if task was killed while sleeping */
789
790 /* NOTE : if you do not implement task killing, you do not need this check */
791
792 if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
793 {
794 }
795
796 GKI_TRACE("GKI_delay %d %d done", (int)rtask, (int)timeout);
797
798 return;
799}
800
801
802/*******************************************************************************
803**
804** Function GKI_send_event
805**
806** Description This function is called by tasks to send events to other
807** tasks. Tasks can also send events to themselves.
808**
809** Parameters: task_id - (input) The id of the task to which the event has to
810** be sent
811** event - (input) The event that has to be sent
812**
813**
814** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
815**
816*******************************************************************************/
817
818UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
819{
820 GKI_TRACE("GKI_send_event %d %x", task_id, event);
821
The Android Open Source Project5738f832012-12-12 16:00:35 -0800822 if (task_id < GKI_MAX_TASKS)
823 {
824 /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
825 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
826
827 /* Set the event bit */
828 gki_cb.com.OSWaitEvt[task_id] |= event;
829
830 pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
831
832 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
833
834 GKI_TRACE("GKI_send_event %d %x done", task_id, event);
835 return ( GKI_SUCCESS );
836 }
837 GKI_TRACE("############## GKI_send_event FAILED!! ##################");
838 return (GKI_FAILURE);
839}
840
841
842/*******************************************************************************
843**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800844** Function GKI_get_taskid
845**
846** Description This function gets the currently running task ID.
847**
848** Returns task ID
849**
850** NOTE The Broadcom upper stack and profiles may run as a single task.
851** If you only have one GKI task, then you can hard-code this
852** function to return a '1'. Otherwise, you should have some
853** OS-specific method to determine the current task.
854**
855*******************************************************************************/
856UINT8 GKI_get_taskid (void)
857{
858 int i;
859
860 pthread_t thread_id = pthread_self( );
861
862 GKI_TRACE("GKI_get_taskid %x", (int)thread_id);
863
864 for (i = 0; i < GKI_MAX_TASKS; i++) {
865 if (gki_cb.os.thread_id[i] == thread_id) {
866 //GKI_TRACE("GKI_get_taskid %x %d done", thread_id, i);
867 return(i);
868 }
869 }
870
871 GKI_TRACE("GKI_get_taskid: task id = -1");
872
873 return(-1);
874}
875
876
877/*******************************************************************************
878**
879** Function GKI_map_taskname
880**
881** Description This function gets the task name of the taskid passed as arg.
882** If GKI_MAX_TASKS is passed as arg the currently running task
883** name is returned
884**
885** Parameters: task_id - (input) The id of the task whose name is being
886** sought. GKI_MAX_TASKS is passed to get the name of the
887** currently running task.
888**
889** Returns pointer to task name
890**
891** NOTE this function needs no customization
892**
893*******************************************************************************/
894
895INT8 *GKI_map_taskname (UINT8 task_id)
896{
897 GKI_TRACE("GKI_map_taskname %d", task_id);
898
899 if (task_id < GKI_MAX_TASKS)
900 {
901 GKI_TRACE("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
902 return (gki_cb.com.OSTName[task_id]);
903 }
904 else if (task_id == GKI_MAX_TASKS )
905 {
906 return (gki_cb.com.OSTName[GKI_get_taskid()]);
907 }
908 else
909 {
910 return (INT8*)"BAD";
911 }
912}
913
914
915/*******************************************************************************
916**
917** Function GKI_enable
918**
919** Description This function enables interrupts.
920**
921** Returns void
922**
923*******************************************************************************/
924void GKI_enable (void)
925{
The Android Open Source Project5738f832012-12-12 16:00:35 -0800926 pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800927}
928
929
930/*******************************************************************************
931**
932** Function GKI_disable
933**
934** Description This function disables interrupts.
935**
936** Returns void
937**
938*******************************************************************************/
939
940void GKI_disable (void)
941{
The Android Open Source Project5738f832012-12-12 16:00:35 -0800942 pthread_mutex_lock(&gki_cb.os.GKI_mutex);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800943}
944
945
946/*******************************************************************************
947**
948** Function GKI_exception
949**
950** Description This function throws an exception.
951** This is normally only called for a nonrecoverable error.
952**
953** Parameters: code - (input) The code for the error
954** msg - (input) The message that has to be logged
955**
956** Returns void
957**
958*******************************************************************************/
959
960void GKI_exception (UINT16 code, char *msg)
961{
962 UINT8 task_id;
963 int i = 0;
964
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700965 ALOGE( "GKI_exception(): Task State Table");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800966
967 for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
968 {
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700969 ALOGE( "TASK ID [%d] task name [%s] state [%d]",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800970 task_id,
971 gki_cb.com.OSTName[task_id],
972 gki_cb.com.OSRdyTbl[task_id]);
973 }
974
Sharvil Nanavatid42dba52014-06-29 17:36:56 -0700975 ALOGE("GKI_exception %d %s", code, msg);
976 ALOGE( "********************************************************************");
977 ALOGE( "* GKI_exception(): %d %s", code, msg);
978 ALOGE( "********************************************************************");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800979
980#if 0//(GKI_DEBUG == TRUE)
981 GKI_disable();
982
983 if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
984 {
985 EXCEPTION_T *pExp;
986
987 pExp = &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
988 pExp->type = code;
989 pExp->taskid = GKI_get_taskid();
990 strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
991 }
992
993 GKI_enable();
994#endif
995
996 GKI_TRACE("GKI_exception %d %s done", code, msg);
997 return;
998}
999
The Android Open Source Project5738f832012-12-12 16:00:35 -08001000/*******************************************************************************
1001**
The Android Open Source Project5738f832012-12-12 16:00:35 -08001002** Function GKI_os_malloc
1003**
1004** Description This function allocates memory
1005**
1006** Parameters: size - (input) The size of the memory that has to be
1007** allocated
1008**
1009** Returns the address of the memory allocated, or NULL if failed
1010**
1011** NOTE This function is called by the Broadcom stack when
1012** dynamic memory allocation is used. (see dyn_mem.h)
1013**
1014*******************************************************************************/
1015void *GKI_os_malloc (UINT32 size)
1016{
Sharvil Nanavati6449e492014-06-06 01:26:23 -07001017 return malloc(size);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001018}
1019
1020/*******************************************************************************
1021**
1022** Function GKI_os_free
1023**
1024** Description This function frees memory
1025**
1026** Parameters: size - (input) The address of the memory that has to be
1027** freed
1028**
1029** Returns void
1030**
1031** NOTE This function is NOT called by the Broadcom stack and
1032** profiles. It is only called from within GKI if dynamic
1033**
1034*******************************************************************************/
1035void GKI_os_free (void *p_mem)
1036{
Sharvil Nanavati6449e492014-06-06 01:26:23 -07001037 free(p_mem);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001038}
1039
1040
1041/*******************************************************************************
1042**
1043** Function GKI_exit_task
1044**
1045** Description This function is called to stop a GKI task.
1046**
1047** Parameters: task_id - (input) the id of the task that has to be stopped
1048**
1049** Returns void
1050**
1051** NOTE This function is NOT called by the Broadcom stack and
1052** profiles. If you want to use it in your own implementation,
1053** put specific code here to kill a task.
1054**
1055*******************************************************************************/
1056void GKI_exit_task (UINT8 task_id)
1057{
1058 GKI_disable();
1059 gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
1060
1061 /* Destroy mutex and condition variable objects */
1062 pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
1063 pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
1064 pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
1065 pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
1066
1067 GKI_enable();
1068
Sharvil Nanavatid42dba52014-06-29 17:36:56 -07001069 ALOGI("GKI_exit_task %d done", task_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001070 return;
1071}