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