summaryrefslogtreecommitdiff
path: root/src/common/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/timer.c')
-rw-r--r--src/common/timer.c624
1 files changed, 312 insertions, 312 deletions
diff --git a/src/common/timer.c b/src/common/timer.c
index b2289e4f8..7d03d4e5e 100644
--- a/src/common/timer.c
+++ b/src/common/timer.c
@@ -1,312 +1,312 @@
-// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 MagicalTux Exp $
-// original : core.c 2003/02/26 18:03:12 Rev 1.7
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#ifdef _WIN32
-#include <winsock.h>
-#else
-#include <sys/socket.h>
-#include <sys/time.h>
-#endif
-
-#include "timer.h"
-#include "utils.h"
-
-#ifdef MEMWATCH
-#include "memwatch.h"
-#endif
-
-static struct TimerData* timer_data;
-static int timer_data_max,timer_data_num;
-static int* free_timer_list;
-static int free_timer_list_max, free_timer_list_pos;
-
-static int timer_heap_max;
-static int* timer_heap = NULL;
-
-// for debug
-struct timer_func_list {
- int (*func)(int,unsigned int,int,int);
- struct timer_func_list* next;
- char* name;
-};
-static struct timer_func_list* tfl_root;
-
-#if defined(_WIN32)
-void gettimeofday(struct timeval *t, struct timezone *dummy)
-{
- DWORD millisec = GetTickCount();
-
- t->tv_sec = (int) (millisec / 1000);
- t->tv_usec = (millisec % 1000) * 1000;
-}
-
-#endif
-
-
-//
-int add_timer_func_list(int (*func)(int,unsigned int,int,int),char* name)
-{
- struct timer_func_list* tfl;
-
- CREATE(tfl, struct timer_func_list, 1);
- CREATE(tfl->name, char, strlen(name) + 1);
-
- tfl->next = tfl_root;
- tfl->func = func;
- strcpy(tfl->name,name);
- tfl_root = tfl;
-
- return 0;
-}
-
-char* search_timer_func_list(int (*func)(int,unsigned int,int,int))
-{
- struct timer_func_list* tfl;
- for(tfl = tfl_root;tfl;tfl = tfl->next) {
- if (func == tfl->func)
- return tfl->name;
- }
- return "???";
-}
-
-/*----------------------------
- * Get tick time
- *----------------------------*/
-static unsigned int gettick_cache;
-static int gettick_count;
-unsigned int gettick_nocache(void)
-{
- struct timeval tval;
- gettimeofday(&tval,NULL);
- gettick_count = 256;
- return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000;
-}
-
-unsigned int gettick(void)
-{
- gettick_count--;
- if (gettick_count<0)
- return gettick_nocache();
- return gettick_cache;
-}
-
-/*======================================
- * CORE : Timer Heap
- *--------------------------------------
- */
-static void push_timer_heap(int index)
-{
- int i, h;
-
- if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) {
- int first = timer_heap == NULL;
-
- timer_heap_max += 256;
- RECREATE(timer_heap, int, timer_heap_max);
- memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
- if (first)
- timer_heap[0] = 0;
- }
-
- timer_heap[0]++;
-
- for (h = timer_heap[0]-1, i = (h - 1) / 2;
- h > 0 && DIFF_TICK(timer_data[index].tick,
- timer_data[timer_heap[i + 1]].tick) < 0;
- i = (h - 1) / 2) {
- timer_heap[h + 1] = timer_heap[i + 1];
- h = i;
- }
- timer_heap[h + 1] = index;
-}
-
-static int top_timer_heap()
-{
- if (timer_heap == NULL || timer_heap[0] <= 0)
- return -1;
-
- return timer_heap[1];
-}
-
-static int pop_timer_heap()
-{
- int i,h,k;
- int ret,last;
-
- if (timer_heap == NULL || timer_heap[0] <= 0)
- return -1;
- ret = timer_heap[1];
- last = timer_heap[timer_heap[0]];
- timer_heap[0]--;
-
- for(h = 0,k = 2;k<timer_heap[0];k = k * 2 + 2) {
- if (DIFF_TICK(timer_data[timer_heap[k + 1]].tick , timer_data[timer_heap[k]].tick)>0)
- k--;
- timer_heap[h + 1] = timer_heap[k + 1], h = k;
- }
- if (k == timer_heap[0])
- timer_heap[h + 1] = timer_heap[k], h = k-1;
-
- for(i = (h-1)/2;
- h>0 && DIFF_TICK(timer_data[timer_heap[i + 1]].tick , timer_data[last].tick)>0;
- i = (h-1)/2) {
- timer_heap[h + 1] = timer_heap[i + 1],h = i;
- }
- timer_heap[h + 1] = last;
-
- return ret;
-}
-
-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;
- CREATE(timer_data, struct TimerData, timer_data_max);
- } else {
- timer_data_max += 256;
- RECREATE(timer_data, struct TimerData, timer_data_max);
- if (timer_data == NULL) {
- printf("out of memory : add_timer timer_data\n");
- exit(1);
- }
- memset(timer_data + (timer_data_max - 256), 0,
- sizeof(struct TimerData) * 256);
- }
- 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_interval(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data,int interval)
-{
- int tid;
- tid = add_timer(tick,func,id,data);
- timer_data[tid].type = TIMER_INTERVAL;
- timer_data[tid].interval = interval;
- return tid;
-}
-
-int delete_timer(int id,int (*func)(int,unsigned int,int,int))
-{
- if (id <= 0 || id >= timer_data_num) {
- printf("delete_timer error : no such timer %d\n", id);
- return -1;
- }
- if (timer_data[id].func != func) {
- printf("delete_timer error : function dismatch %08x(%s) != %08x(%s)\n",
- (int)timer_data[id].func,
- search_timer_func_list(timer_data[id].func),
- (int)func,
- search_timer_func_list(func));
- return -2;
- }
- // そのうち消えるにまかせる
- timer_data[id].func = NULL;
- timer_data[id].type = TIMER_ONCE_AUTODEL;
- timer_data[id].tick -= 60 * 60 * 1000;
- return 0;
-}
-
-int addtick_timer(int tid,unsigned int tick)
-{
- return timer_data[tid].tick += tick;
-}
-struct TimerData* get_timer(int tid)
-{
- return &timer_data[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;
- RECREATE(free_timer_list, int, free_timer_list_max);
- memset(free_timer_list + (free_timer_list_max - 256), 0,
- 256 * sizeof(free_timer_list[0]));
- }
- 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;
-}
-
-void timer_final()
-{
- free(timer_data);
-}
+// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 MagicalTux Exp $
+// original : core.c 2003/02/26 18:03:12 Rev 1.7
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <sys/time.h>
+#endif
+
+#include "timer.h"
+#include "utils.h"
+
+#ifdef MEMWATCH
+#include "memwatch.h"
+#endif
+
+static struct TimerData* timer_data;
+static int timer_data_max,timer_data_num;
+static int* free_timer_list;
+static int free_timer_list_max, free_timer_list_pos;
+
+static int timer_heap_max;
+static int* timer_heap = NULL;
+
+// for debug
+struct timer_func_list {
+ int (*func)(int,unsigned int,int,int);
+ struct timer_func_list* next;
+ char* name;
+};
+static struct timer_func_list* tfl_root;
+
+#if defined(_WIN32)
+void gettimeofday(struct timeval *t, struct timezone *dummy)
+{
+ DWORD millisec = GetTickCount();
+
+ t->tv_sec = (int) (millisec / 1000);
+ t->tv_usec = (millisec % 1000) * 1000;
+}
+
+#endif
+
+
+//
+int add_timer_func_list(int (*func)(int,unsigned int,int,int),char* name)
+{
+ struct timer_func_list* tfl;
+
+ CREATE(tfl, struct timer_func_list, 1);
+ CREATE(tfl->name, char, strlen(name) + 1);
+
+ tfl->next = tfl_root;
+ tfl->func = func;
+ strcpy(tfl->name,name);
+ tfl_root = tfl;
+
+ return 0;
+}
+
+char* search_timer_func_list(int (*func)(int,unsigned int,int,int))
+{
+ struct timer_func_list* tfl;
+ for(tfl = tfl_root;tfl;tfl = tfl->next) {
+ if (func == tfl->func)
+ return tfl->name;
+ }
+ return "???";
+}
+
+/*----------------------------
+ * Get tick time
+ *----------------------------*/
+static unsigned int gettick_cache;
+static int gettick_count;
+unsigned int gettick_nocache(void)
+{
+ struct timeval tval;
+ gettimeofday(&tval,NULL);
+ gettick_count = 256;
+ return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000;
+}
+
+unsigned int gettick(void)
+{
+ gettick_count--;
+ if (gettick_count<0)
+ return gettick_nocache();
+ return gettick_cache;
+}
+
+/*======================================
+ * CORE : Timer Heap
+ *--------------------------------------
+ */
+static void push_timer_heap(int index)
+{
+ int i, h;
+
+ if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) {
+ int first = timer_heap == NULL;
+
+ timer_heap_max += 256;
+ RECREATE(timer_heap, int, timer_heap_max);
+ memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
+ if (first)
+ timer_heap[0] = 0;
+ }
+
+ timer_heap[0]++;
+
+ for (h = timer_heap[0]-1, i = (h - 1) / 2;
+ h > 0 && DIFF_TICK(timer_data[index].tick,
+ timer_data[timer_heap[i + 1]].tick) < 0;
+ i = (h - 1) / 2) {
+ timer_heap[h + 1] = timer_heap[i + 1];
+ h = i;
+ }
+ timer_heap[h + 1] = index;
+}
+
+static int top_timer_heap()
+{
+ if (timer_heap == NULL || timer_heap[0] <= 0)
+ return -1;
+
+ return timer_heap[1];
+}
+
+static int pop_timer_heap()
+{
+ int i,h,k;
+ int ret,last;
+
+ if (timer_heap == NULL || timer_heap[0] <= 0)
+ return -1;
+ ret = timer_heap[1];
+ last = timer_heap[timer_heap[0]];
+ timer_heap[0]--;
+
+ for(h = 0,k = 2;k<timer_heap[0];k = k * 2 + 2) {
+ if (DIFF_TICK(timer_data[timer_heap[k + 1]].tick , timer_data[timer_heap[k]].tick)>0)
+ k--;
+ timer_heap[h + 1] = timer_heap[k + 1], h = k;
+ }
+ if (k == timer_heap[0])
+ timer_heap[h + 1] = timer_heap[k], h = k-1;
+
+ for(i = (h-1)/2;
+ h>0 && DIFF_TICK(timer_data[timer_heap[i + 1]].tick , timer_data[last].tick)>0;
+ i = (h-1)/2) {
+ timer_heap[h + 1] = timer_heap[i + 1],h = i;
+ }
+ timer_heap[h + 1] = last;
+
+ return ret;
+}
+
+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;
+ CREATE(timer_data, struct TimerData, timer_data_max);
+ } else {
+ timer_data_max += 256;
+ RECREATE(timer_data, struct TimerData, timer_data_max);
+ if (timer_data == NULL) {
+ printf("out of memory : add_timer timer_data\n");
+ exit(1);
+ }
+ memset(timer_data + (timer_data_max - 256), 0,
+ sizeof(struct TimerData) * 256);
+ }
+ 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_interval(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data,int interval)
+{
+ int tid;
+ tid = add_timer(tick,func,id,data);
+ timer_data[tid].type = TIMER_INTERVAL;
+ timer_data[tid].interval = interval;
+ return tid;
+}
+
+int delete_timer(int id,int (*func)(int,unsigned int,int,int))
+{
+ if (id <= 0 || id >= timer_data_num) {
+ printf("delete_timer error : no such timer %d\n", id);
+ return -1;
+ }
+ if (timer_data[id].func != func) {
+ printf("delete_timer error : function dismatch %08x(%s) != %08x(%s)\n",
+ (int)timer_data[id].func,
+ search_timer_func_list(timer_data[id].func),
+ (int)func,
+ search_timer_func_list(func));
+ return -2;
+ }
+ // そのうち消えるにまかせる
+ timer_data[id].func = NULL;
+ timer_data[id].type = TIMER_ONCE_AUTODEL;
+ timer_data[id].tick -= 60 * 60 * 1000;
+ return 0;
+}
+
+int addtick_timer(int tid,unsigned int tick)
+{
+ return timer_data[tid].tick += tick;
+}
+struct TimerData* get_timer(int tid)
+{
+ return &timer_data[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;
+ RECREATE(free_timer_list, int, free_timer_list_max);
+ memset(free_timer_list + (free_timer_list_max - 256), 0,
+ 256 * sizeof(free_timer_list[0]));
+ }
+ 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;
+}
+
+void timer_final()
+{
+ free(timer_data);
+}