1 /******************************************************************************
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
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <errno.h>
31 #include <sys/times.h>
32
33 #include <pthread.h> /* must be 1st header defined */
34 #include <time.h>
35 #include "gki_int.h"
36 #include "bt_utils.h"
37
38 #define LOG_TAG "GKI_LINUX"
39
40 #include <utils/Log.h>
41
42 /*****************************************************************************
43 ** Constants & Macros
44 ******************************************************************************/
45
46 #ifndef GKI_TICK_TIMER_DEBUG
47 #define GKI_TICK_TIMER_DEBUG FALSE
48 #endif
49
50 #define GKI_INFO(fmt, ...) ALOGI ("%s: " fmt, __FUNCTION__, ## __VA_ARGS__)
51
52 /* always log errors */
53 #define GKI_ERROR_LOG(fmt, ...) ALOGE ("##### ERROR : %s: " fmt "#####", __FUNCTION__, ## __VA_ARGS__)
54
55 #if defined (GKI_TICK_TIMER_DEBUG) && (GKI_TICK_TIMER_DEBUG == TRUE)
56 #define GKI_TIMER_TRACE(fmt, ...) ALOGI ("%s: " fmt, __FUNCTION__, ## __VA_ARGS__)
57 #else
58 #define GKI_TIMER_TRACE(fmt, ...)
59 #endif
60
61
62 #define SCHED_NORMAL 0
63 #define SCHED_FIFO 1
64 #define SCHED_RR 2
65 #define SCHED_BATCH 3
66
67 #define NANOSEC_PER_MILLISEC (1000000)
68 #define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
69
70 /* works only for 1ms to 1000ms heart beat ranges */
71 #define LINUX_SEC (1000/TICKS_PER_SEC)
72
73 #define LOCK(m) pthread_mutex_lock(&m)
74 #define UNLOCK(m) pthread_mutex_unlock(&m)
75 #define INIT(m) pthread_mutex_init(&m, NULL)
76
77 #define WAKE_LOCK_ID "brcm_btld"
78 #define PARTIAL_WAKE_LOCK 1
79
80 #if GKI_DYNAMIC_MEMORY == FALSE
81 tGKI_CB gki_cb;
82 #endif
83
84 #ifdef NO_GKI_RUN_RETURN
85 static pthread_t timer_thread_id = 0;
86 static int shutdown_timer = 0;
87 #endif
88
89 #ifndef GKI_SHUTDOWN_EVT
90 #define GKI_SHUTDOWN_EVT APPL_EVT_7
91 #endif
92
93 #define __likely(cond) __builtin_expect(!!(cond), 1)
94 #define __unlikely(cond) __builtin_expect(!!(cond), 0)
95
96 /*****************************************************************************
97 ** Local type definitions
98 ******************************************************************************/
99
100 #define pthread_cond_timedwait_monotonic pthread_cond_timedwait
101
102 typedef struct
103 {
104 UINT8 task_id; /* GKI task id */
105 TASKPTR task_entry; /* Task entry function*/
106 UINT32 params; /* Extra params to pass to task entry function */
107 } gki_pthread_info_t;
108
109
110 /*****************************************************************************
111 ** Static variables
112 ******************************************************************************/
113
114 int g_GkiTimerWakeLockOn = 0;
115 gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
116
117 /*****************************************************************************
118 ** Static functions
119 ******************************************************************************/
120
121 /*****************************************************************************
122 ** Externs
123 ******************************************************************************/
124
125 extern int acquire_wake_lock(int lock, const char* id);
126 extern int release_wake_lock(const char* id);
127
128 /*****************************************************************************
129 ** Functions
130 ******************************************************************************/
131
132
133 /*****************************************************************************
134 **
135 ** Function gki_task_entry
136 **
137 ** Description GKI pthread callback
138 **
139 ** Returns void
140 **
141 *******************************************************************************/
142
gki_task_entry(UINT32 params)143 void gki_task_entry(UINT32 params)
144 {
145 gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
146 gki_cb.os.thread_id[p_pthread_info->task_id] = pthread_self();
147
148 prctl(PR_SET_NAME, (unsigned long)gki_cb.com.OSTName[p_pthread_info->task_id], 0, 0, 0);
149
150 GKI_INFO("gki_task_entry task_id=%i [%s] starting\n", p_pthread_info->task_id,
151 gki_cb.com.OSTName[p_pthread_info->task_id]);
152
153 /* Call the actual thread entry point */
154 (p_pthread_info->task_entry)(p_pthread_info->params);
155
156 GKI_INFO("gki_task task_id=%i [%s] terminating\n", p_pthread_info->task_id,
157 gki_cb.com.OSTName[p_pthread_info->task_id]);
158
159 pthread_exit(0); /* GKI tasks have no return value */
160 }
161 /* end android */
162
163 /*******************************************************************************
164 **
165 ** Function GKI_init
166 **
167 ** Description This function is called once at startup to initialize
168 ** all the timer structures.
169 **
170 ** Returns void
171 **
172 *******************************************************************************/
173
GKI_init(void)174 void GKI_init(void)
175 {
176 pthread_mutexattr_t attr;
177 tGKI_OS *p_os;
178
179 memset (&gki_cb, 0, sizeof (gki_cb));
180
181 gki_buffer_init();
182 gki_timers_init();
183 gki_cb.com.OSTicks = (UINT32) times(0);
184
185 pthread_mutexattr_init(&attr);
186
187 #ifndef __CYGWIN__
188 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
189 #endif
190 p_os = &gki_cb.os;
191 pthread_mutex_init(&p_os->GKI_mutex, &attr);
192 /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
193 #if (GKI_DEBUG == TRUE)
194 pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
195 #endif
196 /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
197 /* pthread_cond_init (&thread_delay_cond, NULL); */
198
199 /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
200 * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
201 p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
202 pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
203 #ifndef NO_GKI_RUN_RETURN
204 pthread_cond_init(&p_os->gki_timer_cond, NULL);
205 #endif
206 }
207
208
209 /*******************************************************************************
210 **
211 ** Function GKI_get_os_tick_count
212 **
213 ** Description This function is called to retrieve the native OS system tick.
214 **
215 ** Returns Tick count of native OS.
216 **
217 *******************************************************************************/
GKI_get_os_tick_count(void)218 UINT32 GKI_get_os_tick_count(void)
219 {
220 /* TODO - add any OS specific code here */
221 return (gki_cb.com.OSTicks);
222 }
223
224 /*******************************************************************************
225 **
226 ** Function GKI_create_task
227 **
228 ** Description This function is called to create a new OSS task.
229 **
230 ** Parameters: task_entry - (input) pointer to the entry function of the task
231 ** task_id - (input) Task id is mapped to priority
232 ** taskname - (input) name given to the task
233 ** stack - (input) pointer to the top of the stack (highest memory location)
234 ** stacksize - (input) size of the stack allocated for the task
235 **
236 ** Returns GKI_SUCCESS if all OK, GKI_FAILURE if any problem
237 **
238 ** NOTE This function take some parameters that may not be needed
239 ** by your particular OS. They are here for compatability
240 ** of the function prototype.
241 **
242 *******************************************************************************/
GKI_create_task(TASKPTR task_entry,UINT8 task_id,INT8 * taskname,UINT16 * stack,UINT16 stacksize)243 UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize)
244 {
245 UINT16 i;
246 UINT8 *p;
247 struct sched_param param;
248 int policy, ret = 0;
249 pthread_attr_t attr1;
250
251 GKI_TRACE( "GKI_create_task %x %d %s %x %d", (int)task_entry, (int)task_id,
252 (char*) taskname, (int) stack, (int)stacksize);
253
254 if (task_id >= GKI_MAX_TASKS)
255 {
256 GKI_ERROR_LOG("Error! task ID > max task allowed");
257 return (GKI_FAILURE);
258 }
259
260
261 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
262 gki_cb.com.OSTName[task_id] = taskname;
263 gki_cb.com.OSWaitTmr[task_id] = 0;
264 gki_cb.com.OSWaitEvt[task_id] = 0;
265
266 /* Initialize mutex and condition variable objects for events and timeouts */
267 pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
268 pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], NULL);
269 pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
270 pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);
271
272 pthread_attr_init(&attr1);
273 /* by default, pthread creates a joinable thread */
274 #if ( FALSE == GKI_PTHREAD_JOINABLE )
275 pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
276
277 GKI_TRACE("GKI creating task %i\n", task_id);
278 #else
279 GKI_TRACE("GKI creating JOINABLE task %i\n", task_id);
280 #endif
281
282 /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
283 /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
284 gki_pthread_info[task_id].task_id = task_id;
285 gki_pthread_info[task_id].task_entry = task_entry;
286 gki_pthread_info[task_id].params = 0;
287
288 ret = pthread_create( &gki_cb.os.thread_id[task_id],
289 &attr1,
290 (void *)gki_task_entry,
291 &gki_pthread_info[task_id]);
292
293 if (ret != 0)
294 {
295 GKI_ERROR_LOG("pthread_create failed(%d), %s!\n\r", ret, taskname);
296 return GKI_FAILURE;
297 }
298
299 if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, ¶m)==0)
300 {
301 #if (GKI_LINUX_BASE_POLICY!=GKI_SCHED_NORMAL)
302 #if defined(PBS_SQL_TASK)
303 if (task_id == PBS_SQL_TASK)
304 {
305 GKI_TRACE("PBS SQL lowest priority task");
306 policy = SCHED_NORMAL;
307 }
308 else
309 #endif
310 #endif
311 {
312 /* check if define in gki_int.h is correct for this compile environment! */
313 policy = GKI_LINUX_BASE_POLICY;
314 #if (GKI_LINUX_BASE_POLICY!=GKI_SCHED_NORMAL)
315 param.sched_priority = GKI_LINUX_BASE_PRIORITY - task_id - 2;
316 #endif
317 }
318 pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, ¶m);
319 }
320
321 GKI_TRACE( "Leaving GKI_create_task %x %d %x %s %x %d\n",
322 (int)task_entry,
323 (int)task_id,
324 (int)gki_cb.os.thread_id[task_id],
325 (char*)taskname,
326 (int)stack,
327 (int)stacksize);
328
329 return (GKI_SUCCESS);
330 }
331
GKI_destroy_task(UINT8 task_id)332 void GKI_destroy_task(UINT8 task_id)
333 {
334 #if ( FALSE == GKI_PTHREAD_JOINABLE )
335 int i = 0;
336 #else
337 int result;
338 #endif
339 if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
340 {
341 gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
342
343 /* paranoi settings, make sure that we do not execute any mailbox events */
344 gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
345 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
346
347 #if (GKI_NUM_TIMERS > 0)
348 gki_cb.com.OSTaskTmr0R[task_id] = 0;
349 gki_cb.com.OSTaskTmr0 [task_id] = 0;
350 #endif
351
352 #if (GKI_NUM_TIMERS > 1)
353 gki_cb.com.OSTaskTmr1R[task_id] = 0;
354 gki_cb.com.OSTaskTmr1 [task_id] = 0;
355 #endif
356
357 #if (GKI_NUM_TIMERS > 2)
358 gki_cb.com.OSTaskTmr2R[task_id] = 0;
359 gki_cb.com.OSTaskTmr2 [task_id] = 0;
360 #endif
361
362 #if (GKI_NUM_TIMERS > 3)
363 gki_cb.com.OSTaskTmr3R[task_id] = 0;
364 gki_cb.com.OSTaskTmr3 [task_id] = 0;
365 #endif
366
367 GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
368
369 #if ( FALSE == GKI_PTHREAD_JOINABLE )
370 i = 0;
371
372 while ((gki_cb.com.OSWaitEvt[task_id] != 0) && (++i < 10))
373 usleep(100 * 1000);
374 #else
375 result = pthread_join( gki_cb.os.thread_id[task_id], NULL );
376 if ( result < 0 )
377 {
378 GKI_ERROR_LOG( "pthread_join() FAILED: result: %d", result );
379 }
380 #endif
381 GKI_exit_task(task_id);
382 GKI_INFO( "GKI_shutdown(): task [%s] terminated\n", gki_cb.com.OSTName[task_id]);
383 }
384 }
385
386
387 /*******************************************************************************
388 **
389 ** Function GKI_task_self_cleanup
390 **
391 ** Description This function is used in the case when the calling thread
392 ** is exiting itself. The GKI_destroy_task function can not be
393 ** used in this case due to the pthread_join call. The function
394 ** cleans up GKI control block associated to the terminating
395 ** thread.
396 **
397 ** Parameters: task_id - (input) Task id is used for sanity check to
398 ** make sure the calling thread is in the right
399 ** context.
400 **
401 ** Returns None
402 **
403 *******************************************************************************/
GKI_task_self_cleanup(UINT8 task_id)404 void GKI_task_self_cleanup(UINT8 task_id)
405 {
406 UINT8 my_task_id = GKI_get_taskid();
407
408 if (task_id != my_task_id)
409 {
410 GKI_ERROR_LOG("%s: Wrong context - current task %d is not the given task id %d",\
411 __FUNCTION__, my_task_id, task_id);
412 return;
413 }
414
415 if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
416 {
417 /* paranoi settings, make sure that we do not execute any mailbox events */
418 gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
419 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
420
421 #if (GKI_NUM_TIMERS > 0)
422 gki_cb.com.OSTaskTmr0R[task_id] = 0;
423 gki_cb.com.OSTaskTmr0 [task_id] = 0;
424 #endif
425
426 #if (GKI_NUM_TIMERS > 1)
427 gki_cb.com.OSTaskTmr1R[task_id] = 0;
428 gki_cb.com.OSTaskTmr1 [task_id] = 0;
429 #endif
430
431 #if (GKI_NUM_TIMERS > 2)
432 gki_cb.com.OSTaskTmr2R[task_id] = 0;
433 gki_cb.com.OSTaskTmr2 [task_id] = 0;
434 #endif
435
436 #if (GKI_NUM_TIMERS > 3)
437 gki_cb.com.OSTaskTmr3R[task_id] = 0;
438 gki_cb.com.OSTaskTmr3 [task_id] = 0;
439 #endif
440
441 GKI_exit_task(task_id);
442
443 /* Calling pthread_detach here to mark the thread as detached.
444 Once the thread terminates, the system can reclaim its resources
445 without waiting for another thread to join with.
446 */
447 pthread_detach(gki_cb.os.thread_id[task_id]);
448 }
449 }
450
451 /*******************************************************************************
452 **
453 ** Function GKI_shutdown
454 **
455 ** Description shutdowns the GKI tasks/threads in from max task id to 0 and frees
456 ** pthread resources!
457 ** IMPORTANT: in case of join method, GKI_shutdown must be called outside
458 ** a GKI thread context!
459 **
460 ** Returns void
461 **
462 *******************************************************************************/
463
GKI_shutdown(void)464 void GKI_shutdown(void)
465 {
466 UINT8 task_id;
467 #if ( FALSE == GKI_PTHREAD_JOINABLE )
468 int i = 0;
469 #else
470 int result;
471 #endif
472
473 #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
474 gki_dealloc_free_queue();
475 #endif
476
477 /* release threads and set as TASK_DEAD. going from low to high priority fixes
478 * GKI_exception problem due to btu->hci sleep request events */
479 for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
480 {
481 if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
482 {
483 gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
484
485 /* paranoi settings, make sure that we do not execute any mailbox events */
486 gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
487 TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
488 GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
489
490 #if ( FALSE == GKI_PTHREAD_JOINABLE )
491 i = 0;
492
493 while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
494 usleep(100 * 1000);
495 #else
496 result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
497
498 if ( result < 0 )
499 {
500 ALOGE( "pthread_join() FAILED: result: %d", result );
501 }
502 #endif
503 // GKI_ERROR_LOG( "GKI_shutdown(): task %s dead\n", gki_cb.com.OSTName[task_id]);
504 GKI_exit_task(task_id - 1);
505 }
506 }
507
508 /* Destroy mutex and condition variable objects */
509 pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
510
511 /* pthread_mutex_destroy(&GKI_sched_mutex); */
512 #if (GKI_DEBUG == TRUE)
513 pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
514 #endif
515 /* pthread_mutex_destroy(&thread_delay_mutex);
516 pthread_cond_destroy (&thread_delay_cond); */
517 #if ( FALSE == GKI_PTHREAD_JOINABLE )
518 i = 0;
519 #endif
520
521 #ifdef NO_GKI_RUN_RETURN
522 shutdown_timer = 1;
523 #endif
524 if (g_GkiTimerWakeLockOn)
525 {
526 GKI_TRACE("GKI_shutdown : release_wake_lock(brcm_btld)");
527 release_wake_lock(WAKE_LOCK_ID);
528 g_GkiTimerWakeLockOn = 0;
529 }
530 }
531
532 /*******************************************************************************
533 **
534 ** Function gki_system_tick_start_stop_cback
535 **
536 ** Description This function runs a task
537 **
538 ** Parameters: start: TRUE start system tick (again), FALSE stop
539 **
540 ** Returns void
541 **
542 *********************************************************************************/
543
gki_system_tick_start_stop_cback(BOOLEAN start)544 void gki_system_tick_start_stop_cback(BOOLEAN start)
545 {
546 tGKI_OS *p_os = &gki_cb.os;
547 int *p_run_cond = &p_os->no_timer_suspend;
548 static int wake_lock_count;
549
550 if ( FALSE == start )
551 {
552 /* gki_system_tick_start_stop_cback() maybe called even so it was already stopped! */
553 if (GKI_TIMER_TICK_RUN_COND == *p_run_cond)
554 {
555 #ifdef NO_GKI_RUN_RETURN
556 /* take free mutex to block timer thread */
557 pthread_mutex_lock(&p_os->gki_timer_mutex);
558 #endif
559 /* this can lead to a race condition. however as we only read this variable in the
560 * timer loop we should be fine with this approach. otherwise uncomment below mutexes.
561 */
562 /* GKI_disable(); */
563 *p_run_cond = GKI_TIMER_TICK_STOP_COND;
564 /* GKI_enable(); */
565
566 GKI_TIMER_TRACE(">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count);
567
568 release_wake_lock(WAKE_LOCK_ID);
569 g_GkiTimerWakeLockOn = 0;
570 }
571 }
572 else
573 {
574 /* restart GKI_timer_update() loop */
575 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
576
577 g_GkiTimerWakeLockOn = 1;
578 *p_run_cond = GKI_TIMER_TICK_RUN_COND;
579
580 #ifdef NO_GKI_RUN_RETURN
581 pthread_mutex_unlock( &p_os->gki_timer_mutex );
582 #else
583 pthread_mutex_lock( &p_os->gki_timer_mutex );
584 pthread_cond_signal( &p_os->gki_timer_cond );
585 pthread_mutex_unlock( &p_os->gki_timer_mutex );
586 #endif
587
588 GKI_TIMER_TRACE(">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count );
589 }
590 }
591
592
593 /*******************************************************************************
594 **
595 ** Function GKI_run
596 **
597 ** Description This function runs a task
598 ****
599 ** Returns void
600 **
601 ** NOTE This function is only needed for operating systems where
602 ** starting a task is a 2-step process. Most OS's do it in
603 ** one step, If your OS does it in one step, this function
604 ** should be empty.
605 *********************************************************************************/
606 #ifdef NO_GKI_RUN_RETURN
timer_thread(void * arg)607 void* timer_thread(void *arg)
608 {
609 int timeout_ns=0;
610 struct timespec timeout;
611 struct timespec previous = {0,0};
612 struct timespec current;
613 int err;
614 int delta_ns;
615 int restart;
616 tGKI_OS *p_os = &gki_cb.os;
617 int *p_run_cond = &p_os->no_timer_suspend;
618
619 /* Indicate that tick is just starting */
620 restart = 1;
621
622 prctl(PR_SET_NAME, (unsigned long)"gki timer", 0, 0, 0);
623
624 raise_priority_a2dp(TASK_HIGH_GKI_TIMER);
625
626 while(!shutdown_timer)
627 {
628 /* If the timer has been stopped (no SW timer running) */
629 if (*p_run_cond == GKI_TIMER_TICK_STOP_COND)
630 {
631 /*
632 * We will lock/wait on GKI_timer_mutex.
633 * This mutex will be unlocked when timer is re-started
634 */
635 GKI_TRACE("GKI_run lock mutex");
636 pthread_mutex_lock(&p_os->gki_timer_mutex);
637
638 /* We are here because the mutex has been released by timer cback */
639 /* Let's release it for future use */
640 GKI_TRACE("GKI_run unlock mutex");
641 pthread_mutex_unlock(&p_os->gki_timer_mutex);
642
643 /* Indicate that tick is just starting */
644 restart = 1;
645 }
646
647 /* Get time */
648 clock_gettime(CLOCK_MONOTONIC, ¤t);
649
650 /* Check if tick was just restarted, indicating to the compiler that this is
651 * unlikely to happen (to help branch prediction) */
652 if (__unlikely(restart))
653 {
654 /* Clear the restart indication */
655 restart = 0;
656
657 timeout_ns = (GKI_TICKS_TO_MS(1) * 1000000);
658 }
659 else
660 {
661 /* Compute time elapsed since last sleep start */
662 delta_ns = current.tv_nsec - previous.tv_nsec;
663 delta_ns += (current.tv_sec - previous.tv_sec) * 1000000000;
664
665 /* Compute next timeout:
666 * timeout = (next theoretical expiration) - current time
667 * timeout = (previous time + timeout + delay) - current time
668 * timeout = timeout + delay - (current time - previous time)
669 * timeout += delay - delta */
670 timeout_ns += (GKI_TICKS_TO_MS(1) * 1000000) - delta_ns;
671 }
672 /* Save the current time for next iteration */
673 previous = current;
674
675 timeout.tv_sec = 0;
676
677 /* Sleep until next theoretical tick time. In case of excessive
678 elapsed time since last theoretical tick expiration, it is
679 possible that the timeout value is negative. To protect
680 against this error, we set minimum sleep time to 10% of the
681 tick period. We indicate to compiler that this is unlikely to
682 happen (to help branch prediction) */
683
684 if (__unlikely(timeout_ns < ((GKI_TICKS_TO_MS(1) * 1000000) * 0.1)))
685 {
686 timeout.tv_nsec = (GKI_TICKS_TO_MS(1) * 1000000) * 0.1;
687
688 /* Print error message if tick really got delayed
689 (more than 5 ticks) */
690 if (timeout_ns < GKI_TICKS_TO_MS(-5) * 1000000)
691 {
692 GKI_ERROR_LOG("tick delayed > 5 slots (%d,%d) -- cpu overload ? ",
693 timeout_ns, GKI_TICKS_TO_MS(-5) * 1000000);
694 }
695 }
696 else
697 {
698 timeout.tv_nsec = timeout_ns;
699 }
700
701 do
702 {
703 /* [u]sleep can't be used because it uses SIGALRM */
704 err = nanosleep(&timeout, &timeout);
705 } while (err < 0 && errno == EINTR);
706
707 /* Increment the GKI time value by one tick and update internal timers */
708 GKI_timer_update(1);
709 }
710 GKI_TRACE("gki_ulinux: Exiting timer_thread");
711 pthread_exit(NULL);
712 return NULL;
713 }
714 #endif
715
716
717 /*****************************************************************************
718 **
719 ** Function gki_set_timer_scheduling
720 **
721 ** Description helper function to set scheduling policy and priority of btdl
722 **
723 ** Returns void
724 **
725 *******************************************************************************/
726
gki_set_timer_scheduling(void)727 static void gki_set_timer_scheduling( void )
728 {
729 pid_t main_pid = getpid();
730 struct sched_param param;
731 int policy;
732
733 policy = sched_getscheduler(main_pid);
734
735 if ( policy != -1 )
736 {
737 GKI_TRACE("gki_set_timer_scheduling(()::scheduler current policy: %d", policy);
738
739 /* ensure highest priority in the system + 2 to allow space for read threads */
740 param.sched_priority = GKI_LINUX_TIMER_TICK_PRIORITY;
741
742 if ( 0!=sched_setscheduler(main_pid, GKI_LINUX_TIMER_POLICY, ¶m ) )
743 {
744 GKI_TRACE("sched_setscheduler() failed with error: %d", errno);
745 }
746 }
747 else
748 {
749 GKI_TRACE( "getscheduler failed: %d", errno);
750 }
751 }
752
753
754 /*****************************************************************************
755 **
756 ** Function GKI_freeze
757 **
758 ** Description Freeze GKI. Relevant only when NO_GKI_RUN_RETURN is defined
759 **
760 ** Returns
761 **
762 *******************************************************************************/
763
GKI_freeze()764 void GKI_freeze()
765 {
766 #ifdef NO_GKI_RUN_RETURN
767 shutdown_timer = 1;
768 pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
769 /* Ensure that the timer thread exits */
770 pthread_join(timer_thread_id, NULL);
771 #endif
772 }
773
774 /*****************************************************************************
775 **
776 ** Function GKI_run
777 **
778 ** Description Main GKI loop
779 **
780 ** Returns
781 **
782 *******************************************************************************/
783
GKI_run(void * p_task_id)784 void GKI_run (void *p_task_id)
785 {
786 struct timespec delay;
787 int err;
788 volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
789
790 #ifndef GKI_NO_TICK_STOP
791 /* adjust btld scheduling scheme now */
792 gki_set_timer_scheduling();
793
794 /* register start stop function which disable timer loop in GKI_run() when no timers are
795 * in any GKI/BTA/BTU this should save power when BTLD is idle! */
796 GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
797 GKI_TRACE( "GKI_run(): Start/Stop GKI_timer_update_registered!" );
798 #endif
799
800 #ifdef NO_GKI_RUN_RETURN
801 pthread_attr_t timer_attr;
802
803 shutdown_timer = 0;
804
805 pthread_attr_init(&timer_attr);
806 if (pthread_create( &timer_thread_id,
807 &timer_attr,
808 timer_thread,
809 NULL) != 0 )
810 {
811 GKI_ERROR_LOG("pthread_create failed to create timer_thread!\n\r");
812 return;
813 }
814
815 #else
816 GKI_TRACE("GKI_run ");
817 for (;;)
818 {
819 do
820 {
821 /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
822 * 1-1000ms heart beat units! */
823 delay.tv_sec = LINUX_SEC / 1000;
824 delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
825
826 /* [u]sleep can't be used because it uses SIGALRM */
827 do
828 {
829 err = nanosleep(&delay, &delay);
830 } while (err < 0 && errno == EINTR);
831
832 /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
833 * e.g. power saving you may want to provide more ticks
834 */
835 GKI_timer_update( 1 );
836 /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
837 } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond );
838
839 /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
840 * block timer main thread till re-armed by */
841
842 GKI_TIMER_TRACE(">>> SUSPENDED GKI_timer_update()" );
843
844 pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
845 pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
846 pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
847
848 /* potentially we need to adjust os gki_cb.com.OSTicks */
849 GKI_TIMER_TRACE(">>> RESTARTED GKI_timer_update(): run_cond: %d",
850 *p_run_cond );
851
852 }
853 #endif
854 return;
855 }
856
857
858 /*******************************************************************************
859 **
860 ** Function GKI_stop
861 **
862 ** Description This function is called to stop
863 ** the tasks and timers when the system is being stopped
864 **
865 ** Returns void
866 **
867 ** NOTE This function is NOT called by the Broadcom stack and
868 ** profiles. If you want to use it in your own implementation,
869 ** put specific code here.
870 **
871 *******************************************************************************/
872
GKI_stop(void)873 void GKI_stop (void)
874 {
875 UINT8 task_id;
876
877 /* gki_queue_timer_cback(FALSE); */
878 /* TODO - add code here if needed*/
879
880 for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
881 {
882 if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
883 {
884 GKI_exit_task(task_id);
885 }
886 }
887 }
888
889
890 /*******************************************************************************
891 **
892 ** Function GKI_wait
893 **
894 ** Description This function is called by tasks to wait for a specific
895 ** event or set of events. The task may specify the duration
896 ** that it wants to wait for, or 0 if infinite.
897 **
898 ** Parameters: flag - (input) the event or set of events to wait for
899 ** timeout - (input) the duration that the task wants to wait
900 ** for the specific events (in system ticks)
901 **
902 **
903 ** Returns the event mask of received events or zero if timeout
904 **
905 *******************************************************************************/
GKI_wait(UINT16 flag,UINT32 timeout)906 UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
907 {
908 UINT16 evt;
909 UINT8 rtask;
910 struct timespec abstime = { 0, 0 };
911
912 int sec;
913 int nano_sec;
914
915 rtask = GKI_get_taskid();
916
917 GKI_TRACE("GKI_wait %d %x %d", (int)rtask, (int)flag, (int)timeout);
918
919 gki_cb.com.OSWaitForEvt[rtask] = flag;
920
921 /* protect OSWaitEvt[rtask] from modification from an other thread */
922 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
923
924 if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
925 {
926 if (timeout)
927 {
928 clock_gettime(CLOCK_MONOTONIC, &abstime);
929
930 /* add timeout */
931 sec = timeout / 1000;
932 nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
933 abstime.tv_nsec += nano_sec;
934 if (abstime.tv_nsec > NSEC_PER_SEC)
935 {
936 abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
937 abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
938 }
939 abstime.tv_sec += sec;
940
941 pthread_cond_timedwait_monotonic(&gki_cb.os.thread_evt_cond[rtask],
942 &gki_cb.os.thread_evt_mutex[rtask], &abstime);
943
944 }
945 else
946 {
947 pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
948 }
949
950 /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
951 e.g. it looks like it is implemented as a counter in which case multiple cond_signal
952 should NOT be lost! */
953
954 /* we are waking up after waiting for some events, so refresh variables
955 no need to call GKI_disable() here as we know that we will have some events as we've been waking
956 up after condition pending or timeout */
957
958 if (gki_cb.com.OSTaskQFirst[rtask][0])
959 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
960 if (gki_cb.com.OSTaskQFirst[rtask][1])
961 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
962 if (gki_cb.com.OSTaskQFirst[rtask][2])
963 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
964 if (gki_cb.com.OSTaskQFirst[rtask][3])
965 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
966
967 if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
968 {
969 gki_cb.com.OSWaitEvt[rtask] = 0;
970 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
971 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
972 return (EVENT_MASK(GKI_SHUTDOWN_EVT));
973 }
974 }
975
976 /* Clear the wait for event mask */
977 gki_cb.com.OSWaitForEvt[rtask] = 0;
978
979 /* Return only those bits which user wants... */
980 evt = gki_cb.com.OSWaitEvt[rtask] & flag;
981
982 /* Clear only those bits which user wants... */
983 gki_cb.com.OSWaitEvt[rtask] &= ~flag;
984
985 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
986 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
987
988 GKI_TRACE("GKI_wait %d %x %d %x done", (int)rtask, (int)flag, (int)timeout, (int)evt);
989 return (evt);
990 }
991
992
993 /*******************************************************************************
994 **
995 ** Function GKI_delay
996 **
997 ** Description This function is called by tasks to sleep unconditionally
998 ** for a specified amount of time. The duration is in milliseconds
999 **
1000 ** Parameters: timeout - (input) the duration in milliseconds
1001 **
1002 ** Returns void
1003 **
1004 *******************************************************************************/
1005
GKI_delay(UINT32 timeout)1006 void GKI_delay (UINT32 timeout)
1007 {
1008 UINT8 rtask = GKI_get_taskid();
1009 struct timespec delay;
1010 int err;
1011
1012 GKI_TRACE("GKI_delay %d %d", (int)rtask, (int)timeout);
1013
1014 delay.tv_sec = timeout / 1000;
1015 delay.tv_nsec = 1000 * 1000 * (timeout%1000);
1016
1017 /* [u]sleep can't be used because it uses SIGALRM */
1018
1019 do {
1020 err = nanosleep(&delay, &delay);
1021 } while (err < 0 && errno ==EINTR);
1022
1023 /* Check if task was killed while sleeping */
1024
1025 /* NOTE : if you do not implement task killing, you do not need this check */
1026
1027 if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
1028 {
1029 }
1030
1031 GKI_TRACE("GKI_delay %d %d done", (int)rtask, (int)timeout);
1032
1033 return;
1034 }
1035
1036
1037 /*******************************************************************************
1038 **
1039 ** Function GKI_send_event
1040 **
1041 ** Description This function is called by tasks to send events to other
1042 ** tasks. Tasks can also send events to themselves.
1043 **
1044 ** Parameters: task_id - (input) The id of the task to which the event has to
1045 ** be sent
1046 ** event - (input) The event that has to be sent
1047 **
1048 **
1049 ** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
1050 **
1051 *******************************************************************************/
1052
GKI_send_event(UINT8 task_id,UINT16 event)1053 UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
1054 {
1055 GKI_TRACE("GKI_send_event %d %x", task_id, event);
1056
1057 /* use efficient coding to avoid pipeline stalls */
1058 if (task_id < GKI_MAX_TASKS)
1059 {
1060 /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
1061 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
1062
1063 /* Set the event bit */
1064 gki_cb.com.OSWaitEvt[task_id] |= event;
1065
1066 pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
1067
1068 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
1069
1070 GKI_TRACE("GKI_send_event %d %x done", task_id, event);
1071 return ( GKI_SUCCESS );
1072 }
1073 GKI_TRACE("############## GKI_send_event FAILED!! ##################");
1074 return (GKI_FAILURE);
1075 }
1076
1077
1078 /*******************************************************************************
1079 **
1080 ** Function GKI_isend_event
1081 **
1082 ** Description This function is called from ISRs to send events to other
1083 ** tasks. The only difference between this function and GKI_send_event
1084 ** is that this function assumes interrupts are already disabled.
1085 **
1086 ** Parameters: task_id - (input) The destination task Id for the event.
1087 ** event - (input) The event flag
1088 **
1089 ** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
1090 **
1091 ** NOTE This function is NOT called by the Broadcom stack and
1092 ** profiles. If you want to use it in your own implementation,
1093 ** put your code here, otherwise you can delete the entire
1094 ** body of the function.
1095 **
1096 *******************************************************************************/
GKI_isend_event(UINT8 task_id,UINT16 event)1097 UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
1098 {
1099 GKI_TRACE("GKI_isend_event %d %x", task_id, event);
1100 GKI_TRACE("GKI_isend_event %d %x done", task_id, event);
1101 return GKI_send_event(task_id, event);
1102 }
1103
1104
1105 /*******************************************************************************
1106 **
1107 ** Function GKI_get_taskid
1108 **
1109 ** Description This function gets the currently running task ID.
1110 **
1111 ** Returns task ID
1112 **
1113 ** NOTE The Broadcom upper stack and profiles may run as a single task.
1114 ** If you only have one GKI task, then you can hard-code this
1115 ** function to return a '1'. Otherwise, you should have some
1116 ** OS-specific method to determine the current task.
1117 **
1118 *******************************************************************************/
GKI_get_taskid(void)1119 UINT8 GKI_get_taskid (void)
1120 {
1121 int i;
1122
1123 pthread_t thread_id = pthread_self( );
1124
1125 GKI_TRACE("GKI_get_taskid %x", (int)thread_id);
1126
1127 for (i = 0; i < GKI_MAX_TASKS; i++) {
1128 if (gki_cb.os.thread_id[i] == thread_id) {
1129 //GKI_TRACE("GKI_get_taskid %x %d done", thread_id, i);
1130 return(i);
1131 }
1132 }
1133
1134 GKI_TRACE("GKI_get_taskid: task id = -1");
1135
1136 return(-1);
1137 }
1138
1139
1140 /*******************************************************************************
1141 **
1142 ** Function GKI_map_taskname
1143 **
1144 ** Description This function gets the task name of the taskid passed as arg.
1145 ** If GKI_MAX_TASKS is passed as arg the currently running task
1146 ** name is returned
1147 **
1148 ** Parameters: task_id - (input) The id of the task whose name is being
1149 ** sought. GKI_MAX_TASKS is passed to get the name of the
1150 ** currently running task.
1151 **
1152 ** Returns pointer to task name
1153 **
1154 ** NOTE this function needs no customization
1155 **
1156 *******************************************************************************/
1157
GKI_map_taskname(UINT8 task_id)1158 INT8 *GKI_map_taskname (UINT8 task_id)
1159 {
1160 GKI_TRACE("GKI_map_taskname %d", task_id);
1161
1162 if (task_id < GKI_MAX_TASKS)
1163 {
1164 GKI_TRACE("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
1165 return (gki_cb.com.OSTName[task_id]);
1166 }
1167 else if (task_id == GKI_MAX_TASKS )
1168 {
1169 return (gki_cb.com.OSTName[GKI_get_taskid()]);
1170 }
1171 else
1172 {
1173 return (INT8*)"BAD";
1174 }
1175 }
1176
1177
1178 /*******************************************************************************
1179 **
1180 ** Function GKI_enable
1181 **
1182 ** Description This function enables interrupts.
1183 **
1184 ** Returns void
1185 **
1186 *******************************************************************************/
GKI_enable(void)1187 void GKI_enable (void)
1188 {
1189 //GKI_TRACE("GKI_enable");
1190 pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
1191 //GKI_TRACE("Leaving GKI_enable");
1192 return;
1193 }
1194
1195
1196 /*******************************************************************************
1197 **
1198 ** Function GKI_disable
1199 **
1200 ** Description This function disables interrupts.
1201 **
1202 ** Returns void
1203 **
1204 *******************************************************************************/
1205
GKI_disable(void)1206 void GKI_disable (void)
1207 {
1208 //GKI_TRACE("GKI_disable");
1209
1210 pthread_mutex_lock(&gki_cb.os.GKI_mutex);
1211
1212 //GKI_TRACE("Leaving GKI_disable");
1213 return;
1214 }
1215
1216
1217 /*******************************************************************************
1218 **
1219 ** Function GKI_exception
1220 **
1221 ** Description This function throws an exception.
1222 ** This is normally only called for a nonrecoverable error.
1223 **
1224 ** Parameters: code - (input) The code for the error
1225 ** msg - (input) The message that has to be logged
1226 **
1227 ** Returns void
1228 **
1229 *******************************************************************************/
1230
GKI_exception(UINT16 code,char * msg)1231 void GKI_exception (UINT16 code, char *msg)
1232 {
1233 UINT8 task_id;
1234 int i = 0;
1235
1236 GKI_ERROR_LOG( "GKI_exception(): Task State Table\n");
1237
1238 for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
1239 {
1240 GKI_ERROR_LOG( "TASK ID [%d] task name [%s] state [%d]\n",
1241 task_id,
1242 gki_cb.com.OSTName[task_id],
1243 gki_cb.com.OSRdyTbl[task_id]);
1244 }
1245
1246 GKI_ERROR_LOG("GKI_exception %d %s", code, msg);
1247 GKI_ERROR_LOG( "\n********************************************************************\n");
1248 GKI_ERROR_LOG( "* GKI_exception(): %d %s\n", code, msg);
1249 GKI_ERROR_LOG( "********************************************************************\n");
1250
1251 #if 0//(GKI_DEBUG == TRUE)
1252 GKI_disable();
1253
1254 if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
1255 {
1256 EXCEPTION_T *pExp;
1257
1258 pExp = &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
1259 pExp->type = code;
1260 pExp->taskid = GKI_get_taskid();
1261 strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
1262 }
1263
1264 GKI_enable();
1265 #endif
1266
1267 GKI_TRACE("GKI_exception %d %s done", code, msg);
1268 return;
1269 }
1270
1271
1272 /*******************************************************************************
1273 **
1274 ** Function GKI_get_time_stamp
1275 **
1276 ** Description This function formats the time into a user area
1277 **
1278 ** Parameters: tbuf - (output) the address to the memory containing the
1279 ** formatted time
1280 **
1281 ** Returns the address of the user area containing the formatted time
1282 ** The format of the time is ????
1283 **
1284 ** NOTE This function is only called by OBEX.
1285 **
1286 *******************************************************************************/
GKI_get_time_stamp(INT8 * tbuf)1287 INT8 *GKI_get_time_stamp (INT8 *tbuf)
1288 {
1289 UINT32 ms_time;
1290 UINT32 s_time;
1291 UINT32 m_time;
1292 UINT32 h_time;
1293 INT8 *p_out = tbuf;
1294
1295 gki_cb.com.OSTicks = times(0);
1296 ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
1297 s_time = ms_time/100; /* 100 Ticks per second */
1298 m_time = s_time/60;
1299 h_time = m_time/60;
1300
1301 ms_time -= s_time*100;
1302 s_time -= m_time*60;
1303 m_time -= h_time*60;
1304
1305 *p_out++ = (INT8)((h_time / 10) + '0');
1306 *p_out++ = (INT8)((h_time % 10) + '0');
1307 *p_out++ = ':';
1308 *p_out++ = (INT8)((m_time / 10) + '0');
1309 *p_out++ = (INT8)((m_time % 10) + '0');
1310 *p_out++ = ':';
1311 *p_out++ = (INT8)((s_time / 10) + '0');
1312 *p_out++ = (INT8)((s_time % 10) + '0');
1313 *p_out++ = ':';
1314 *p_out++ = (INT8)((ms_time / 10) + '0');
1315 *p_out++ = (INT8)((ms_time % 10) + '0');
1316 *p_out++ = ':';
1317 *p_out = 0;
1318
1319 return (tbuf);
1320 }
1321
1322
1323 /*******************************************************************************
1324 **
1325 ** Function GKI_register_mempool
1326 **
1327 ** Description This function registers a specific memory pool.
1328 **
1329 ** Parameters: p_mem - (input) pointer to the memory pool
1330 **
1331 ** Returns void
1332 **
1333 ** NOTE This function is NOT called by the Broadcom stack and
1334 ** profiles. If your OS has different memory pools, you
1335 ** can tell GKI the pool to use by calling this function.
1336 **
1337 *******************************************************************************/
GKI_register_mempool(void * p_mem)1338 void GKI_register_mempool (void *p_mem)
1339 {
1340 gki_cb.com.p_user_mempool = p_mem;
1341
1342 return;
1343 }
1344
1345 /*******************************************************************************
1346 **
1347 ** Function GKI_os_malloc
1348 **
1349 ** Description This function allocates memory
1350 **
1351 ** Parameters: size - (input) The size of the memory that has to be
1352 ** allocated
1353 **
1354 ** Returns the address of the memory allocated, or NULL if failed
1355 **
1356 ** NOTE This function is called by the Broadcom stack when
1357 ** dynamic memory allocation is used. (see dyn_mem.h)
1358 **
1359 *******************************************************************************/
GKI_os_malloc(UINT32 size)1360 void *GKI_os_malloc (UINT32 size)
1361 {
1362 return (malloc(size));
1363 }
1364
1365 /*******************************************************************************
1366 **
1367 ** Function GKI_os_free
1368 **
1369 ** Description This function frees memory
1370 **
1371 ** Parameters: size - (input) The address of the memory that has to be
1372 ** freed
1373 **
1374 ** Returns void
1375 **
1376 ** NOTE This function is NOT called by the Broadcom stack and
1377 ** profiles. It is only called from within GKI if dynamic
1378 **
1379 *******************************************************************************/
GKI_os_free(void * p_mem)1380 void GKI_os_free (void *p_mem)
1381 {
1382 if(p_mem != NULL)
1383 free(p_mem);
1384 return;
1385 }
1386
1387
1388 /*******************************************************************************
1389 **
1390 ** Function GKI_suspend_task()
1391 **
1392 ** Description This function suspends the task specified in the argument.
1393 **
1394 ** Parameters: task_id - (input) the id of the task that has to suspended
1395 **
1396 ** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
1397 **
1398 ** NOTE This function is NOT called by the Broadcom stack and
1399 ** profiles. If you want to implement task suspension capability,
1400 ** put specific code here.
1401 **
1402 *******************************************************************************/
GKI_suspend_task(UINT8 task_id)1403 UINT8 GKI_suspend_task (UINT8 task_id)
1404 {
1405 GKI_TRACE("GKI_suspend_task %d - NOT implemented", task_id);
1406
1407
1408 GKI_TRACE("GKI_suspend_task %d done", task_id);
1409
1410 return (GKI_SUCCESS);
1411 }
1412
1413
1414 /*******************************************************************************
1415 **
1416 ** Function GKI_resume_task()
1417 **
1418 ** Description This function resumes the task specified in the argument.
1419 **
1420 ** Parameters: task_id - (input) the id of the task that has to resumed
1421 **
1422 ** Returns GKI_SUCCESS if all OK
1423 **
1424 ** NOTE This function is NOT called by the Broadcom stack and
1425 ** profiles. If you want to implement task suspension capability,
1426 ** put specific code here.
1427 **
1428 *******************************************************************************/
GKI_resume_task(UINT8 task_id)1429 UINT8 GKI_resume_task (UINT8 task_id)
1430 {
1431 GKI_TRACE("GKI_resume_task %d - NOT implemented", task_id);
1432
1433
1434 GKI_TRACE("GKI_resume_task %d done", task_id);
1435
1436 return (GKI_SUCCESS);
1437 }
1438
1439
1440 /*******************************************************************************
1441 **
1442 ** Function GKI_exit_task
1443 **
1444 ** Description This function is called to stop a GKI task.
1445 **
1446 ** Parameters: task_id - (input) the id of the task that has to be stopped
1447 **
1448 ** Returns void
1449 **
1450 ** NOTE This function is NOT called by the Broadcom stack and
1451 ** profiles. If you want to use it in your own implementation,
1452 ** put specific code here to kill a task.
1453 **
1454 *******************************************************************************/
GKI_exit_task(UINT8 task_id)1455 void GKI_exit_task (UINT8 task_id)
1456 {
1457 GKI_disable();
1458 gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
1459
1460 /* Destroy mutex and condition variable objects */
1461 pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
1462 pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
1463 pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
1464 pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
1465
1466 GKI_enable();
1467
1468 //GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
1469
1470 GKI_INFO("GKI_exit_task %d done", task_id);
1471 return;
1472 }
1473
1474
1475 /*******************************************************************************
1476 **
1477 ** Function GKI_sched_lock
1478 **
1479 ** Description This function is called by tasks to disable scheduler
1480 ** task context switching.
1481 **
1482 ** Returns void
1483 **
1484 ** NOTE This function is NOT called by the Broadcom stack and
1485 ** profiles. If you want to use it in your own implementation,
1486 ** put code here to tell the OS to disable context switching.
1487 **
1488 *******************************************************************************/
GKI_sched_lock(void)1489 void GKI_sched_lock(void)
1490 {
1491 GKI_TRACE("GKI_sched_lock");
1492 return;
1493 }
1494
1495
1496 /*******************************************************************************
1497 **
1498 ** Function GKI_sched_unlock
1499 **
1500 ** Description This function is called by tasks to enable scheduler switching.
1501 **
1502 ** Returns void
1503 **
1504 ** NOTE This function is NOT called by the Broadcom stack and
1505 ** profiles. If you want to use it in your own implementation,
1506 ** put code here to tell the OS to re-enable context switching.
1507 **
1508 *******************************************************************************/
GKI_sched_unlock(void)1509 void GKI_sched_unlock(void)
1510 {
1511 GKI_TRACE("GKI_sched_unlock");
1512 }
1513
1514
1515