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