• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include <errno.h>
19 #include <malloc.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 
23 #define GKI_DEBUG FALSE
24 
25 #include <pthread.h> /* must be 1st header defined  */
26 #include <time.h>
27 #include "bt_trace.h"
28 #include "gki_int.h"
29 #include "gki_target.h"
30 
31 /* Temp android logging...move to android tgt config file */
32 
33 #ifndef LINUX_NATIVE
34 #include <cutils/log.h>
35 #else
36 #define LOGV(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
37 #define LOGE(format, ...) fprintf(stderr, LOG_TAG format, ##__VA_ARGS__)
38 #define LOGI(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
39 
40 #define SCHED_NORMAL 0
41 #define SCHED_FIFO 1
42 #define SCHED_RR 2
43 #define SCHED_BATCH 3
44 
45 #endif
46 
47 /* Define the structure that holds the GKI variables
48 */
49 tGKI_CB gki_cb;
50 
51 #define NANOSEC_PER_MILLISEC (1000000)
52 #define NSEC_PER_SEC (1000 * NANOSEC_PER_MILLISEC)
53 
54 /* works only for 1ms to 1000ms heart beat ranges */
55 #define LINUX_SEC (1000 / TICKS_PER_SEC)
56 // #define GKI_TICK_TIMER_DEBUG
57 
58 #define LOCK(m) pthread_mutex_lock(&m)
59 #define UNLOCK(m) pthread_mutex_unlock(&m)
60 #define INIT(m) pthread_mutex_init(&m, NULL)
61 
62 /* this kind of mutex go into tGKI_OS control block!!!! */
63 /* static pthread_mutex_t GKI_sched_mutex; */
64 /*static pthread_mutex_t thread_delay_mutex;
65 static pthread_cond_t thread_delay_cond;
66 static pthread_mutex_t gki_timer_update_mutex;
67 static pthread_cond_t   gki_timer_update_cond;
68 */
69 #ifdef NO_GKI_RUN_RETURN
70 static pthread_t timer_thread_id = 0;
71 #endif
72 
73 /* For Android */
74 
75 #ifndef GKI_SHUTDOWN_EVT
76 #define GKI_SHUTDOWN_EVT APPL_EVT_7
77 #endif
78 
79 typedef struct {
80   uint8_t task_id;         /* GKI task id */
81   TASKPTR task_entry;      /* Task entry function*/
82   uintptr_t params;        /* Extra params to pass to task entry function */
83   pthread_cond_t* pCond;   /* for android*/
84   pthread_mutex_t* pMutex; /* for android*/
85 } gki_pthread_info_t;
86 gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
87 
88 /*******************************************************************************
89 **
90 ** Function         gki_task_entry
91 **
92 ** Description      entry point of GKI created tasks
93 **
94 ** Returns          void
95 **
96 *******************************************************************************/
gki_task_entry(uintptr_t params)97 void gki_task_entry(uintptr_t params) {
98   pthread_t thread_id = pthread_self();
99   gki_pthread_info_t* p_pthread_info = (gki_pthread_info_t*)params;
100   GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x",
101               p_pthread_info->task_id,
102               gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
103               p_pthread_info->pCond, p_pthread_info->pMutex);
104 
105   gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
106   /* Call the actual thread entry point */
107   (p_pthread_info->task_entry)(p_pthread_info->params);
108 
109   GKI_TRACE_ERROR_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
110   gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
111 
112   pthread_exit(0); /* GKI tasks have no return value */
113 }
114 /* end android */
115 
116 #ifndef ANDROID
GKI_TRACE(char * fmt,...)117 void GKI_TRACE(char* fmt, ...) {
118   LOCK(gki_cb.os.GKI_trace_mutex);
119   va_list ap;
120 
121   va_start(ap, fmt);
122   vfprintf(stderr, fmt, ap);
123   fprintf(stderr, "\n");
124 
125   va_end(ap);
126   UNLOCK(gki_cb.os.GKI_trace_mutex);
127 }
128 #endif
129 
130 /*******************************************************************************
131 **
132 ** Function         GKI_init
133 **
134 ** Description      This function is called once at startup to initialize
135 **                  all the timer structures.
136 **
137 ** Returns          void
138 **
139 *******************************************************************************/
140 
GKI_init(void)141 void GKI_init(void) {
142   pthread_mutexattr_t attr;
143   tGKI_OS* p_os;
144 
145   memset(&gki_cb, 0, sizeof(gki_cb));
146 
147   gki_buffer_init();
148   gki_timers_init();
149   gki_cb.com.OSTicks = (uint32_t)times(0);
150 
151   pthread_mutexattr_init(&attr);
152 
153 #ifndef __CYGWIN__
154   pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
155 #endif
156   p_os = &gki_cb.os;
157   pthread_mutex_init(&p_os->GKI_mutex, &attr);
158 /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
159 #if (GKI_DEBUG == TRUE)
160   pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
161 #endif
162   /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
163   /* pthread_cond_init (&thread_delay_cond, NULL); */
164 
165   /* Initialiase GKI_timer_update suspend variables & mutexes to be in running
166    * state.
167    * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
168   p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
169   pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
170   pthread_cond_init(&p_os->gki_timer_cond, NULL);
171 }
172 
173 /*******************************************************************************
174 **
175 ** Function         GKI_get_os_tick_count
176 **
177 ** Description      This function is called to retrieve the native OS system
178 **                  tick.
179 **
180 ** Returns          Tick count of native OS.
181 **
182 *******************************************************************************/
GKI_get_os_tick_count(void)183 uint32_t GKI_get_os_tick_count(void) {
184   /* TODO - add any OS specific code here
185   **/
186   return (gki_cb.com.OSTicks);
187 }
188 
189 /*******************************************************************************
190 **
191 ** Function         GKI_create_task
192 **
193 ** Description      This function is called to create a new OSS task.
194 **
195 ** Parameters:      task_entry  - (input) pointer to the entry function of the
196 **                                        task
197 **                  task_id     - (input) Task id is mapped to priority
198 **                  taskname    - (input) name given to the task
199 **                  stack       - (input) pointer to the top of the stack
200 **                                        (highest memory location)
201 **                  stacksize   - (input) size of the stack allocated for the
202 **                                        task
203 **
204 ** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
205 **
206 ** NOTE             This function take some parameters that may not be needed
207 **                  by your particular OS. They are here for compatability
208 **                  of the function prototype.
209 **
210 *******************************************************************************/
GKI_create_task(TASKPTR task_entry,uint8_t task_id,int8_t * taskname,uint16_t * stack,uint16_t stacksize,void * pCondVar,void * pMutex)211 uint8_t GKI_create_task(TASKPTR task_entry, uint8_t task_id, int8_t* taskname,
212                         uint16_t* stack, uint16_t stacksize, void* pCondVar,
213                         void* pMutex) {
214   uint16_t i;
215   uint8_t* p;
216   struct sched_param param;
217   int policy, ret = 0;
218   pthread_condattr_t attr;
219   pthread_attr_t attr1;
220 
221   pthread_condattr_init(&attr);
222   pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
223   GKI_TRACE_5(
224       "GKI_create_task func=0x%x  id=%d  name=%s  stack=0x%x  stackSize=%d",
225       task_entry, task_id, taskname, stack, stacksize);
226 
227   if (task_id >= GKI_MAX_TASKS) {
228     GKI_TRACE_0("Error! task ID > max task allowed");
229     return (GKI_FAILURE);
230   }
231 
232   gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
233   gki_cb.com.OSTName[task_id] = taskname;
234   gki_cb.com.OSWaitTmr[task_id] = 0;
235   gki_cb.com.OSWaitEvt[task_id] = 0;
236 
237   /* Initialize mutex and condition variable objects for events and timeouts */
238   pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
239   pthread_cond_init(&gki_cb.os.thread_evt_cond[task_id], &attr);
240   pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
241   pthread_cond_init(&gki_cb.os.thread_timeout_cond[task_id], &attr);
242 
243   pthread_attr_init(&attr1);
244 /* by default, pthread creates a joinable thread */
245 #if (FALSE == GKI_PTHREAD_JOINABLE)
246   pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
247 
248   GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar,
249               pMutex);
250 #else
251   GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
252 #endif
253 
254   /* On Android, the new tasks starts running before
255    * 'gki_cb.os.thread_id[task_id]' is initialized */
256   /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id]
257    * for it calls GKI_wait */
258   gki_pthread_info[task_id].task_id = task_id;
259   gki_pthread_info[task_id].task_entry = task_entry;
260   gki_pthread_info[task_id].params = 0;
261   gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
262   gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
263 
264   ret = pthread_create(&gki_cb.os.thread_id[task_id], &attr1,
265                        (void*)gki_task_entry, &gki_pthread_info[task_id]);
266 
267   if (ret != 0) {
268     GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
269     return GKI_FAILURE;
270   }
271 
272   if (pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param) ==
273       0) {
274 #if (PBS_SQL_TASK == TRUE)
275     if (task_id == PBS_SQL_TASK) {
276       GKI_TRACE_0("PBS SQL lowest priority task");
277       policy = SCHED_NORMAL;
278     } else
279 #endif
280     {
281       policy = SCHED_RR;
282       param.sched_priority = 30 - task_id - 2;
283     }
284     pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
285   }
286 
287   GKI_TRACE_6("Leaving GKI_create_task %x %d %x %s %x %d", task_entry, task_id,
288               gki_cb.os.thread_id[task_id], taskname, stack, stacksize);
289 
290   return (GKI_SUCCESS);
291 }
292 
293 /*******************************************************************************
294 **
295 ** Function         GKI_shutdown
296 **
297 ** Description      shutdowns the GKI tasks/threads in from max task id to 0 and
298 **                  frees pthread resources!
299 **                  IMPORTANT: in case of join method, GKI_shutdown must be
300 **                  called outside a GKI thread context!
301 **
302 ** Returns          void
303 **
304 *******************************************************************************/
305 #define WAKE_LOCK_ID "brcm_nfca"
306 #define PARTIAL_WAKE_LOCK 1
307 extern int acquire_wake_lock(int lock, const char* id);
308 extern int release_wake_lock(const char* id);
309 
GKI_shutdown(void)310 void GKI_shutdown(void) {
311   uint8_t task_id;
312   volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
313   int oldCOnd = 0;
314 #if (FALSE == GKI_PTHREAD_JOINABLE)
315   int i = 0;
316 #else
317   int result;
318 #endif
319 
320   /* release threads and set as TASK_DEAD. going from low to high priority fixes
321    * GKI_exception problem due to btu->hci sleep request events  */
322   for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--) {
323     if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD) {
324       gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
325 
326       /* paranoi settings, make sure that we do not execute any mailbox events
327        */
328       gki_cb.com.OSWaitEvt[task_id - 1] &=
329           ~(TASK_MBOX_0_EVT_MASK | TASK_MBOX_1_EVT_MASK | TASK_MBOX_2_EVT_MASK |
330             TASK_MBOX_3_EVT_MASK);
331       GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
332 
333 #if (FALSE == GKI_PTHREAD_JOINABLE)
334       i = 0;
335 
336       while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
337         usleep(100 * 1000);
338 #else
339       /* wait for proper Arnold Schwarzenegger task state */
340       result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
341       if (result < 0) {
342         GKI_TRACE_1("pthread_join() FAILED: result: %d", result);
343       }
344 #endif
345       GKI_TRACE_1("GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
346       GKI_exit_task(task_id - 1);
347     }
348   }
349 
350   /* Destroy mutex and condition variable objects */
351   pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
352 /*    pthread_mutex_destroy(&GKI_sched_mutex); */
353 #if (GKI_DEBUG == TRUE)
354   pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
355 #endif
356 /*    pthread_mutex_destroy(&thread_delay_mutex);
357  pthread_cond_destroy (&thread_delay_cond); */
358 #if (FALSE == GKI_PTHREAD_JOINABLE)
359   i = 0;
360 #endif
361 
362 #ifdef NO_GKI_RUN_RETURN
363   shutdown_timer = 1;
364 #endif
365   if (gki_cb.os.gki_timer_wake_lock_on) {
366     GKI_TRACE_0("GKI_shutdown :  release_wake_lock(brcm_btld)");
367     release_wake_lock(WAKE_LOCK_ID);
368     gki_cb.os.gki_timer_wake_lock_on = 0;
369   }
370   oldCOnd = *p_run_cond;
371   *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
372   if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
373     pthread_cond_signal(&gki_cb.os.gki_timer_cond);
374 }
375 
376 /*******************************************************************************
377  **
378  ** Function        GKI_run
379  **
380  ** Description     This function runs a task
381  **
382  ** Parameters:     start: TRUE start system tick (again), FALSE stop
383  **
384  ** Returns         void
385  **
386  ******************************************************************************/
gki_system_tick_start_stop_cback(bool start)387 void gki_system_tick_start_stop_cback(bool start) {
388   tGKI_OS* p_os = &gki_cb.os;
389   volatile int* p_run_cond = &p_os->no_timer_suspend;
390   static volatile int wake_lock_count;
391   if (start == false) {
392     /* this can lead to a race condition. however as we only read this variable
393      * in the timer loop
394      * we should be fine with this approach. otherwise uncomment below mutexes.
395      */
396     /* GKI_disable(); */
397     *p_run_cond = GKI_TIMER_TICK_STOP_COND;
398 /* GKI_enable(); */
399 #ifdef GKI_TICK_TIMER_DEBUG
400     BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
401                ">>> STOP GKI_timer_update(), wake_lock_count:%d",
402                --wake_lock_count);
403 #endif
404     release_wake_lock(WAKE_LOCK_ID);
405     gki_cb.os.gki_timer_wake_lock_on = 0;
406   } else {
407     /* restart GKI_timer_update() loop */
408     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
409     gki_cb.os.gki_timer_wake_lock_on = 1;
410     *p_run_cond = GKI_TIMER_TICK_RUN_COND;
411     pthread_mutex_lock(&p_os->gki_timer_mutex);
412     pthread_cond_signal(&p_os->gki_timer_cond);
413     pthread_mutex_unlock(&p_os->gki_timer_mutex);
414 
415 #ifdef GKI_TICK_TIMER_DEBUG
416     BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
417                ">>> START GKI_timer_update(), wake_lock_count:%d",
418                ++wake_lock_count);
419 #endif
420   }
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         timer_thread
426 **
427 ** Description      Timer thread
428 **
429 ** Parameters:      id  - (input) timer ID
430 **
431 ** Returns          void
432 **
433 *******************************************************************************/
434 #ifdef NO_GKI_RUN_RETURN
timer_thread(signed long id)435 void timer_thread(signed long id) {
436   GKI_TRACE_1("%s enter", __func__);
437   struct timespec delay;
438   int timeout = 1000; /* 10  ms per system tick  */
439   int err;
440 
441   while (!shutdown_timer) {
442     delay.tv_sec = timeout / 1000;
443     delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
444 
445     /* [u]sleep can't be used because it uses SIGALRM */
446 
447     do {
448       err = nanosleep(&delay, &delay);
449     } while (err < 0 && errno == EINTR);
450 
451     GKI_timer_update(1);
452   }
453   GKI_TRACE_ERROR_1("%s exit", __func__);
454   pthread_exit(NULL);
455 }
456 #endif
457 
458 /*******************************************************************************
459 **
460 ** Function         GKI_run
461 **
462 ** Description      This function runs a task
463 **
464 ** Parameters:      p_task_id  - (input) pointer to task id
465 **
466 ** Returns          void
467 **
468 ** NOTE             This function is only needed for operating systems where
469 **                  starting a task is a 2-step process. Most OS's do it in
470 **                  one step, If your OS does it in one step, this function
471 **                  should be empty.
472 *******************************************************************************/
GKI_run(void * p_task_id)473 void GKI_run(void* p_task_id) {
474   GKI_TRACE_1("%s enter", __func__);
475   struct timespec delay;
476   int err = 0;
477   volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
478 
479 #ifndef GKI_NO_TICK_STOP
480   /* register start stop function which disable timer loop in GKI_run() when no
481    * timers are
482    * in any GKI/BTA/BTU this should save power when BTLD is idle! */
483   GKI_timer_queue_register_callback(gki_system_tick_start_stop_cback);
484   APPL_TRACE_DEBUG0("GKI_run(): Start/Stop GKI_timer_update_registered!");
485 #endif
486 
487 #ifdef NO_GKI_RUN_RETURN
488   GKI_TRACE_0("GKI_run == NO_GKI_RUN_RETURN");
489   pthread_attr_t timer_attr;
490 
491   shutdown_timer = 0;
492 
493   pthread_attr_init(&timer_attr);
494   pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
495   if (pthread_create(&timer_thread_id, &timer_attr, timer_thread, NULL) != 0) {
496     GKI_TRACE_0("GKI_run: pthread_create failed to create timer_thread!");
497     return GKI_FAILURE;
498   }
499 #else
500   GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond);
501   for (; GKI_TIMER_TICK_EXIT_COND != *p_run_cond;) {
502     do {
503       /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this
504        * formula works only for
505        * 1-1000ms heart beat units! */
506       delay.tv_sec = LINUX_SEC / 1000;
507       delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
508 
509       /* [u]sleep can't be used because it uses SIGALRM */
510       do {
511         err = nanosleep(&delay, &delay);
512       } while (err < 0 && errno == EINTR);
513 
514       if (GKI_TIMER_TICK_RUN_COND != *p_run_cond) break;  // GKI has shutdown
515 
516       /* the unit should be alsways 1 (1 tick). only if you vary for some reason
517        * heart beat tick
518        * e.g. power saving you may want to provide more ticks
519        */
520       GKI_timer_update(1);
521       /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d,
522        * tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
523     } while (GKI_TIMER_TICK_RUN_COND == *p_run_cond);
524 
525 /* currently on reason to exit above loop is no_timer_suspend ==
526  * GKI_TIMER_TICK_STOP_COND
527  * block timer main thread till re-armed by  */
528 #ifdef GKI_TICK_TIMER_DEBUG
529     BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
530                ">>> SUSPENDED GKI_timer_update()");
531 #endif
532     if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
533       GKI_TRACE_1("%s waiting timer mutex", __func__);
534       pthread_mutex_lock(&gki_cb.os.gki_timer_mutex);
535       pthread_cond_wait(&gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex);
536       pthread_mutex_unlock(&gki_cb.os.gki_timer_mutex);
537       GKI_TRACE_1("%s exited timer mutex", __func__);
538     }
539 /* potentially we need to adjust os gki_cb.com.OSTicks */
540 
541 #ifdef GKI_TICK_TIMER_DEBUG
542     BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
543                ">>> RESTARTED GKI_timer_update(): run_cond: %d", *p_run_cond);
544 #endif
545   } /* for */
546 #endif
547   GKI_TRACE_1("%s exit", __func__);
548 }
549 
550 /*******************************************************************************
551 **
552 ** Function         GKI_stop
553 **
554 ** Description      This function is called to stop
555 **                  the tasks and timers when the system is being stopped
556 **
557 ** Returns          void
558 **
559 ** NOTE             This function is NOT called by the Widcomm stack and
560 **                  profiles. If you want to use it in your own implementation,
561 **                  put specific code here.
562 **
563 *******************************************************************************/
GKI_stop(void)564 void GKI_stop(void) {
565   uint8_t task_id;
566 
567   /*  gki_queue_timer_cback(FALSE); */
568   /* TODO - add code here if needed*/
569 
570   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
571     if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD) {
572       GKI_exit_task(task_id);
573     }
574   }
575 }
576 
577 /*******************************************************************************
578 **
579 ** Function         GKI_wait
580 **
581 ** Description      This function is called by tasks to wait for a specific
582 **                  event or set of events. The task may specify the duration
583 **                  that it wants to wait for, or 0 if infinite.
584 **
585 ** Parameters:      flag -    (input) the event or set of events to wait for
586 **                  timeout - (input) the duration that the task wants to wait
587 **                                    for the specific events (in system ticks)
588 **
589 **
590 ** Returns          the event mask of received events or zero if timeout
591 **
592 *******************************************************************************/
GKI_wait(uint16_t flag,uint32_t timeout)593 uint16_t GKI_wait(uint16_t flag, uint32_t timeout) {
594   uint16_t evt;
595   uint8_t rtask;
596   struct timespec abstime = {0, 0};
597   int sec;
598   int nano_sec;
599 
600   rtask = GKI_get_taskid();
601   GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
602   if (rtask >= GKI_MAX_TASKS) {
603     GKI_TRACE_ERROR_3("%s() Exiting thread; rtask %d >= %d", __func__, rtask,
604                       GKI_MAX_TASKS);
605     pthread_exit(NULL);
606     return 0;
607   }
608 
609   gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
610   if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
611     int ret;
612     GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask,
613                 p_pthread_info->pCond, p_pthread_info->pMutex);
614     ret = pthread_mutex_lock(p_pthread_info->pMutex);
615     ret = pthread_cond_signal(p_pthread_info->pCond);
616     ret = pthread_mutex_unlock(p_pthread_info->pMutex);
617     p_pthread_info->pMutex = NULL;
618     p_pthread_info->pCond = NULL;
619   }
620   gki_cb.com.OSWaitForEvt[rtask] = flag;
621 
622   /* protect OSWaitEvt[rtask] from modification from an other thread */
623   pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
624 
625 #if 0 /* for clean scheduling we probably should always call \
626          pthread_cond_wait() */
627     /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
628      has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
629      the cond is met, it will exit immediately (depending on schedulling) */
630     if (gki_cb.com.OSTaskQFirst[rtask][0])
631     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
632     if (gki_cb.com.OSTaskQFirst[rtask][1])
633     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
634     if (gki_cb.com.OSTaskQFirst[rtask][2])
635     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
636     if (gki_cb.com.OSTaskQFirst[rtask][3])
637     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
638 #endif
639 
640   if (!(gki_cb.com.OSWaitEvt[rtask] & flag)) {
641     if (timeout) {
642       //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from
643       //            milliseconds to ticks */
644 
645       /* get current system time */
646       //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
647       //            abstime.tv_sec = currSysTime.time;
648       //            abstime.tv_nsec = NANOSEC_PER_MILLISEC *
649       //            currSysTime.millitm;
650       clock_gettime(CLOCK_MONOTONIC, &abstime);
651 
652       /* add timeout */
653       sec = timeout / 1000;
654       nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
655       abstime.tv_nsec += nano_sec;
656       if (abstime.tv_nsec > NSEC_PER_SEC) {
657         abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
658         abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
659       }
660       abstime.tv_sec += sec;
661 
662       pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
663                              &gki_cb.os.thread_evt_mutex[rtask], &abstime);
664 
665     } else {
666       pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask],
667                         &gki_cb.os.thread_evt_mutex[rtask]);
668     }
669 
670     /* TODO: check, this is probably neither not needed depending on
671      phtread_cond_wait() implmentation,
672      e.g. it looks like it is implemented as a counter in which case multiple
673      cond_signal
674      should NOT be lost! */
675     // we are waking up after waiting for some events, so refresh variables
676     // no need to call GKI_disable() here as we know that we will have some
677     // events as we've been waking up after condition pending or timeout
678     if (gki_cb.com.OSTaskQFirst[rtask][0])
679       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
680     if (gki_cb.com.OSTaskQFirst[rtask][1])
681       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
682     if (gki_cb.com.OSTaskQFirst[rtask][2])
683       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
684     if (gki_cb.com.OSTaskQFirst[rtask][3])
685       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
686 
687     if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
688       gki_cb.com.OSWaitEvt[rtask] = 0;
689       /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond
690        * is met */
691       pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
692       GKI_TRACE_ERROR_1("GKI TASK_DEAD received. exit thread %d...", rtask);
693 
694       gki_cb.os.thread_id[rtask] = 0;
695       pthread_exit(NULL);
696       return (EVENT_MASK(GKI_SHUTDOWN_EVT));
697     }
698   }
699 
700   /* Clear the wait for event mask */
701   gki_cb.com.OSWaitForEvt[rtask] = 0;
702 
703   /* Return only those bits which user wants... */
704   evt = gki_cb.com.OSWaitEvt[rtask] & flag;
705 
706   /* Clear only those bits which user wants... */
707   gki_cb.com.OSWaitEvt[rtask] &= ~flag;
708 
709   /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when
710    * cond is met */
711   pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
712   GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
713 
714   return (evt);
715 }
716 
717 /*******************************************************************************
718 **
719 ** Function         GKI_delay
720 **
721 ** Description      This function is called by tasks to sleep unconditionally
722 **                  for a specified amount of time. The duration is in
723 **                  milliseconds
724 **
725 ** Parameters:      timeout -    (input) the duration in milliseconds
726 **
727 ** Returns          void
728 **
729 *******************************************************************************/
730 
GKI_delay(uint32_t timeout)731 void GKI_delay(uint32_t timeout) {
732   uint8_t rtask = GKI_get_taskid();
733   struct timespec delay;
734   int err;
735 
736   GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
737 
738   delay.tv_sec = timeout / 1000;
739   delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
740 
741   /* [u]sleep can't be used because it uses SIGALRM */
742 
743   do {
744     err = nanosleep(&delay, &delay);
745   } while (err < 0 && errno == EINTR);
746 
747   /* Check if task was killed while sleeping */
748   /* NOTE
749   **      if you do not implement task killing, you do not
750   **      need this check.
751   */
752   if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
753   }
754 
755   GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
756   return;
757 }
758 
759 /*******************************************************************************
760 **
761 ** Function         GKI_send_event
762 **
763 ** Description      This function is called by tasks to send events to other
764 **                  tasks. Tasks can also send events to themselves.
765 **
766 ** Parameters:      task_id -  (input) The id of the task to which the event has
767 **                                     to be sent
768 **                  event   -  (input) The event that has to be sent
769 **
770 **
771 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
772 **
773 *******************************************************************************/
GKI_send_event(uint8_t task_id,uint16_t event)774 uint8_t GKI_send_event(uint8_t task_id, uint16_t event) {
775   GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
776 
777   /* use efficient coding to avoid pipeline stalls */
778   if (task_id < GKI_MAX_TASKS) {
779     /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
780     pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
781 
782     /* Set the event bit */
783     gki_cb.com.OSWaitEvt[task_id] |= event;
784 
785     pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
786 
787     pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
788 
789     GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
790     return (GKI_SUCCESS);
791   }
792   return (GKI_FAILURE);
793 }
794 
795 /*******************************************************************************
796 **
797 ** Function         GKI_isend_event
798 **
799 ** Description      This function is called from ISRs to send events to other
800 **                  tasks. The only difference between this function and
801 **                  GKI_send_event is that this function assumes interrupts are
802 **                  already disabled.
803 **
804 ** Parameters:      task_id -  (input) The destination task Id for the event.
805 **                  event   -  (input) The event flag
806 **
807 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
808 **
809 ** NOTE             This function is NOT called by the Widcomm stack and
810 **                  profiles. If you want to use it in your own implementation,
811 **                  put your code here, otherwise you can delete the entire
812 **                  body of the function.
813 **
814 *******************************************************************************/
GKI_isend_event(uint8_t task_id,uint16_t event)815 uint8_t GKI_isend_event(uint8_t task_id, uint16_t event) {
816   GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
817   GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
818   return GKI_send_event(task_id, event);
819 }
820 
821 /*******************************************************************************
822 **
823 ** Function         GKI_get_taskid
824 **
825 ** Description      This function gets the currently running task ID.
826 **
827 ** Returns          task ID
828 **
829 ** NOTE             The Widcomm upper stack and profiles may run as a single
830 **                  task. If you only have one GKI task, then you can hard-code
831 **                  this function to return a '1'. Otherwise, you should have
832 **                  some OS-specific method to determine the current task.
833 **
834 *******************************************************************************/
GKI_get_taskid(void)835 uint8_t GKI_get_taskid(void) {
836   int i;
837 
838   pthread_t thread_id = pthread_self();
839   for (i = 0; i < GKI_MAX_TASKS; i++) {
840     if (gki_cb.os.thread_id[i] == thread_id) {
841       GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
842       return (i);
843     }
844   }
845 
846   GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
847 
848   return (-1);
849 }
850 
851 /*******************************************************************************
852 **
853 ** Function         GKI_map_taskname
854 **
855 ** Description      This function gets the task name of the taskid passed as
856 **                  arg. If GKI_MAX_TASKS is passed as arg the currently running
857 **                  task name is returned
858 **
859 ** Parameters:      task_id -  (input) The id of the task whose name is being
860 **                  sought. GKI_MAX_TASKS is passed to get the name of the
861 **                  currently running task.
862 **
863 ** Returns          pointer to task name
864 **
865 ** NOTE             this function needs no customization
866 **
867 *******************************************************************************/
GKI_map_taskname(uint8_t task_id)868 int8_t* GKI_map_taskname(uint8_t task_id) {
869   GKI_TRACE_1("GKI_map_taskname %d", task_id);
870 
871   if (task_id < GKI_MAX_TASKS) {
872     GKI_TRACE_2("GKI_map_taskname %d %s done", task_id,
873                 gki_cb.com.OSTName[task_id]);
874     return (gki_cb.com.OSTName[task_id]);
875   } else if (task_id == GKI_MAX_TASKS) {
876     return (gki_cb.com.OSTName[GKI_get_taskid()]);
877   } else {
878     return (int8_t*)"BAD";
879   }
880 }
881 
882 /*******************************************************************************
883 **
884 ** Function         GKI_enable
885 **
886 ** Description      This function enables interrupts.
887 **
888 ** Returns          void
889 **
890 *******************************************************************************/
GKI_enable(void)891 void GKI_enable(void) {
892   GKI_TRACE_0("GKI_enable");
893   pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
894   /* 	pthread_mutex_xx is nesting save, no need for this: already_disabled =
895    * 0; */
896   GKI_TRACE_0("Leaving GKI_enable");
897   return;
898 }
899 
900 /*******************************************************************************
901 **
902 ** Function         GKI_disable
903 **
904 ** Description      This function disables interrupts.
905 **
906 ** Returns          void
907 **
908 *******************************************************************************/
909 
GKI_disable(void)910 void GKI_disable(void) {
911   // GKI_TRACE_0("GKI_disable");
912 
913   /*	pthread_mutex_xx is nesting save, no need for this: if
914      (!already_disabled) {
915       already_disabled = 1; */
916   pthread_mutex_lock(&gki_cb.os.GKI_mutex);
917   /*  } */
918   // GKI_TRACE_0("Leaving GKI_disable");
919   return;
920 }
921 
922 /*******************************************************************************
923 **
924 ** Function         GKI_exception
925 **
926 ** Description      This function throws an exception.
927 **                  This is normally only called for a nonrecoverable error.
928 **
929 ** Parameters:      code    -  (input) The code for the error
930 **                  msg     -  (input) The message that has to be logged
931 **
932 ** Returns          void
933 **
934 *******************************************************************************/
935 
GKI_exception(uint16_t code,char * msg)936 void GKI_exception(uint16_t code, char* msg) {
937   uint8_t task_id;
938   int i = 0;
939 
940   GKI_TRACE_ERROR_0("GKI_exception(): Task State Table");
941 
942   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
943     GKI_TRACE_ERROR_3("TASK ID [%d] task name [%s] state [%d]", task_id,
944                       gki_cb.com.OSTName[task_id],
945                       gki_cb.com.OSRdyTbl[task_id]);
946   }
947 
948   GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
949   GKI_TRACE_ERROR_0(
950       "********************************************************************");
951   GKI_TRACE_ERROR_2("* GKI_exception(): %d %s", code, msg);
952   GKI_TRACE_ERROR_0(
953       "********************************************************************");
954 
955 #if (GKI_DEBUG == TRUE)
956   GKI_disable();
957 
958   if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION) {
959     EXCEPTION_T* pExp;
960 
961     pExp = &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
962     pExp->type = code;
963     pExp->taskid = GKI_get_taskid();
964     strncpy((char*)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
965   }
966 
967   GKI_enable();
968 #endif
969 
970   GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
971 
972   return;
973 }
974 
975 /*******************************************************************************
976 **
977 ** Function         GKI_get_time_stamp
978 **
979 ** Description      This function formats the time into a user area
980 **
981 ** Parameters:      tbuf -  (output) the address to the memory containing the
982 **                  formatted time
983 **
984 ** Returns          the address of the user area containing the formatted time
985 **                  The format of the time is ????
986 **
987 ** NOTE             This function is only called by OBEX.
988 **
989 *******************************************************************************/
GKI_get_time_stamp(int8_t * tbuf)990 int8_t* GKI_get_time_stamp(int8_t* tbuf) {
991   uint32_t ms_time;
992   uint32_t s_time;
993   uint32_t m_time;
994   uint32_t h_time;
995   int8_t* p_out = tbuf;
996 
997   gki_cb.com.OSTicks = times(0);
998   ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
999   s_time = ms_time / 100; /* 100 Ticks per second */
1000   m_time = s_time / 60;
1001   h_time = m_time / 60;
1002 
1003   ms_time -= s_time * 100;
1004   s_time -= m_time * 60;
1005   m_time -= h_time * 60;
1006 
1007   *p_out++ = (int8_t)((h_time / 10) + '0');
1008   *p_out++ = (int8_t)((h_time % 10) + '0');
1009   *p_out++ = ':';
1010   *p_out++ = (int8_t)((m_time / 10) + '0');
1011   *p_out++ = (int8_t)((m_time % 10) + '0');
1012   *p_out++ = ':';
1013   *p_out++ = (int8_t)((s_time / 10) + '0');
1014   *p_out++ = (int8_t)((s_time % 10) + '0');
1015   *p_out++ = ':';
1016   *p_out++ = (int8_t)((ms_time / 10) + '0');
1017   *p_out++ = (int8_t)((ms_time % 10) + '0');
1018   *p_out++ = ':';
1019   *p_out = 0;
1020 
1021   return (tbuf);
1022 }
1023 
1024 /*******************************************************************************
1025 **
1026 ** Function         GKI_register_mempool
1027 **
1028 ** Description      This function registers a specific memory pool.
1029 **
1030 ** Parameters:      p_mem -  (input) pointer to the memory pool
1031 **
1032 ** Returns          void
1033 **
1034 ** NOTE             This function is NOT called by the Widcomm stack and
1035 **                  profiles. If your OS has different memory pools, you
1036 **                  can tell GKI the pool to use by calling this function.
1037 **
1038 *******************************************************************************/
GKI_register_mempool(void * p_mem)1039 void GKI_register_mempool(void* p_mem) {
1040   gki_cb.com.p_user_mempool = p_mem;
1041 
1042   return;
1043 }
1044 
1045 /*******************************************************************************
1046 **
1047 ** Function         GKI_os_malloc
1048 **
1049 ** Description      This function allocates memory
1050 **
1051 ** Parameters:      size -  (input) The size of the memory that has to be
1052 **                  allocated
1053 **
1054 ** Returns          the address of the memory allocated, or NULL if failed
1055 **
1056 ** NOTE             This function is called by the Widcomm stack when
1057 **                  dynamic memory allocation is used.
1058 **
1059 *******************************************************************************/
GKI_os_malloc(uint32_t size)1060 void* GKI_os_malloc(uint32_t size) { return (malloc(size)); }
1061 
1062 /*******************************************************************************
1063 **
1064 ** Function         GKI_os_free
1065 **
1066 ** Description      This function frees memory
1067 **
1068 ** Parameters:      size -  (input) The address of the memory that has to be
1069 **                  freed
1070 **
1071 ** Returns          void
1072 **
1073 ** NOTE             This function is NOT called by the Widcomm stack and
1074 **                  profiles. It is only called from within GKI if dynamic
1075 **
1076 *******************************************************************************/
GKI_os_free(void * p_mem)1077 void GKI_os_free(void* p_mem) {
1078   if (p_mem != NULL) free(p_mem);
1079   return;
1080 }
1081 
1082 /*******************************************************************************
1083 **
1084 ** Function         GKI_suspend_task()
1085 **
1086 ** Description      This function suspends the task specified in the argument.
1087 **
1088 ** Parameters:      task_id  - (input) the id of the task that has to suspended
1089 **
1090 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
1091 **
1092 ** NOTE             This function is NOT called by the Widcomm stack and
1093 **                  profiles. If you want to implement task suspension
1094 **                  capability, put specific code here.
1095 **
1096 *******************************************************************************/
GKI_suspend_task(uint8_t task_id)1097 uint8_t GKI_suspend_task(uint8_t task_id) {
1098   GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
1099 
1100   GKI_TRACE_1("GKI_suspend_task %d done", task_id);
1101 
1102   return (GKI_SUCCESS);
1103 }
1104 
1105 /*******************************************************************************
1106 **
1107 ** Function         GKI_resume_task()
1108 **
1109 ** Description      This function resumes the task specified in the argument.
1110 **
1111 ** Parameters:      task_id  - (input) the id of the task that has to resumed
1112 **
1113 ** Returns          GKI_SUCCESS if all OK
1114 **
1115 ** NOTE             This function is NOT called by the Widcomm stack and
1116 **                  profiles. If you want to implement task suspension
1117 **                  capability, put specific code here.
1118 **
1119 *******************************************************************************/
GKI_resume_task(uint8_t task_id)1120 uint8_t GKI_resume_task(uint8_t task_id) {
1121   GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
1122 
1123   GKI_TRACE_1("GKI_resume_task %d done", task_id);
1124 
1125   return (GKI_SUCCESS);
1126 }
1127 
1128 /*******************************************************************************
1129 **
1130 ** Function         GKI_exit_task
1131 **
1132 ** Description      This function is called to stop a GKI task.
1133 **
1134 ** Parameters:      task_id  - (input) the id of the task that has to be stopped
1135 **
1136 ** Returns          void
1137 **
1138 ** NOTE             This function is NOT called by the Widcomm stack and
1139 **                  profiles. If you want to use it in your own implementation,
1140 **                  put specific code here to kill a task.
1141 **
1142 *******************************************************************************/
GKI_exit_task(uint8_t task_id)1143 void GKI_exit_task(uint8_t task_id) {
1144   GKI_disable();
1145   gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
1146 
1147   /* Destroy mutex and condition variable objects */
1148   pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
1149   pthread_cond_destroy(&gki_cb.os.thread_evt_cond[task_id]);
1150   pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
1151   pthread_cond_destroy(&gki_cb.os.thread_timeout_cond[task_id]);
1152 
1153   GKI_enable();
1154 
1155   // GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
1156 
1157   GKI_TRACE_1("GKI_exit_task %d done", task_id);
1158   return;
1159 }
1160 
1161 /*******************************************************************************
1162 **
1163 ** Function         GKI_sched_lock
1164 **
1165 ** Description      This function is called by tasks to disable scheduler
1166 **                  task context switching.
1167 **
1168 ** Returns          void
1169 **
1170 ** NOTE             This function is NOT called by the Widcomm stack and
1171 **                  profiles. If you want to use it in your own implementation,
1172 **                  put code here to tell the OS to disable context switching.
1173 **
1174 *******************************************************************************/
GKI_sched_lock(void)1175 void GKI_sched_lock(void) {
1176   GKI_TRACE_0("GKI_sched_lock");
1177   GKI_disable();
1178   return;
1179 }
1180 
1181 /*******************************************************************************
1182 **
1183 ** Function         GKI_sched_unlock
1184 **
1185 ** Description      This function is called by tasks to enable scheduler
1186 **                  switching.
1187 **
1188 ** Returns          void
1189 **
1190 ** NOTE             This function is NOT called by the Widcomm stack and
1191 **                  profiles. If you want to use it in your own implementation,
1192 **                  put code here to tell the OS to re-enable context switching.
1193 **
1194 *******************************************************************************/
GKI_sched_unlock(void)1195 void GKI_sched_unlock(void) {
1196   GKI_TRACE_0("GKI_sched_unlock");
1197   GKI_enable();
1198 }
1199 
1200 /*******************************************************************************
1201 **
1202 ** Function         GKI_shiftdown
1203 **
1204 ** Description      shift memory down (to make space to insert a record)
1205 **
1206 *******************************************************************************/
GKI_shiftdown(uint8_t * p_mem,uint32_t len,uint32_t shift_amount)1207 void GKI_shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
1208   register uint8_t* ps = p_mem + len - 1;
1209   register uint8_t* pd = ps + shift_amount;
1210   register uint32_t xx;
1211 
1212   for (xx = 0; xx < len; xx++) *pd-- = *ps--;
1213 }
1214 
1215 /*******************************************************************************
1216 **
1217 ** Function         GKI_shiftup
1218 **
1219 ** Description      shift memory up (to delete a record)
1220 **
1221 *******************************************************************************/
GKI_shiftup(uint8_t * p_dest,uint8_t * p_src,uint32_t len)1222 void GKI_shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
1223   register uint8_t* ps = p_src;
1224   register uint8_t* pd = p_dest;
1225   register uint32_t xx;
1226 
1227   for (xx = 0; xx < len; xx++) *pd++ = *ps++;
1228 }
1229