added --enable-rdtsc configure option to enhance timer performance, especially in virtualized environments; default disabled - credits to sirius_black

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14265 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
Yommy 2010-03-16 21:42:14 +00:00
parent 2b305d5a62
commit f9c60fd3fa
3 changed files with 3031 additions and 3858 deletions

6807
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,30 @@ AC_ARG_ENABLE(
[enable_debug="no"]
)
#
# RDTSC as Tick Source
#
AC_ARG_ENABLE(
[rdtsc],
AC_HELP_STRING(
[--enable-rdtsc],
[
Uses rdtsc as timing source (disabled by default)
Enable it when you've timing issues.
(For example: in conjunction with XEN or Other Virtualization mechanisms)
Note:
Please ensure that you've disabled dynamic CPU-Frequencys, such as power saving options.
(On the most modern Dedicated Servers cpufreq is preconfigured, see your distribution's manual
how to disable it)
]
),
[
enable_rdtsc=1
],
[enable_rdtsc=0]
)
#
# Profiler
@ -383,6 +407,19 @@ case $enable_debug in
esac
#
# RDTSC
#
case $enable_rdtsc in
0)
#default value
;;
1)
CFLAGS="$CFLAGS -DENABLE_RDTSC"
;;
esac
#
# Profiler
#

View File

@ -100,11 +100,52 @@ char* search_timer_func_list(TimerFunc func)
* Get tick time
*----------------------------*/
#if defined(ENABLE_RDTSC)
static uint64 RDTSC_BEGINTICK = 0, RDTSC_CLOCK = 0;
static __inline uint64 _rdtsc(){
register union{
uint64 qw;
uint32 dw[2];
} t;
asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]) );
return t.qw;
}
static void rdtsc_calibrate(){
uint64 t1, t2;
int32 i;
ShowStatus("Calibrating Timer Source, please wait... ");
RDTSC_CLOCK = 0;
for(i = 0; i < 5; i++){
t1 = _rdtsc();
usleep(1000000); //1000 MS
t2 = _rdtsc();
RDTSC_CLOCK += (t2 - t1) / 1000;
}
RDTSC_CLOCK /= 5;
RDTSC_BEGINTICK = _rdtsc();
ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000) );
}
#endif
/// platform-abstracted tick retrieval
static unsigned int tick(void)
{
#if defined(WIN32)
return GetTickCount();
#elif defined(ENABLE_RDTSC)
//
return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK);
//
#elif (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) /* posix compliant */) || (defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 500005 /* FreeBSD >= 5.1.0 */)
struct timespec tval;
clock_gettime(CLOCK_MONOTONIC, &tval);
@ -368,6 +409,10 @@ unsigned long get_uptime(void)
void timer_init(void)
{
#if defined(ENABLE_RDTSC)
rdtsc_calibrate();
#endif
time(&start_time);
}