* small timer.c cleaning
- removed "with less than 4 values, it's speedier to use a simple loop" as this case will never occur (premature optimization from r1284) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11499 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
@@ -3,6 +3,10 @@ Date Added
|
||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2007/10/17
|
||||
* small timer.c cleaning
|
||||
- removed "with less than 4 values, it's speedier to use a simple loop"
|
||||
as this case will never occur (premature optimization from r1284)
|
||||
2007/10/16
|
||||
* Venom Splasher fixes according to bugreport:230
|
||||
- added passive skillv*30% bonus from Poison React
|
||||
|
||||
@@ -1,29 +1,20 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../common/cbasetypes.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/showmsg.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef WIN32
|
||||
//#define __USE_W32_SOCKETS
|
||||
// Well, this won't last another 30++ years (where conversion will truncate).
|
||||
//#define _USE_32BIT_TIME_T // use 32 bit time variables on 64bit windows
|
||||
//#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h> // GetTickCount()
|
||||
#endif
|
||||
|
||||
// タイマー間隔の最小値。モンスターの大量召還時、多数のクライアント接続時に
|
||||
// サーバーが反応しなくなる場合は、TIMER_MIN_INTERVAL を増やしてください。
|
||||
|
||||
@@ -47,20 +38,6 @@ static int free_timer_list_pos = 0;
|
||||
static int timer_heap_num = 0;
|
||||
static int timer_heap_max = 0;
|
||||
static int* timer_heap = NULL;
|
||||
// searches for the target tick's position and stores it in pos (binary search)
|
||||
#define HEAP_SEARCH(target,from,to,pos) \
|
||||
do { \
|
||||
int max,pivot; \
|
||||
pos = from; \
|
||||
max = to; \
|
||||
while (pos < max) { \
|
||||
pivot = (pos + max) / 2; \
|
||||
if (DIFF_TICK(target, timer_data[timer_heap[pivot]].tick) < 0) \
|
||||
pos = pivot + 1; \
|
||||
else \
|
||||
max = pivot; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
// for debug
|
||||
struct timer_func_list {
|
||||
@@ -70,6 +47,7 @@ struct timer_func_list {
|
||||
};
|
||||
static struct timer_func_list* tfl_root = NULL;
|
||||
|
||||
// server startup time
|
||||
time_t start_time;
|
||||
|
||||
/// Sets the name of a timer function.
|
||||
@@ -110,40 +88,8 @@ char* search_timer_func_list(TimerFunc func)
|
||||
* Get tick time
|
||||
*----------------------------*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#if defined(TICK_CACHE) && TICK_CACHE > 1
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// tick is cached for TICK_CACHE calls
|
||||
static unsigned int gettick_cache;
|
||||
static int gettick_count;
|
||||
|
||||
unsigned int gettick_nocache(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
gettick_count = TICK_CACHE;
|
||||
return gettick_cache = GetTickCount();
|
||||
#else
|
||||
struct timeval tval;
|
||||
|
||||
gettimeofday(&tval, NULL);
|
||||
gettick_count = TICK_CACHE;
|
||||
|
||||
return gettick_cache = tval.tv_sec * 1000 + tval.tv_usec / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int gettick(void)
|
||||
{
|
||||
if (--gettick_count < 0)
|
||||
return gettick_nocache();
|
||||
|
||||
return gettick_cache;
|
||||
}
|
||||
//////////////////////////////
|
||||
#else
|
||||
//////////////////////////////
|
||||
// tick doesn't get cached
|
||||
unsigned int gettick(void)
|
||||
/// platform-abstracted tick retrieval
|
||||
static unsigned int tick(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return GetTickCount();
|
||||
@@ -153,6 +99,38 @@ unsigned int gettick(void)
|
||||
return tval.tv_sec * 1000 + tval.tv_usec / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#if defined(TICK_CACHE) && TICK_CACHE > 1
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// tick is cached for TICK_CACHE calls
|
||||
static unsigned int gettick_cache;
|
||||
static int gettick_count = 1;
|
||||
|
||||
unsigned int gettick_nocache(void)
|
||||
{
|
||||
gettick_count = TICK_CACHE;
|
||||
gettick_cache = tick();
|
||||
return gettick_cache;
|
||||
}
|
||||
|
||||
unsigned int gettick(void)
|
||||
{
|
||||
return ( --gettick_count == 0 ) ? gettick_nocache() : gettick_cache;
|
||||
}
|
||||
//////////////////////////////
|
||||
#else
|
||||
//////////////////////////////
|
||||
// tick doesn't get cached
|
||||
unsigned int gettick_nocache(void)
|
||||
{
|
||||
return tick();
|
||||
}
|
||||
|
||||
unsigned int gettick(void)
|
||||
{
|
||||
return tick();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -160,12 +138,26 @@ unsigned int gettick(void)
|
||||
/*======================================
|
||||
* CORE : Timer Heap
|
||||
*--------------------------------------*/
|
||||
|
||||
// searches for the target tick's position and stores it in pos (binary search)
|
||||
#define HEAP_SEARCH(target,from,to,pos) \
|
||||
do { \
|
||||
int max,pivot; \
|
||||
pos = from; \
|
||||
max = to; \
|
||||
while (pos < max) { \
|
||||
pivot = (pos + max) / 2; \
|
||||
if (DIFF_TICK(target, timer_data[timer_heap[pivot]].tick) < 0) \
|
||||
pos = pivot + 1; \
|
||||
else \
|
||||
max = pivot; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/// Adds a timer to the timer_heap
|
||||
static void push_timer_heap(int tid)
|
||||
{
|
||||
unsigned int tick;
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
// check number of element
|
||||
if (timer_heap_num >= timer_heap_max) {
|
||||
@@ -180,37 +172,16 @@ static void push_timer_heap(int tid)
|
||||
}
|
||||
|
||||
// do a sorting from higher to lower
|
||||
tick = timer_data[tid].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) //Plain comparisons break on bound looping timers. [Skotlex]
|
||||
if (DIFF_TICK(tick, timer_data[timer_heap[i - 1]].tick) < 0)
|
||||
break;
|
||||
else
|
||||
timer_heap[i] = timer_heap[i - 1];
|
||||
}
|
||||
timer_heap[i] = tid;
|
||||
// searching by dichotomy (binary search)
|
||||
} else {
|
||||
// if lower actual item is higher than new
|
||||
// if (j < timer_data[timer_heap[timer_heap_num - 1]].tick) //Plain comparisons break on bound looping timers. [Skotlex]
|
||||
if (DIFF_TICK(tick, timer_data[timer_heap[timer_heap_num - 1]].tick) < 0)
|
||||
timer_heap[timer_heap_num] = tid;
|
||||
else {
|
||||
// searching position
|
||||
HEAP_SEARCH(tick,0,timer_heap_num-1,pos);
|
||||
// move elements - do loop if there are a little number of elements to move
|
||||
if (timer_heap_num - pos < 5) {
|
||||
for(i = timer_heap_num; i > pos; i--)
|
||||
timer_heap[i] = timer_heap[i - 1];
|
||||
// move elements - else use memmove (speeder for a lot of elements)
|
||||
} else
|
||||
memmove(&timer_heap[pos + 1], &timer_heap[pos], sizeof(int) * (timer_heap_num - pos));
|
||||
// save new element
|
||||
timer_heap[pos] = tid;
|
||||
}
|
||||
if( timer_heap_num == 0 || DIFF_TICK(timer_data[tid].tick, timer_data[timer_heap[timer_heap_num - 1]].tick) < 0 )
|
||||
timer_heap[timer_heap_num] = tid; // if lower actual item is higher than new
|
||||
else
|
||||
{
|
||||
// searching position
|
||||
HEAP_SEARCH(timer_data[tid].tick,0,timer_heap_num-1,pos);
|
||||
// move elements
|
||||
memmove(&timer_heap[pos + 1], &timer_heap[pos], sizeof(int) * (timer_heap_num - pos));
|
||||
// save new element
|
||||
timer_heap[pos] = tid;
|
||||
}
|
||||
|
||||
timer_heap_num++;
|
||||
@@ -328,9 +299,6 @@ int settick_timer(int tid, unsigned int tick)
|
||||
if( old_tick == tick )
|
||||
return tick;
|
||||
|
||||
//FIXME: This search is not all that effective... there doesn't seems to be a better way to locate an element in the heap.
|
||||
//for(i = timer_heap_num-1; i >= 0 && timer_heap[i] != tid; i--);
|
||||
|
||||
// search old_tick position
|
||||
HEAP_SEARCH(old_tick,0,timer_heap_num-1,old_pos);
|
||||
while( timer_heap[old_pos] != tid )
|
||||
|
||||
@@ -8,18 +8,11 @@
|
||||
#include "../common/cbasetypes.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* We need winsock lib to have timeval struct - windows is weirdo */
|
||||
//#define __USE_W32_SOCKETS
|
||||
//#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#define BASE_TICK 5
|
||||
|
||||
#define TIMER_ONCE_AUTODEL 0x1
|
||||
#define TIMER_INTERVAL 0x2
|
||||
#define TIMER_REMOVE_HEAP 0x10
|
||||
#define TIMER_ONCE_AUTODEL 0x01
|
||||
#define TIMER_INTERVAL 0x02
|
||||
#define TIMER_REMOVE_HEAP 0x10
|
||||
|
||||
#define DIFF_TICK(a,b) ((int)((a)-(b)))
|
||||
|
||||
@@ -41,12 +34,8 @@ struct TimerData {
|
||||
|
||||
// Function prototype declaration
|
||||
|
||||
#if defined(TICK_CACHE) && TICK_CACHE > 1
|
||||
unsigned int gettick_nocache(void);
|
||||
#else
|
||||
#define gettick_nocache gettick
|
||||
#endif
|
||||
unsigned int gettick(void);
|
||||
unsigned int gettick_nocache(void);
|
||||
|
||||
int add_timer(unsigned int,TimerFunc f,int,int);
|
||||
int add_timer_interval(unsigned int tick, TimerFunc func, int id, int data, int interval);
|
||||
|
||||
Reference in New Issue
Block a user