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