static void *sched_thread_entrance(void *args) { ScheduleContext *pContext; ScheduleEntry *pPrevious; ScheduleEntry *pCurrent; ScheduleEntry *pSaveNext; ScheduleEntry *pNode; ScheduleEntry *pUntil; int exec_count; int i; pContext = (ScheduleContext *)args; if (sched_init_entries(&(pContext->scheduleArray)) != 0) { free(pContext); return NULL; } sched_make_chain(pContext); g_schedule_flag = true; while (*(pContext->pcontinue_flag)) { g_current_time = time(NULL); sched_deal_delay_tasks(pContext); sched_check_waiting_more(pContext); if (pContext->scheduleArray.count == 0) //no schedule entry { sleep(1); continue; } while (pContext->head->next_call_time > g_current_time && *(pContext->pcontinue_flag)) { sleep(1); g_current_time = time(NULL); sched_deal_delay_tasks(pContext); if (sched_check_waiting_more(pContext) == 0) { break; } } if (!(*(pContext->pcontinue_flag))) { break; } exec_count = 0; pCurrent = pContext->head; while (*(pContext->pcontinue_flag) && (pCurrent != NULL \ && pCurrent->next_call_time <= g_current_time)) { //logInfo("exec task id: %d", pCurrent->id); if (!pCurrent->new_thread) { pCurrent->task_func(pCurrent->func_args); } else { pthread_t tid; int result; pCurrent->thread_running = false; if ((result=pthread_create(&tid, NULL, sched_call_func, pCurrent)) != 0) { logError("file: "__FILE__", line: %d, " \ "create thread failed, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); } else { usleep(1*1000); for (i=1; !pCurrent->thread_running && i<100; i++) { logDebug("file: "__FILE__", line: %d, " "task_id: %d, waiting thread ready, count %d", __LINE__, pCurrent->id, i); usleep(1*1000); } } } do { pCurrent->next_call_time += pCurrent->interval; } while (pCurrent->next_call_time <= g_current_time); pCurrent = pCurrent->next; exec_count++; } if (exec_count == 0 || pContext->scheduleArray.count == 1) { continue; } if (exec_count > pContext->scheduleArray.count / 2) { sched_make_chain(pContext); continue; } pNode = pContext->head; pContext->head = pCurrent; //new chain head for (i=0; i<exec_count; i++) { if (pNode->next_call_time >= pContext->tail->next_call_time) { pContext->tail->next = pNode; pContext->tail = pNode; pNode = pNode->next; pContext->tail->next = NULL; continue; } pPrevious = NULL; pUntil = pContext->head; while (pUntil != NULL && \ pNode->next_call_time > pUntil->next_call_time) { pPrevious = pUntil; pUntil = pUntil->next; } pSaveNext = pNode->next; if (pPrevious == NULL) { pContext->head = pNode; } else { pPrevious->next = pNode; } pNode->next = pUntil; pNode = pSaveNext; } } g_schedule_flag = false; logDebug("file: "__FILE__", line: %d, " \ "schedule thread exit", __LINE__); free(pContext); return NULL; }
static void *sched_thread_entrance(void *args) { ScheduleContext *pContext; ScheduleEntry *pPrevious; ScheduleEntry *pCurrent; ScheduleEntry *pSaveNext; ScheduleEntry *pNode; ScheduleEntry *pUntil; int exec_count; int i; pContext = (ScheduleContext *)args; if (sched_init_entries(&(pContext->scheduleArray)) != 0) { free(pContext); return NULL; } sched_make_chain(pContext); g_schedule_flag = true; while (*(pContext->pcontinue_flag)) { sched_check_waiting(pContext); if (pContext->scheduleArray.count == 0) //no schedule entry { sleep(1); g_current_time = time(NULL); continue; } g_current_time = time(NULL); while (pContext->head->next_call_time > g_current_time && *(pContext->pcontinue_flag)) { sleep(1); g_current_time = time(NULL); if (sched_check_waiting(pContext) == 0) { break; } } if (!(*(pContext->pcontinue_flag))) { break; } exec_count = 0; pCurrent = pContext->head; while (*(pContext->pcontinue_flag) && (pCurrent != NULL \ && pCurrent->next_call_time <= g_current_time)) { //fprintf(stderr, "exec task id=%d\n", pCurrent->id); pCurrent->task_func(pCurrent->func_args); do { pCurrent->next_call_time += pCurrent->interval; } while (pCurrent->next_call_time <= g_current_time); pCurrent = pCurrent->next; exec_count++; } if (exec_count == 0 || pContext->scheduleArray.count == 1) { continue; } if (exec_count > pContext->scheduleArray.count / 2) { sched_make_chain(pContext); continue; } pNode = pContext->head; pContext->head = pCurrent; //new chain head for (i=0; i<exec_count; i++) { if (pNode->next_call_time >= pContext->tail->next_call_time) { pContext->tail->next = pNode; pContext->tail = pNode; pNode = pNode->next; pContext->tail->next = NULL; continue; } pPrevious = NULL; pUntil = pContext->head; while (pUntil != NULL && \ pNode->next_call_time > pUntil->next_call_time) { pPrevious = pUntil; pUntil = pUntil->next; } pSaveNext = pNode->next; if (pPrevious == NULL) { pContext->head = pNode; } else { pPrevious->next = pNode; } pNode->next = pUntil; pNode = pSaveNext; } } g_schedule_flag = false; logDebug("file: "__FILE__", line: %d, " \ "schedule thread exit", __LINE__); free(pContext); return NULL; }