|
@@ -15,11 +15,15 @@
|
|
|
|
|
|
#include "timer.h"
|
|
#include "timer.h"
|
|
#include "utils.h"
|
|
#include "utils.h"
|
|
|
|
+#include "../common/malloc.h"
|
|
|
|
|
|
#ifdef MEMWATCH
|
|
#ifdef MEMWATCH
|
|
#include "memwatch.h"
|
|
#include "memwatch.h"
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+// タイマー間隔の最小値。モンスターの大量召還時、多数のクライアント接続時に
|
|
|
|
+// サーバーが反応しなくなる場合は、TIMER_MIN_INTERVEL を増やしてください。
|
|
|
|
+
|
|
// If the server shows no reaction when processing thousands of monsters
|
|
// If the server shows no reaction when processing thousands of monsters
|
|
// or connected by many clients, please increase TIMER_MIN_INTERVEL.
|
|
// or connected by many clients, please increase TIMER_MIN_INTERVEL.
|
|
|
|
|
|
@@ -37,9 +41,9 @@ static int* timer_heap = NULL;
|
|
struct timer_func_list {
|
|
struct timer_func_list {
|
|
int (*func)(int,unsigned int,int,int);
|
|
int (*func)(int,unsigned int,int,int);
|
|
struct timer_func_list* next;
|
|
struct timer_func_list* next;
|
|
- char* name;
|
|
|
|
|
|
+ char name[40];
|
|
};
|
|
};
|
|
-static struct timer_func_list* tfl_root;
|
|
|
|
|
|
+static struct timer_func_list* tfl_root=NULL;
|
|
|
|
|
|
#if defined(_WIN32)
|
|
#if defined(_WIN32)
|
|
void gettimeofday(struct timeval *t, struct timezone *dummy)
|
|
void gettimeofday(struct timeval *t, struct timezone *dummy)
|
|
@@ -59,11 +63,11 @@ int add_timer_func_list(int (*func)(int,unsigned int,int,int),char* name)
|
|
struct timer_func_list* tfl;
|
|
struct timer_func_list* tfl;
|
|
|
|
|
|
CREATE(tfl, struct timer_func_list, 1);
|
|
CREATE(tfl, struct timer_func_list, 1);
|
|
- CREATE(tfl->name, char, strlen(name) + 1);
|
|
|
|
|
|
+ //CREATE(tfl->name, char, strlen(name) + 1);
|
|
|
|
|
|
tfl->next = tfl_root;
|
|
tfl->next = tfl_root;
|
|
tfl->func = func;
|
|
tfl->func = func;
|
|
- strcpy(tfl->name,name);
|
|
|
|
|
|
+ strncpy(tfl->name, name, sizeof(tfl->name) - 1);
|
|
tfl_root = tfl;
|
|
tfl_root = tfl;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -86,10 +90,14 @@ static unsigned int gettick_cache;
|
|
static int gettick_count;
|
|
static int gettick_count;
|
|
unsigned int gettick_nocache(void)
|
|
unsigned int gettick_nocache(void)
|
|
{
|
|
{
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+ return gettick_cache = GetTickCount();
|
|
|
|
+#else
|
|
struct timeval tval;
|
|
struct timeval tval;
|
|
gettimeofday(&tval,NULL);
|
|
gettimeofday(&tval,NULL);
|
|
gettick_count = 256;
|
|
gettick_count = 256;
|
|
return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000;
|
|
return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
unsigned int gettick(void)
|
|
unsigned int gettick(void)
|
|
@@ -104,67 +112,135 @@ unsigned int gettick(void)
|
|
* CORE : Timer Heap
|
|
* CORE : Timer Heap
|
|
*--------------------------------------
|
|
*--------------------------------------
|
|
*/
|
|
*/
|
|
|
|
+
|
|
|
|
+// デバッグ用関数群
|
|
|
|
+static void dump_timer_heap(void) {
|
|
|
|
+ int j;
|
|
|
|
+ for(j = 1 ; j <= timer_heap[0] ; j++) {
|
|
|
|
+ if(j != timer_heap[0] && DIFF_TICK(
|
|
|
|
+ timer_data[timer_heap[j]].tick,
|
|
|
|
+ timer_data[timer_heap[j + 1]].tick
|
|
|
|
+ ) < 0) {
|
|
|
|
+ printf("*");
|
|
|
|
+ } else {
|
|
|
|
+ printf(" ");
|
|
|
|
+ }
|
|
|
|
+ printf("%d : %d %d\n",j,timer_heap[j],timer_data[timer_heap[j]].tick);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void push_timer_heap(int index)
|
|
static void push_timer_heap(int index)
|
|
{
|
|
{
|
|
- int i, h;
|
|
|
|
-
|
|
|
|
if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) {
|
|
if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) {
|
|
int first = timer_heap == NULL;
|
|
int first = timer_heap == NULL;
|
|
|
|
|
|
timer_heap_max += 256;
|
|
timer_heap_max += 256;
|
|
- RECREATE(timer_heap, int, timer_heap_max);
|
|
|
|
|
|
+ timer_heap = (int*)aRealloc(timer_heap, sizeof(int) * timer_heap_max);
|
|
memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
|
|
memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256);
|
|
if (first)
|
|
if (first)
|
|
timer_heap[0] = 0;
|
|
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[0] : タイマーヒープの数
|
|
|
|
+ // timer_heap[1..] : タイマーヒープ(大 → 小)
|
|
|
|
+ if(timer_heap[0] == 0) {
|
|
|
|
+ // データが無い : 先頭に追加
|
|
|
|
+ timer_heap[0]++;
|
|
|
|
+ timer_heap[1] = index;
|
|
|
|
+ } else if(DIFF_TICK(timer_data[timer_heap[timer_heap[0]]].tick,timer_data[index].tick) > 0) {
|
|
|
|
+ // 最後尾に追加
|
|
|
|
+ timer_heap[++timer_heap[0]] = index;
|
|
|
|
+ } else if(DIFF_TICK(timer_data[timer_heap[1]].tick,timer_data[index].tick) < 0) {
|
|
|
|
+ // 先頭に追加
|
|
|
|
+ memmove(&timer_heap[2],&timer_heap[1],timer_heap[0] * sizeof(int));
|
|
|
|
+ timer_heap[0]++;
|
|
|
|
+ timer_heap[1] = index;
|
|
|
|
+ } else {
|
|
|
|
+ int min = 1;
|
|
|
|
+ int max = timer_heap[0] + 1;
|
|
|
|
+ while(max != min + 1) {
|
|
|
|
+ int mid = (min + max)/2;
|
|
|
|
+ if(DIFF_TICK(timer_data[index].tick,timer_data[timer_heap[mid]].tick) > 0) {
|
|
|
|
+ max = mid;
|
|
|
|
+ } else {
|
|
|
|
+ min = mid;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ memmove(&timer_heap[min+2],&timer_heap[min+1],(timer_heap[0] - min) * sizeof(int));
|
|
|
|
+ timer_heap[min+1] = index;
|
|
|
|
+ timer_heap[0]++;
|
|
}
|
|
}
|
|
- timer_heap[h + 1] = index;
|
|
|
|
|
|
+ // check_timer_heap();
|
|
}
|
|
}
|
|
|
|
|
|
-static int top_timer_heap()
|
|
|
|
|
|
+// 指定したindex を持つタイマーヒープを返す
|
|
|
|
+static int search_timer_heap(int index)
|
|
{
|
|
{
|
|
- if (timer_heap == NULL || timer_heap[0] <= 0)
|
|
|
|
|
|
+ if (timer_heap == NULL || timer_heap[0] <= 0) {
|
|
return -1;
|
|
return -1;
|
|
|
|
+ } else {
|
|
|
|
+ int min = 1;
|
|
|
|
+ int max = timer_heap[0] + 1;
|
|
|
|
+ while(max != min + 1) {
|
|
|
|
+ int mid = (min + max)/2;
|
|
|
|
+ if(DIFF_TICK(timer_data[index].tick,timer_data[timer_heap[mid]].tick) > 0) {
|
|
|
|
+ max = mid;
|
|
|
|
+ } else {
|
|
|
|
+ min = mid;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(timer_heap[min] == index) {
|
|
|
|
+ return min;
|
|
|
|
+ } else {
|
|
|
|
+ int pos = min - 1;
|
|
|
|
+ while(pos > 0 && timer_data[index].tick == timer_data[timer_heap[pos]].tick) {
|
|
|
|
+ if(timer_heap[pos] == index) {
|
|
|
|
+ return pos;
|
|
|
|
+ }
|
|
|
|
+ pos--;
|
|
|
|
+ }
|
|
|
|
+ pos = min + 1;
|
|
|
|
+ while(pos <= timer_heap[0] && timer_data[index].tick == timer_data[timer_heap[pos]].tick) {
|
|
|
|
+ if(timer_heap[pos] == index) {
|
|
|
|
+ return pos;
|
|
|
|
+ }
|
|
|
|
+ pos++;
|
|
|
|
+ }
|
|
|
|
+ printf("search_timer_heap : can't find tid:%d\n",index);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- return timer_heap[1];
|
|
|
|
|
|
+static void delete_timer_heap(int index) {
|
|
|
|
+ int pos = search_timer_heap(index);
|
|
|
|
+ if(pos != -1) {
|
|
|
|
+ memmove(&timer_heap[pos],&timer_heap[pos+1],(timer_heap[0] - pos) * sizeof(int));
|
|
|
|
+ timer_heap[0]--;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-static int pop_timer_heap()
|
|
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+int top_timer_heap(void)
|
|
|
|
+#else
|
|
|
|
+static inline int top_timer_heap(void)
|
|
|
|
+#endif
|
|
{
|
|
{
|
|
- int i,h,k;
|
|
|
|
- int ret,last;
|
|
|
|
-
|
|
|
|
if (timer_heap == NULL || timer_heap[0] <= 0)
|
|
if (timer_heap == NULL || timer_heap[0] <= 0)
|
|
return -1;
|
|
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 timer_heap[timer_heap[0]];
|
|
|
|
+}
|
|
|
|
|
|
- return ret;
|
|
|
|
|
|
+#ifdef _WIN32
|
|
|
|
+int pop_timer_heap(void)
|
|
|
|
+#else
|
|
|
|
+static inline int pop_timer_heap(void)
|
|
|
|
+#endif
|
|
|
|
+{
|
|
|
|
+ if (timer_heap == NULL || timer_heap[0] <= 0)
|
|
|
|
+ return -1;
|
|
|
|
+ return timer_heap[timer_heap[0]--];
|
|
}
|
|
}
|
|
|
|
|
|
int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data)
|
|
int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data)
|
|
@@ -185,6 +261,7 @@ int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int
|
|
if (timer_data_max == 0) {
|
|
if (timer_data_max == 0) {
|
|
timer_data_max = 256;
|
|
timer_data_max = 256;
|
|
CREATE(timer_data, struct TimerData, timer_data_max);
|
|
CREATE(timer_data, struct TimerData, timer_data_max);
|
|
|
|
+ //timer_data[0] = NULL;
|
|
} else {
|
|
} else {
|
|
timer_data_max += 256;
|
|
timer_data_max += 256;
|
|
RECREATE(timer_data, struct TimerData, timer_data_max);
|
|
RECREATE(timer_data, struct TimerData, timer_data_max);
|
|
@@ -237,13 +314,16 @@ int delete_timer(int id,int (*func)(int,unsigned int,int,int))
|
|
// そのうち消えるにまかせる
|
|
// そのうち消えるにまかせる
|
|
timer_data[id].func = NULL;
|
|
timer_data[id].func = NULL;
|
|
timer_data[id].type = TIMER_ONCE_AUTODEL;
|
|
timer_data[id].type = TIMER_ONCE_AUTODEL;
|
|
- timer_data[id].tick -= 60 * 60 * 1000;
|
|
|
|
|
|
+ // timer_data[id].tick -= 60 * 60 * 1000;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
int addtick_timer(int tid,unsigned int tick)
|
|
int addtick_timer(int tid,unsigned int tick)
|
|
{
|
|
{
|
|
- return timer_data[tid].tick += tick;
|
|
|
|
|
|
+ delete_timer_heap(tid);
|
|
|
|
+ timer_data[tid].tick += tick;
|
|
|
|
+ push_timer_heap(tid);
|
|
|
|
+ return timer_data[tid].tick;
|
|
}
|
|
}
|
|
struct TimerData* get_timer(int tid)
|
|
struct TimerData* get_timer(int tid)
|
|
{
|
|
{
|
|
@@ -264,6 +344,9 @@ int do_timer(unsigned int tick)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
while((i = top_timer_heap()) >= 0) {
|
|
while((i = top_timer_heap()) >= 0) {
|
|
|
|
+ if(i == 2) {
|
|
|
|
+ i = 2;
|
|
|
|
+ }
|
|
if (DIFF_TICK(timer_data[i].tick , tick)>0) {
|
|
if (DIFF_TICK(timer_data[i].tick , tick)>0) {
|
|
nextmin = DIFF_TICK(timer_data[i].tick , tick);
|
|
nextmin = DIFF_TICK(timer_data[i].tick , tick);
|
|
break;
|
|
break;
|
|
@@ -312,7 +395,19 @@ int do_timer(unsigned int tick)
|
|
return nextmin;
|
|
return nextmin;
|
|
}
|
|
}
|
|
|
|
|
|
-void timer_final()
|
|
|
|
|
|
+void timer_final(void)
|
|
{
|
|
{
|
|
- free(timer_data);
|
|
|
|
|
|
+ struct timer_func_list *tfl, *tfl_next;
|
|
|
|
+ for(tfl = tfl_root; tfl; tfl = tfl_next)
|
|
|
|
+ {
|
|
|
|
+ tfl_next = tfl->next;
|
|
|
|
+ free(tfl);
|
|
|
|
+ tfl = NULL;
|
|
|
|
+ }
|
|
|
|
+ if(timer_heap)
|
|
|
|
+ free(timer_heap);
|
|
|
|
+ if(free_timer_list)
|
|
|
|
+ free(free_timer_list);
|
|
|
|
+ if(timer_data)
|
|
|
|
+ free(timer_data);
|
|
}
|
|
}
|