213 uint8_t GKI_create_task(TASKPTR task_entry, uint8_t task_id, int8_t* taskname,
214 uint16_t* stack, uint16_t stacksize, void* pCondVar,
215 void* pMutex) {
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 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
224 "GKI_create_task func=0x%p id=%d name=%s stack=0x%p stackSize=%d",
225 task_entry, task_id, taskname, stack, stacksize);
226
227 if (task_id >= GKI_MAX_TASKS) {
228 DLOG_IF(INFO, nfc_debug_enabled)
229 << StringPrintf("Error! task ID > max task allowed");
230 return (GKI_FAILURE);
231 }
232
233 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
234 gki_cb.com.OSTName[task_id] = taskname;
235 gki_cb.com.OSWaitTmr[task_id] = 0;
236 gki_cb.com.OSWaitEvt[task_id] = 0;
237
238 /* Initialize mutex and condition variable objects for events and timeouts */
239 pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], nullptr);
240 pthread_cond_init(&gki_cb.os.thread_evt_cond[task_id], &attr);
241 pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], nullptr);
242 pthread_cond_init(&gki_cb.os.thread_timeout_cond[task_id], &attr);
243
244 pthread_attr_init(&attr1);
245 /* by default, pthread creates a joinable thread */
246 #if (FALSE == GKI_PTHREAD_JOINABLE)
247 pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
248
249 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
250 "GKI creating task %i, pCond/pMutex=%p/%p", task_id, pCondVar, pMutex);
251 #else
252 DLOG_IF(INFO, nfc_debug_enabled)
253 << StringPrintf("GKI creating JOINABLE task %i", task_id);
254 #endif
255
256 /* On Android, the new tasks starts running before
257 * 'gki_cb.os.thread_id[task_id]' is initialized */
258 /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id]
259 * for it calls GKI_wait */
260 gki_pthread_info[task_id].task_id = task_id;
261 gki_pthread_info[task_id].task_entry = task_entry;
262 gki_pthread_info[task_id].params = 0;
263 gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
264 gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
265
266 ret = pthread_create(&gki_cb.os.thread_id[task_id], &attr1, gki_task_entry,
267 &gki_pthread_info[task_id]);
268
269 if (ret != 0) {
270 DLOG_IF(INFO, nfc_debug_enabled)
271 << StringPrintf("pthread_create failed(%d), %s!", ret, taskname);
272 return GKI_FAILURE;
273 }
274
275 if (pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, ¶m) ==
276 0) {
277 #if (PBS_SQL_TASK == TRUE)
278 if (task_id == PBS_SQL_TASK) {
279 DLOG_IF(INFO, nfc_debug_enabled)
280 << StringPrintf("PBS SQL lowest priority task");
281 policy = SCHED_NORMAL;
282 } else
283 #endif
284 {
285 policy = SCHED_RR;
286 param.sched_priority = 30 - task_id - 2;
287 }
288 pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, ¶m);
289 }
290
291 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
292 "Leaving GKI_create_task %p %d %lx %s %p %d", task_entry, task_id,
293 gki_cb.os.thread_id[task_id], taskname, stack, stacksize);
294
295 return (GKI_SUCCESS);
296 }