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
81tGKI_CB   gki_cb;
82#endif
83
84#ifdef NO_GKI_RUN_RETURN
85static pthread_t            timer_thread_id = 0;
86static 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
102typedef 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
114int g_GkiTimerWakeLockOn = 0;
115gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
116
117/*****************************************************************************
118**  Static functions
119******************************************************************************/
120
121/*****************************************************************************
122**  Externs
123******************************************************************************/
124
125extern int acquire_wake_lock(int lock, const char* id);
126extern 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
143void 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
174void 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*******************************************************************************/
218UINT32 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*******************************************************************************/
243UINT8 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
332void 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*******************************************************************************/
404void 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
464void 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
544void 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
607void* 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
727static 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
764void 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
784void 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
873void 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*******************************************************************************/
906UINT16 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
1006void 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
1053UINT8 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*******************************************************************************/
1097UINT8 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*******************************************************************************/
1119UINT8 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
1158INT8 *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*******************************************************************************/
1187void 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
1206void 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
1231void 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*******************************************************************************/
1287INT8 *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*******************************************************************************/
1338void 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*******************************************************************************/
1360void *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*******************************************************************************/
1380void 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*******************************************************************************/
1403UINT8 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*******************************************************************************/
1429UINT8 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*******************************************************************************/
1455void 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*******************************************************************************/
1489void 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*******************************************************************************/
1509void GKI_sched_unlock(void)
1510{
1511    GKI_TRACE("GKI_sched_unlock");
1512}
1513
1514
1515