From bb83a7c114c17b67e9209fcda27b125192ce6b5a Mon Sep 17 00:00:00 2001 From: codemaster Date: Mon, 20 Dec 2004 20:11:23 +0000 Subject: * Updated makefiles to new strlib locations [Codemaster] * Moved strlib.h and strlib.c into the common directory [Codemaster] * Updated a bit of jA 1081 - it's not completly updated yet!!! [Codemaster] git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@681 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/common/timer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/common/timer.h') diff --git a/src/common/timer.h b/src/common/timer.h index f6fc5c84d..c43c0e6b0 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -38,6 +38,7 @@ struct TimerData *get_timer(int tid); int do_timer(unsigned int tick); int add_timer_func_list(int (*)(int,unsigned int,int,int),char*); +void do_final_timer(void); char* search_timer_func_list(int (*)(int,unsigned int,int,int)); extern void timer_final(); -- cgit v1.2.3-70-g09d2 From 33b8fd47955eeab26cede233b14d683b8e0491b8 Mon Sep 17 00:00:00 2001 From: celest Date: Wed, 23 Mar 2005 15:26:52 +0000 Subject: * Fixed alot of memory leaks * Added stray memory cleaning routine to db.c git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1275 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-SVN.txt | 2 + src/char/char.c | 12 ++--- src/char/int_guild.c | 20 ++++++++- src/char/int_guild.h | 1 + src/char/int_party.c | 11 +++++ src/char/int_party.h | 1 + src/char/int_pet.c | 11 +++++ src/char/int_pet.h | 1 + src/char/int_storage.c | 16 +++++++ src/char/int_storage.h | 1 + src/char/inter.c | 23 ++++++++++ src/char/inter.h | 1 + src/char_sql/char.c | 9 ++++ src/char_sql/int_guild.c | 29 ++++++++++++ src/char_sql/int_guild.h | 1 + src/char_sql/int_party.c | 4 ++ src/char_sql/int_party.h | 1 + src/char_sql/int_pet.c | 4 ++ src/char_sql/int_pet.h | 1 + src/char_sql/int_storage.c | 7 +++ src/char_sql/int_storage.h | 1 + src/char_sql/inter.c | 20 +++++++++ src/char_sql/inter.h | 2 +- src/common/core.c | 12 ++--- src/common/malloc.c | 4 +- src/common/malloc.h | 3 ++ src/common/socket.c | 8 ++-- src/common/timer.h | 4 +- src/login/login.c | 3 +- src/login_sql/login.c | 43 ++++++++++-------- src/map/map.c | 108 ++++++++++++++++++++------------------------- src/map/npc.c | 92 ++++++++++++++++++++++++++------------ src/map/pc.c | 5 +++ src/map/pc.h | 1 + 34 files changed, 327 insertions(+), 135 deletions(-) (limited to 'src/common/timer.h') diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index 7d4f3d92a..047c96b99 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,8 @@ Date Added 03/23 + * Fixed alot of memory leaks [celest] + * Added stray memory cleaning routine to db.c [celest] * Fixed some compile errors, sorry xP [celest] * Corrected potion creation success chances, thanks to Avaj and DracoRPG * Removed some unused potion creation code, thanks to DracoRPG diff --git a/src/char/char.c b/src/char/char.c index 1a2b61389..78f4bd3ae 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -22,6 +22,7 @@ #include "socket.h" #include "timer.h" #include "mmo.h" +#include "db.h" #include "version.h" #include "lock.h" #include "char.h" @@ -630,11 +631,6 @@ int mmo_char_init(void) { printf("out of memory: mmo_char_init (calloc of char_dat).\n"); exit(1); } - online_chars = (struct online_chars*)aCalloc(sizeof(struct online_chars) * 256, 1); - if (!online_chars) { - printf("out of memory: mmo_char_init (calloc of online_chars).\n"); - exit(1); - } for(i = 0; i < char_max; i++) { online_chars[i].char_id = -1; @@ -3456,8 +3452,9 @@ void do_final(void) { delete_session(login_fd); delete_session(char_fd); - for(i = 0; i < fd_max; i++) - if(session[i] != NULL) aFree(session[i]); + inter_final(); + exit_dbn(); + timer_final(); char_log("----End of char-server (normal end with closing of all files)." RETCODE); } @@ -3512,7 +3509,6 @@ int do_init(int argc, char **argv) { online_chars[i].server = -1; } - mmo_char_init(); update_online = time(NULL); diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 267b66f0f..78e6b476f 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -488,10 +488,28 @@ int inter_guild_init() { return 0; } +int castle_db_final (void *k, void *data, va_list ap) +{ + struct guild_castle *gc = data; + if (gc) aFree(gc); + return 0; +} +int guild_db_final (void *k, void *data, va_list ap) +{ + struct guild *g = data; + if (g) aFree(g); + return 0; +} +void inter_guild_final() { + numdb_final(castle_db, castle_db_final); + numdb_final(guild_db, guild_db_final); + return; +} + struct guild *inter_guild_search(int guild_id) { struct guild *g; - g= (struct guild *) numdb_search(guild_db, guild_id); + g = (struct guild *) numdb_search(guild_db, guild_id); return g; } diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 555f5e123..3eeb1b3db 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -3,6 +3,7 @@ #define _INT_GUILD_H_ int inter_guild_init(); +void inter_guild_final(); int inter_guild_save(); int inter_guild_parse_frommap(int fd); struct guild *inter_guild_search(int guild_id); diff --git a/src/char/int_party.c b/src/char/int_party.c index 3298587f1..5ee48fc70 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -117,6 +117,17 @@ int inter_party_init() { return 0; } +int party_db_final (void *k, void *data, va_list ap) { + struct party *p = data; + if (p) aFree(p); + return 0; +} +void inter_party_final() +{ + numdb_final(party_db, party_db_final); + return; +} + // パ?ティ?デ?タのセ?ブ用 int inter_party_save_sub(void *key, void *data, va_list ap) { char line[8192]; diff --git a/src/char/int_party.h b/src/char/int_party.h index b265b4c2e..e3180f3b7 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -3,6 +3,7 @@ #define _INT_PARTY_H_ int inter_party_init(); +void inter_party_final(); int inter_party_save(); int inter_party_parse_frommap(int fd); diff --git a/src/char/int_pet.c b/src/char/int_pet.c index 8682860c0..342854f8b 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -109,6 +109,17 @@ int inter_pet_init() return 0; } +int pet_db_final (void *k, void *data, va_list ap) { + struct s_pet *p = data; + if (p) aFree(p); + return 0; +} +void inter_pet_final() +{ + numdb_final(pet_db, pet_db_final); + return; +} + int inter_pet_save_sub(void *key,void *data,va_list ap) { char line[8192]; diff --git a/src/char/int_pet.h b/src/char/int_pet.h index 993f913ab..3a48ada3b 100644 --- a/src/char/int_pet.h +++ b/src/char/int_pet.h @@ -3,6 +3,7 @@ #define _INT_PET_H_ int inter_pet_init(); +void inter_pet_final(); int inter_pet_save(); int inter_pet_delete(int pet_id); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 3c5695c90..67b25909b 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -291,6 +291,22 @@ int inter_storage_init() return 0; } +int storage_db_final (void *k, void *data, va_list ap) { + struct storage *p = data; + if (p) aFree(p); + return 0; +} +int guild_storage_db_final (void *k, void *data, va_list ap) { + struct guild_storage *p = data; + if (p) aFree(p); + return 0; +} +void inter_storage_final() { + numdb_final(storage_db, storage_db_final); + numdb_final(guild_storage_db, guild_storage_db_final); + return; +} + int inter_storage_save_sub(void *key,void *data,va_list ap) { char line[65536]; diff --git a/src/char/int_storage.h b/src/char/int_storage.h index d918f5fe3..f228be53d 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -3,6 +3,7 @@ #define _INT_STORAGE_H_ int inter_storage_init(); +void inter_storage_final(); int inter_storage_save(); int inter_guild_storage_save(); int inter_storage_delete(int account_id); diff --git a/src/char/inter.c b/src/char/inter.c index f368a48b6..3a388ea82 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -261,6 +261,29 @@ int inter_init(const char *file) { return 0; } +// finalize +int accreg_db_final (void *k, void *data, va_list ap) { + struct accreg *p = data; + if (p) aFree(p); + return 0; +} +int wis_db_final (void *k, void *data, va_list ap) { + struct WisData *p = data; + if (p) aFree(p); + return 0; +} +void inter_final() { + numdb_final(accreg_db, accreg_db_final); + numdb_final(wis_db, wis_db_final); + + inter_party_final(); + inter_guild_final(); + inter_storage_final(); + inter_pet_final(); + + return; +} + // マップサーバー接続 int inter_mapif_init(int fd) { inter_guild_mapif_init(fd); diff --git a/src/char/inter.h b/src/char/inter.h index 0b6f809d7..636ce31d8 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -3,6 +3,7 @@ #define _INTER_H_ int inter_init(const char *file); +void inter_final(); int inter_save(); int inter_parse_frommap(int fd); int inter_mapif_init(int fd); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 78467b579..6b122974f 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -3134,6 +3134,12 @@ int char_lan_config_read(const char *lancfgName){ return 0; } +static int char_db_final(void *key,void *data,va_list ap) +{ + struct mmo_charstatus *p = data; + if (p) aFree(p); + return 0; +} void do_final(void) { printf("Doing final stage...\n"); //mmo_char_sync(); @@ -3162,9 +3168,12 @@ void do_final(void) { delete_session(login_fd); delete_session(char_fd); + numdb_final(char_db_, char_db_final); + exit_dbn(); mysql_close(&mysql_handle); mysql_close(&lmysql_handle); + timer_final(); printf("ok! all done...\n"); } diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c index 2f294bade..4961fd933 100644 --- a/src/char_sql/int_guild.c +++ b/src/char_sql/int_guild.c @@ -709,6 +709,35 @@ int inter_guild_sql_init() return 0; } +int guild_expcache_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_infoevent_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_castleinfoevent_db_final (void *k, void *data, va_list ap) { return 0; } +int guild_db_final (void *k, void *data, va_list ap) +{ + struct guild *g = data; + if (g) aFree(g); + return 0; +} +int castle_db_final (void *k, void *data, va_list ap) +{ + struct guild_castle *gc = data; + if (gc) aFree(gc); + return 0; +} +void inter_guild_sql_final() +{ + if (guild_pt) aFree(guild_pt); + if (guild_pt2) aFree(guild_pt2); + if (guildcastle_pt) aFree(guildcastle_pt); + + numdb_final(guild_db_, guild_db_); + numdb_final(castle_db_, castle_db_final); + numdb_final(guild_expcache_db_, guild_expcache_db_final); + numdb_final(guild_infoevent_db_, guild_infoevent_db_final); + numdb_final(guild_castleinfoevent_db_, guild_castleinfoevent_db_final); + + return; +} // Get guild by its name struct guild* search_guildname(char *str) diff --git a/src/char_sql/int_guild.h b/src/char_sql/int_guild.h index 8f4203d7c..8257cf8f6 100644 --- a/src/char_sql/int_guild.h +++ b/src/char_sql/int_guild.h @@ -3,6 +3,7 @@ int inter_guild_parse_frommap(int fd); int inter_guild_sql_init(); +void inter_guild_sql_final(); int inter_guild_mapif_init(int fd); int inter_guild_leave(int guild_id,int account_id,int char_id); diff --git a/src/char_sql/int_party.c b/src/char_sql/int_party.c index 4cafa9f4d..03392feb6 100644 --- a/src/char_sql/int_party.c +++ b/src/char_sql/int_party.c @@ -237,6 +237,10 @@ int inter_party_sql_init(){ return 0; } +void inter_party_sql_final(){ + if (party_pt) aFree(party_pt); + return; +} // Search for the party according to its name diff --git a/src/char_sql/int_party.h b/src/char_sql/int_party.h index 04f71c881..686d70b04 100644 --- a/src/char_sql/int_party.h +++ b/src/char_sql/int_party.h @@ -3,6 +3,7 @@ int inter_party_parse_frommap(int fd); int inter_party_sql_init(); +void inter_party_sql_final(); int inter_party_leave(int party_id,int account_id); #endif diff --git a/src/char_sql/int_pet.c b/src/char_sql/int_pet.c index 35a7710a7..ea1fed67d 100644 --- a/src/char_sql/int_pet.c +++ b/src/char_sql/int_pet.c @@ -136,6 +136,10 @@ int inter_pet_sql_init(){ return 0; } +void inter_pet_sql_final(){ + if (pet_pt) aFree(pet_pt); + return; +} //---------------------------------- int inter_pet_delete(int pet_id){ printf("request delete pet: %d.......\n",pet_id); diff --git a/src/char_sql/int_pet.h b/src/char_sql/int_pet.h index b6e3f1bbf..39f127262 100644 --- a/src/char_sql/int_pet.h +++ b/src/char_sql/int_pet.h @@ -2,6 +2,7 @@ #define _INT_PET_H_ int inter_pet_init(); +void inter_pet_sql_final(); int inter_pet_save(); int inter_pet_delete(int pet_id); diff --git a/src/char_sql/int_storage.c b/src/char_sql/int_storage.c index 48f5e04a1..9bb5318c6 100644 --- a/src/char_sql/int_storage.c +++ b/src/char_sql/int_storage.c @@ -166,6 +166,13 @@ int inter_storage_sql_init(){ return 1; } +// storage data finalize +void inter_storage_sql_final() +{ + if (storage_pt) aFree(storage_pt); + if (guild_storage_pt) aFree(guild_storage_pt); + return; +} // q?f[^? int inter_storage_delete(int account_id) { diff --git a/src/char_sql/int_storage.h b/src/char_sql/int_storage.h index f9f37db3e..5541d1ed7 100644 --- a/src/char_sql/int_storage.h +++ b/src/char_sql/int_storage.h @@ -2,6 +2,7 @@ #define _INT_STORAGE_H_ int inter_storage_sql_init(); +void inter_storage_sql_final(); int inter_storage_delete(int account_id); int inter_guild_storage_delete(int guild_id); diff --git a/src/char_sql/inter.c b/src/char_sql/inter.c index a8e0d4f44..13ce0acbe 100644 --- a/src/char_sql/inter.c +++ b/src/char_sql/inter.c @@ -290,12 +290,32 @@ int inter_init(const char *file) inter_pet_sql_init(); inter_accreg_sql_init(); + atexit(inter_final); + //printf ("interserver timer initializing : %d sec...\n",autosave_interval); //i=add_timer_interval(gettick()+autosave_interval,inter_save_timer,0,0,autosave_interval); return 0; } +// finalize +int wis_db_final (void *k, void *data, va_list ap) { + struct WisData *p = data; + if (p) aFree(p); + return 0; +} +void inter_final() { + numdb_final(wis_db, wis_db_final); + + inter_guild_sql_final(); + inter_storage_sql_final(); + inter_party_sql_final(); + inter_pet_sql_final(); + + if (accreg_pt) aFree(accreg_pt); + return; +} + int inter_mapif_init(int fd) { inter_guild_mapif_init(fd); diff --git a/src/char_sql/inter.h b/src/char_sql/inter.h index 4b61b69c5..1e6a26dce 100644 --- a/src/char_sql/inter.h +++ b/src/char_sql/inter.h @@ -2,10 +2,10 @@ #define _INTER_H_ int inter_init(const char *file); +void inter_final(); int inter_parse_frommap(int fd); int inter_mapif_init(int fd); - int inter_check_length(int fd,int length); int inter_log(char *fmt,...); diff --git a/src/common/core.c b/src/common/core.c index 96d2c872b..03945040a 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -285,6 +285,12 @@ int main(int argc,char **argv) { int next; + display_title(); +#ifdef USE_MEMMGR + // call this first so it'll be finalised last + do_init_memmgr(argv[0]); // 一番最初に実行する必要がある +#endif + sscanf(argv[0], "./%24[^\n]", server_type); // map/char/login? atexit(log_uptime); pid_create(argv[0]); @@ -305,12 +311,6 @@ int main(int argc,char **argv) compat_signal(SIGTRAP, SIG_DFL); #endif - display_title(); - -#ifdef USE_MEMMGR - do_init_memmgr(argv[0]); // 一番最初に実行する必要がある -#endif - tick_ = time(0); ticks = gettick(); diff --git a/src/common/malloc.c b/src/common/malloc.c index 40c9f34bf..703933d01 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -7,9 +7,6 @@ #include "memwatch.h" #endif -// 独自メモリマネージャを使用する場合、次のコメントを外してください。 -// #define USE_MEMMGR - #if !defined(DMALLOC) && !defined(GCOLLECT) && !defined(BCHECK) && !defined(USE_MEMMGR) void* aMalloc_( size_t size, const char *file, int line, const char *func ) @@ -537,6 +534,7 @@ static void memmer_exit(void) { printf("memmgr: no memory leaks found.\n"); } else { printf("memmgr: memory leaks found.\n"); + fclose(fp); } } diff --git a/src/common/malloc.h b/src/common/malloc.h index 45451c9e0..eec138cdd 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -3,6 +3,9 @@ #include +// 独自メモリマネージャを使用する場合、次のコメントを外してください。 +// #define USE_MEMMGR + #if defined(DMALLOC) # include "dmalloc.h" diff --git a/src/common/socket.c b/src/common/socket.c index f49d4c0ca..1c4d5931a 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -943,11 +943,9 @@ void do_final_socket(void) aFree(access_deny); // session[0] のダミーデータを削除 - if (session[0]) { - aFree(session[0]->rdata); - aFree(session[0]->wdata); - aFree(session[0]); - } + aFree(session[0]->rdata); + aFree(session[0]->wdata); + aFree(session[0]); } void do_socket(void) diff --git a/src/common/timer.h b/src/common/timer.h index c43c0e6b0..57036ae01 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -36,11 +36,9 @@ int addtick_timer(int tid,unsigned int tick); struct TimerData *get_timer(int tid); int do_timer(unsigned int tick); +void timer_final(); int add_timer_func_list(int (*)(int,unsigned int,int,int),char*); -void do_final_timer(void); char* search_timer_func_list(int (*)(int,unsigned int,int,int)); -extern void timer_final(); - #endif // _TIMER_H_ diff --git a/src/login/login.c b/src/login/login.c index a54aca410..27f7c12ce 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -3923,11 +3923,12 @@ void do_final(void) { memset(&server[i], 0, sizeof(struct mmo_char_server)); close(fd); delete_session(fd); - if(session[fd]) aFree(session[fd]); } } close(login_fd); delete_session(login_fd); + exit_dbn(); + timer_final(); login_log("----End of login-server (normal end with closing of all files)." RETCODE); diff --git a/src/login_sql/login.c b/src/login_sql/login.c index 91fc9ccb8..071b6d32c 100644 --- a/src/login_sql/login.c +++ b/src/login_sql/login.c @@ -41,30 +41,19 @@ void Gettimeofday(struct timeval *timenow) #include #include #include -#include "malloc.h" //add include for DBMS(mysql) #include -#include "../common/strlib.h" -#include "timer.h" -/* -#include "timer.h" -#include "core.h" -#include "socket.h" -#include "login.h" -#include "mmo.h" -#include "version.h" -#include "db.h" -*/ - #include "../common/core.h" #include "../common/socket.h" -#include "login.h" -#include "../common/mmo.h" -#include "../common/version.h" +#include "../common/malloc.h" #include "../common/db.h" #include "../common/timer.h" +#include "../common/strlib.h" +#include "../common/mmo.h" +#include "../common/version.h" +#include "login.h" #ifdef PASSWORDENC #include "md5calc.h" @@ -1835,6 +1824,24 @@ int flush_timer(int tid, unsigned int tick, int id, int data){ return 0; } +//-------------------------------------- +// Function called at exit of the server +//-------------------------------------- +static int online_db_final(void *key,void *data,va_list ap) +{ + int *p = data; + if (p) aFree(p); + return 0; +} +void do_final(void) { + //sync account when terminating. + //but no need when you using DBMS (mysql) + mmo_db_close(); + numdb_final(online_db, online_db_final); + exit_dbn(); + timer_final(); +} + int do_init(int argc,char **argv){ //initialize login server int i; @@ -1876,9 +1883,7 @@ int do_init(int argc,char **argv){ printf ("Running mmo_auth_sqldb_init()\n"); mmo_auth_sqldb_init(); printf ("finished mmo_auth_sqldb_init()\n"); - //sync account when terminating. - //but no need when you using DBMS (mysql) - set_termfunc(mmo_db_close); + set_termfunc(do_final); //set default parser as parse_login function set_defaultparse(parse_login); diff --git a/src/map/map.c b/src/map/map.c index 60d41b84e..9dcf541c1 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1697,24 +1697,24 @@ int map_addnpc(int m,struct npc_data *nd) { } void map_removenpc(void) { - int i,m,n=0; - - for(m=0;mbl,2); - map_delblock(&map[m].npc[i]->bl); - numdb_erase(id_db,map[m].npc[i]->bl.id); - if(map[m].npc[i]->bl.subtype==SCRIPT) { -// aFree(map[m].npc[i]->u.scr.script); -// aFree(map[m].npc[i]->u.scr.label_list); - } - aFree(map[m].npc[i]); - map[m].npc[i] = NULL; - n++; - } - } - } + int i,m,n=0; + + for(m=0;mbl,2); + map_delblock(&map[m].npc[i]->bl); + numdb_erase(id_db,map[m].npc[i]->bl.id); + if(map[m].npc[i]->bl.subtype==SCRIPT) { + aFree(map[m].npc[i]->u.scr.script); + aFree(map[m].npc[i]->u.scr.label_list); + } + aFree(map[m].npc[i]); + map[m].npc[i] = NULL; + n++; + } + } + } sprintf(tmp_output,"Successfully removed and freed from memory '"CL_WHITE"%d"CL_RESET"' NPCs.\n",n); ShowStatus(tmp_output); @@ -3097,29 +3097,20 @@ int flush_timer(int tid, unsigned int tick, int id, int data){ return 0; } -int id_db_final(void *k,void *d,va_list ap) +int id_db_final(void *k,void *d,va_list ap) { return 0; } +int map_db_final(void *k,void *d,va_list ap) { return 0; } +int nick_db_final(void *k,void *d,va_list ap) { - struct mob_data *id; - nullpo_retr(0, id = (struct mob_data*)d); - if(id->lootitem) - aFree(id->lootitem); - if(id) - aFree(id); + char *p = d; + if (p) aFree(p); return 0; } - -int map_db_final(void *k,void *d,va_list ap) +int charid_db_final(void *k,void *d,va_list ap) { - struct map_data *id; - nullpo_retr(0, id = (struct map_data*)d); - if(id->gat) - aFree(id->gat); - if(id) - aFree(id); + struct charid2nick *p = d; + if (p) aFree(p); return 0; } -int nick_db_final(void *k,void *d,va_list ap){ return 0; } -int charid_db_final(void *k,void *d,va_list ap){ return 0; } int cleanup_sub(struct block_list *bl, va_list ap) { nullpo_retr(0, bl); @@ -3152,12 +3143,12 @@ int cleanup_sub(struct block_list *bl, va_list ap) { *------------------------------------------ */ void do_final(void) { - int map_id, i; + int i; ShowStatus("Terminating...\n"); - for (map_id = 0; map_id < map_num;map_id++) - if(map[map_id].m) - map_foreachinarea(cleanup_sub, map_id, 0, 0, map[map_id].xs, map[map_id].ys, 0, 0); + for (i = 0; i < map_num; i++) + if(map[i].m) + map_foreachinarea(cleanup_sub, i, 0, 0, map[i].xs, map[i].ys, 0, 0); #ifndef TXT_ONLY chrif_char_reset_offline(); @@ -3165,38 +3156,35 @@ void do_final(void) { chrif_flush_fifo(); - for (i = 0; i < fd_max; i++) - delete_session(i); - -#if 0 - map_removenpc(); - -// do_final_timer(); (we used timer_final() instead) - timer_final(); -// numdb_final(id_db, id_db_final); - strdb_final(map_db, map_db_final); - strdb_final(nick_db, nick_db_final); - numdb_final(charid_db, charid_db_final); - +//#if 0 // why is this here? >_> do_final_chrif(); // この内部でキャラを全て切断する + do_final_npc(); +// map_removenpc(); do_final_script(); do_final_itemdb(); do_final_storage(); do_final_guild(); + do_final_party(); + do_final_pc(); do_final_pet(); -/* - for(i=0;ichat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){ + aFree (cd); + cd = NULL; + } + if (nd->bl.subtype == SCRIPT) { + if (nd->u.scr.timer_event) + aFree(nd->u.scr.timer_event); + if (nd->u.scr.src_id==0) { + if(nd->u.scr.script) { + aFree(nd->u.scr.script); + nd->u.scr.script=NULL; + } + if (nd->u.scr.label_list) { + aFree(nd->u.scr.label_list); + nd->u.scr.label_list = NULL; + } + } + } + clif_clearchar_area(&nd->bl, 2); + map_delblock(&nd->bl); + map_deliddb(&nd->bl); + aFree(nd); + nd = NULL; + return 0; +} static int ev_db_final(void *key,void *data,va_list ap) { aFree(data); @@ -2326,6 +2356,30 @@ static int ev_db_final(void *key,void *data,va_list ap) static int npcname_db_final(void *key,void *data,va_list ap) { return 0; +} +/*========================================== + * + *------------------------------------------ + */ +int npc_reload(void) +{ + struct npc_data *nd; + struct block_list *bl; + int i; + + if(ev_db) + strdb_final(ev_db,ev_db_final); + if(npcname_db) + strdb_final(npcname_db,npcname_db_final); + + for (i = START_NPC_NUM; i < npc_id; i++) { + if((bl = map_id2bl(i)) && bl->type == BL_NPC && (nd = (struct npc_data *)bl)) + npc_unload(nd); + } + + return 0; + + } /*========================================== * 終了 @@ -2337,7 +2391,6 @@ int do_final_npc(void) struct block_list *bl; struct npc_data *nd; struct mob_data *md; - struct chat_data *cd; struct pet_data *pd; if(ev_db) @@ -2345,31 +2398,14 @@ int do_final_npc(void) if(npcname_db) strdb_final(npcname_db,npcname_db_final); - for(i=START_NPC_NUM;itype == BL_NPC && (nd = (struct npc_data *)bl)){ - if(nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){ - aFree(cd); - cd = NULL; - } - if(nd->bl.subtype == SCRIPT){ - if(nd->u.scr.timer_event) - aFree(nd->u.scr.timer_event); - if(nd->u.scr.src_id==0){ - if(nd->u.scr.script){ - aFree(nd->u.scr.script); - nd->u.scr.script=NULL; - } - if(nd->u.scr.label_list){ - aFree(nd->u.scr.label_list); - nd->u.scr.label_list = NULL; - } - } - } - aFree(nd); - nd = NULL; - }else if(bl->type == BL_MOB && (md = (struct mob_data *)bl)){ - if(md->lootitem){ + npc_unload(nd); + }else if (bl->type == BL_MOB && (md = (struct mob_data *)bl)){ + if (md->lootitem){ aFree(md->lootitem); md->lootitem = NULL; } @@ -2415,10 +2451,10 @@ int do_init_npc(void) // comparing only the first 24 chars of labels that are 50 chars long isn't that nice // will cause "duplicated" labels where actually no dup is... //ev_db=strdb_init(24); - ev_db=strdb_init(51); - npcname_db=strdb_init(24); + ev_db = strdb_init(51); + npcname_db = strdb_init(24); - ev_db->release = ev_release; + ev_db->release = ev_release; memset(&ev_tm_b,-1,sizeof(ev_tm_b)); diff --git a/src/map/pc.c b/src/map/pc.c index 07e712dbe..8c0857d4b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -7234,6 +7234,11 @@ int pc_readdb(void) * pc? 係初期化 *------------------------------------------ */ +void do_final_pc(void) { + if (gm_account) + aFree(gm_account); + return; +} int do_init_pc(void) { pc_readdb(); diff --git a/src/map/pc.h b/src/map/pc.h index 242ae3147..8c4f96529 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -202,6 +202,7 @@ int pc_delspiritball(struct map_session_data *sd,int,int); int pc_eventtimer(int tid,unsigned int tick,int id,int data); // for npc_dequeue int do_init_pc(void); +void do_final_pc(void); enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT}; -- cgit v1.2.3-70-g09d2 From bdb9b86170175ac6c98b8c9b1034312a84487f41 Mon Sep 17 00:00:00 2001 From: Lupus Date: Thu, 24 Mar 2005 17:18:26 +0000 Subject: timers optimization / speed up / bug fix : no freezing mobs ported from Yor's git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1284 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-SVN.txt | 1 + src/common/timer.c | 366 ++++++++++++++++++----------------------------------- src/common/timer.h | 13 +- 3 files changed, 137 insertions(+), 243 deletions(-) (limited to 'src/common/timer.h') diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index 7f699be37..441e08bd1 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,7 @@ Date Added 03/24 + * Added timer.c optimization / timers sort fix. 'no freezing mobs anymore' Thanx 2 Yor/Freya [Lupus] * Added 'map_charid2id' [celest] * Changed monster damage logging to save char ID's for the most time -- also fixes an exp bug, thanks to Super Novice / Ezhik [celest] diff --git a/src/common/timer.c b/src/common/timer.c index 96631c078..90b4e901e 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -1,82 +1,75 @@ -// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 MagicalTux Exp $ +// $Id: timer.c,v 1.1.1.1 2004/09/10 17:44:49 Yor Exp $ // original : core.c 2003/02/26 18:03:12 Rev 1.7 +//#include + #include #include #include #include -#ifdef _WIN32 -#include +#ifdef __WIN32 +#define __USE_W32_SOCKETS +#include #else #include #include #endif #include "timer.h" -#include "utils.h" -#include "../common/malloc.h" +#include "malloc.h" #ifdef MEMWATCH #include "memwatch.h" #endif -// タイマー間隔の最小値。モンスターの大量召還時、多数のクライアント接続時に -// サーバーが反応しなくなる場合は、TIMER_MIN_INTERVEL を増やしてください。 - -// If the server shows no reaction when processing thousands of monsters -// or connected by many clients, please increase TIMER_MIN_INTERVEL. - -#define TIMER_MIN_INTERVEL 50 - static struct TimerData* timer_data; -static int timer_data_max,timer_data_num; +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=0; //fixed Shinomori from eA forums +static int timer_heap_num = 0, timer_heap_max = 0; 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[40]; + char* name; }; -static struct timer_func_list* tfl_root=NULL; +static struct timer_func_list* tfl_root; -#if defined(_WIN32) -void gettimeofday(struct timeval *t, struct timezone *dummy) -{ - DWORD millisec = GetTickCount(); +#ifdef __WIN32 +/* Modified struct timezone to void - we pass NULL anyway */ +void gettimeofday(struct timeval *t, void *dummy) { + DWORD millisec = GetTickCount(); - t->tv_sec = (int) (millisec / 1000); - t->tv_usec = (millisec % 1000) * 1000; + 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) -{ +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); + //CALLOC(tfl, struct timer_func_list, 1); + tfl = aCalloc( sizeof(struct timer_func_list) , 1); + //MALLOC(tfl->name, char, strlen(name) + 1); + tfl->name = aMalloc( strlen(name) + 1 ); tfl->next = tfl_root; tfl->func = func; - strncpy(tfl->name, name, sizeof(tfl->name) - 1); + strcpy(tfl->name, name); tfl_root = tfl; return 0; } -char* search_timer_func_list(int (*func)(int,unsigned int,int,int)) -{ +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) { + + for(tfl = tfl_root; tfl; tfl = tfl->next) { if (func == tfl->func) return tfl->name; } @@ -88,24 +81,21 @@ char* search_timer_func_list(int (*func)(int,unsigned int,int,int)) *----------------------------*/ static unsigned int gettick_cache; static int gettick_count; -unsigned int gettick_nocache(void) -{ -#ifdef _WIN32 - gettick_count = 256; // [Shinomori] - return gettick_cache = GetTickCount(); -#else + +unsigned int gettick_nocache(void) { struct timeval tval; - gettimeofday(&tval,NULL); + + gettimeofday(&tval, NULL); gettick_count = 256; - return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec/1000; -#endif + + return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec / 1000; } -unsigned int gettick(void) -{ +unsigned int gettick(void) { gettick_count--; - if (gettick_count<0) + if (gettick_count < 0) return gettick_nocache(); + return gettick_cache; } @@ -113,141 +103,66 @@ unsigned int gettick(void) * 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("*"); +static void push_timer_heap(int index) { + int i, j; + int min, max, pivot; // for sorting + + // check number of element + if (timer_heap_num >= timer_heap_max) { + if (timer_heap_max == 0) { + timer_heap_max = 256; + //CALLOC(timer_heap, int, 256); + timer_heap = aCalloc( sizeof(int) , 256); } else { - printf(" "); + timer_heap_max += 256; + //REALLOC(timer_heap, int, timer_heap_max); + timer_heap = aRealloc( timer_heap, sizeof(int) * timer_heap_max); + memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256); } - printf("%d : %d %d\n",j,timer_heap[j],timer_data[timer_heap[j]].tick); } -} -*/ - -static void push_timer_heap(int index) -{ - if (timer_heap == NULL || timer_heap[0] + 1 >= timer_heap_max) { - int first = timer_heap == NULL; - - timer_heap_max += 256; - timer_heap = (int*)aRealloc(timer_heap, sizeof(int) * timer_heap_max); - memset(timer_heap + (timer_heap_max - 256), 0, sizeof(int) * 256); - if (first) - timer_heap[0] = 0; - } - - // 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]++; - } - // check_timer_heap(); -} -// 指定したindex を持つタイマーヒープを返す -static int search_timer_heap(int index) -{ - if (timer_heap == NULL || timer_heap[0] <= 0) { - return -1; + // do a sorting from higher to lower + j = timer_data[index].tick; // speed up + // with less than 4 values, it's speeder to use simple loop + if (timer_heap_num < 4) { + for(i = timer_heap_num; i > 0; i--) + if (j < timer_data[timer_heap[i - 1]].tick) + break; + else + timer_heap[i] = timer_heap[i - 1]; + timer_heap[i] = index; + // searching by dichotomie } 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++; + // if lower actual item is higher than new + if (j < timer_data[timer_heap[timer_heap_num - 1]].tick) + timer_heap[timer_heap_num] = index; + else { + // searching position + min = 0; + max = timer_heap_num - 1; + while (min < max) { + pivot = (min + max) / 2; + if (j < timer_data[timer_heap[pivot]].tick) + min = pivot + 1; + else + max = pivot; } - printf("search_timer_heap : can't find tid:%d\n",index); - return -1; + // move elements - do loop if there are a little number of elements to move + if (timer_heap_num - min < 5) { + for(i = timer_heap_num; i > min; i--) + timer_heap[i] = timer_heap[i - 1]; + // move elements - else use memmove (speeder for a lot of elements) + } else + memmove(&timer_heap[min + 1], &timer_heap[min], sizeof(int) * (timer_heap_num - min)); + // save new element + timer_heap[min] = index; } } -} -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]--; - } + timer_heap_num++; } -#ifdef _WIN32 -int top_timer_heap(void) -#else -static inline int top_timer_heap(void) -#endif -{ - if (timer_heap == NULL || timer_heap[0] <= 0) - return -1; - - return timer_heap[timer_heap[0]]; -} - -#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) { struct TimerData* td; int i; @@ -258,25 +173,18 @@ int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int } else i = timer_data_num; if (i >= timer_data_num) - for (i = timer_data_num;i= timer_data_num && i >= timer_data_max) { - int j; if (timer_data_max == 0) { timer_data_max = 256; - CREATE_A(timer_data, struct TimerData, timer_data_max); - //timer_data[0] = NULL; + //CALLOC(timer_data, struct TimerData, timer_data_max); + timer_data = aCalloc( sizeof(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); + //REALLOC(timer_data, struct TimerData, timer_data_max); + timer_data = aRealloc( timer_data, sizeof(struct TimerData) * timer_data_max); + memset(timer_data + (timer_data_max - 256), 0, sizeof(struct TimerData) * 256); } - for(j = timer_data_max-256;jtick = tick; @@ -288,94 +196,79 @@ int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int 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 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)) -{ +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)); + (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; +// timer_data[id].tick -= 60 * 60 * 1000; + return 0; } -int addtick_timer(int tid,unsigned int tick) -{ - delete_timer_heap(tid); - timer_data[tid].tick += tick; - push_timer_heap(tid); - return timer_data[tid].tick; +int addtick_timer(int tid,unsigned int tick) { + return timer_data[tid].tick += tick; } -struct TimerData* get_timer(int tid) -{ + +struct TimerData* get_timer(int tid) { return &timer_data[tid]; } +int do_timer(unsigned int tick) { + int i, nextmin = 1000; -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(i == 2) { - i = 2; - } - if (DIFF_TICK(timer_data[i].tick , tick)>0) { - nextmin = DIFF_TICK(timer_data[i].tick , tick); + while(timer_heap_num) { + i = timer_heap[timer_heap_num - 1]; // next shorter element + if (DIFF_TICK(timer_data[i].tick, tick) > 0) { + nextmin = DIFF_TICK(timer_data[i].tick, tick); break; } - pop_timer_heap(); + 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 (DIFF_TICK(timer_data[i].tick , tick) < -1000) { + 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); + 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); + 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) { + 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])); + //REALLOC(free_timer_list, int, free_timer_list_max); + free_timer_list = 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; @@ -392,25 +285,14 @@ int do_timer(unsigned int tick) } } - if(nextmin < TIMER_MIN_INTERVEL) + if (nextmin < 10) + nextmin = 10; - nextmin = TIMER_MIN_INTERVEL; return nextmin; } -void timer_final(void) -{ - struct timer_func_list *tfl, *tfl_next; - for(tfl = tfl_root; tfl; tfl = tfl_next) - { - tfl_next = tfl->next; - aFree(tfl); - tfl = NULL; - } - if(timer_heap) - aFree(timer_heap); - if(free_timer_list) - aFree(free_timer_list); - if(timer_data) - aFree(timer_data); +void timer_final() { + //FREE(timer_data); + aFree(timer_data); } + diff --git a/src/common/timer.h b/src/common/timer.h index 57036ae01..81086cb70 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -3,6 +3,12 @@ #ifndef _TIMER_H_ #define _TIMER_H_ +#ifdef __WIN32 +/* We need winsock lib to have timeval struct - windows is weirdo */ +#define __USE_W32_SOCKETS +#include +#endif + #define BASE_TICK 5 #define TIMER_ONCE_AUTODEL 1 @@ -25,6 +31,10 @@ struct TimerData { // Function prototype declaration +#ifdef __WIN32 +void gettimeofday(struct timeval *t, void *dummy); +#endif + unsigned int gettick_nocache(void); unsigned int gettick(void); @@ -36,9 +46,10 @@ int addtick_timer(int tid,unsigned int tick); struct TimerData *get_timer(int tid); int do_timer(unsigned int tick); -void timer_final(); int add_timer_func_list(int (*)(int,unsigned int,int,int),char*); char* search_timer_func_list(int (*)(int,unsigned int,int,int)); +void timer_final(); + #endif // _TIMER_H_ -- cgit v1.2.3-70-g09d2