• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param)==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, &param);
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, &current);
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, &param ) )
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