int do_timer(unsigned int tick) { int i, nextmin = 1000; if (tick < 0x010000 && fix_heap_flag) { fix_timer_heap(tick); fix_heap_flag = 0; } while(timer_heap_num) { i = timer_heap[timer_heap_num - 1]; // next shorter element if ((nextmin = DIFF_TICK(timer_data[i].tick, tick)) > 0) break; if (timer_heap_num > 0) // suppress the actual element from the table timer_heap_num--; timer_data[i].type |= TIMER_REMOVE_HEAP; if (timer_data[i].func) { if (nextmin < -1000) { // 1秒以上の大幅な遅延が発生しているので、 // timer処理タイミングを現在値とする事で // 呼び出し時タイミング(引数のtick)相対で処理してる // timer関数の次回処理タイミングを遅らせる timer_data[i].func(i, tick, timer_data[i].id, timer_data[i].data); } else { timer_data[i].func(i, timer_data[i].tick, timer_data[i].id, timer_data[i].data); } } if (timer_data[i].type & TIMER_REMOVE_HEAP) { switch(timer_data[i].type & ~TIMER_REMOVE_HEAP) { case TIMER_ONCE_AUTODEL: timer_data[i].type = 0; if (free_timer_list_pos >= free_timer_list_max) { free_timer_list_max += 256; free_timer_list = (int *) aRealloc(free_timer_list, sizeof(int) * free_timer_list_max); memset(free_timer_list + (free_timer_list_max - 256), 0, 256 * sizeof(int)); } free_timer_list[free_timer_list_pos++] = i; break; case TIMER_INTERVAL: if (DIFF_TICK(timer_data[i].tick , tick) < -1000) { timer_data[i].tick = tick + timer_data[i].interval; } else { timer_data[i].tick += timer_data[i].interval; } timer_data[i].type &= ~TIMER_REMOVE_HEAP; push_timer_heap(i); break; } } } if (nextmin < TIMER_MIN_INTERVAL) nextmin = TIMER_MIN_INTERVAL; if ((unsigned int)(tick + nextmin) < tick) //Tick will loop, rearrange the heap on the next iteration. fix_heap_flag = 1; return nextmin; }
int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data) { struct TimerData *td; int i; if(free_timer_list_pos) { do { i=free_timer_list[--free_timer_list_pos]; } while(i>=timer_data_num && free_timer_list_pos>0); } else i=timer_data_num; if(i>=timer_data_num) for(i=timer_data_num;i<timer_data_max && timer_data[i].type;i++); if(i>=timer_data_num && i>=timer_data_max){ int j; if(timer_data_max==0){ timer_data_max = 256; timer_data = malloc(sizeof(struct TimerData)*timer_data_max); if(timer_data==NULL){ printf("out of memory : add_timer timer_data\n"); exit(1); } //timer_data[0] = NULL; } else { timer_data_max+= 256; timer_data = realloc(timer_data,sizeof(struct TimerData)*timer_data_max); if(timer_data==NULL){ printf("out of memory : add_timer timer_data\n"); exit(1); } } for(j=timer_data_max-256;j<timer_data_max;j++) timer_data[j].type=0; } td=&timer_data[i]; td->tick=tick; td->func=func; td->id=id; td->data=data; td->type=TIMER_ONCE_AUTODEL; td->interval=1000; push_timer_heap(i); if(i>=timer_data_num) timer_data_num=i+1; return i; }
int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int), int id, int data) { int tid = acquire_timer(); timer_data[tid].tick = tick; timer_data[tid].func = func; timer_data[tid].id = id; timer_data[tid].data = data; timer_data[tid].type = TIMER_ONCE_AUTODEL; timer_data[tid].interval = 1000; push_timer_heap(tid); if (tid >= timer_data_num) timer_data_num = tid + 1; return tid; }
int add_timer_interval(unsigned int tick, int (*func)(int,unsigned int,int,int), int id, int data, int interval) { int tid; if (interval < 1) { ShowError("add_timer_interval : function %08x(%s) has invalid interval %d!\n", (int)func, search_timer_func_list(func), interval); return -1; } tid = acquire_timer(); timer_data[tid].tick = tick; timer_data[tid].func = func; timer_data[tid].id = id; timer_data[tid].data = data; timer_data[tid].type = TIMER_INTERVAL; timer_data[tid].interval = interval; push_timer_heap(tid); if (tid >= timer_data_num) timer_data_num = tid + 1; return tid; }
int do_timer(unsigned int tick) { int i,nextmin=1000; #if 0 static int disp_tick=0; if(DIFF_TICK(disp_tick,tick)<-5000 || DIFF_TICK(disp_tick,tick)>5000){ printf("timer %d(%d+%d)\n",timer_data_num,timer_heap[0],free_timer_list_pos); disp_tick=tick; } #endif while((i=top_timer_heap())>=0){ if(DIFF_TICK(timer_data[i].tick , tick)>0){ nextmin=DIFF_TICK(timer_data[i].tick , tick); break; } pop_timer_heap(); timer_data[i].type |= TIMER_REMOVE_HEAP; if(timer_data[i].func){ if(DIFF_TICK(timer_data[i].tick , tick) < -1000){ // 1秒以上の大幅な遅延が発生しているので、 // timer処理タイミングを現在値とする事で // 呼び出し時タイミング(引数のtick)相対で処理してる // timer関数の次回処理タイミングを遅らせる timer_data[i].func(i,tick,timer_data[i].id,timer_data[i].data); } else { timer_data[i].func(i,timer_data[i].tick,timer_data[i].id,timer_data[i].data); } } if(timer_data[i].type&TIMER_REMOVE_HEAP){ switch(timer_data[i].type & ~TIMER_REMOVE_HEAP){ case TIMER_ONCE_AUTODEL: timer_data[i].type=0; if(free_timer_list_pos>=free_timer_list_max){ free_timer_list_max+=256; free_timer_list=realloc(free_timer_list,free_timer_list_max*sizeof(free_timer_list[0])); if(free_timer_list==NULL){ printf("out of memory : do_timer\n"); exit(1); } } free_timer_list[free_timer_list_pos++]=i; break; case TIMER_INTERVAL: if(DIFF_TICK(timer_data[i].tick , tick) < -1000){ timer_data[i].tick = tick+timer_data[i].interval; } else { timer_data[i].tick += timer_data[i].interval; } timer_data[i].type &= ~TIMER_REMOVE_HEAP; push_timer_heap(i); break; } } } if(nextmin<10) nextmin=10; return nextmin; }