From: Tim Thompson Date: 2001-03-05T14:29:13+09:00 Subject: [ruby-talk:11990] higher-resolution Time for Win32 I want to use Ruby for realtime MIDI and audio on Windows. To do that, I need high-resolution timing. The existing C code in Ruby uses gettimeofday() to get the current time. I have made a modification so that, on Windows, it uses the timeGetTime() API to get a higher-resolution time. Before this change, Ruby's Time.now.tv_usec value on Windows 98 was quantized to a large (40-50 millisecond) amount, because of the poor implementation of gettimeofday() in Windows. After this change, Ruby's Time.now.tv_usec value on Windows 98 has millisecond-resolution (i.e. the resolution of the timeGetTime() API). I've tried to make a minimal (but complete) change, by added a rb_gettimeofday() function that all code uses instead of gettimeofday(). The winmm.lib library needs to be added to the makefile as well. A 'diff -u' for 1.6.2 is enclosed at the end of this message. I've tested the change on both Win98 and Linux. Any chance this change can be made in the official distribution? ...Tim Thompson...tjt@nosuch.com... ================================================================ --- win32/Makefile.sub.original Sun Mar 4 20:27:04 2001 +++ win32/Makefile.sub Sun Mar 4 20:33:31 2001 @@ -35,7 +35,7 @@ LDFLAGS = $(CFLAGS) -Fm XLDFLAGS = #EXTLIBS = -LIBS = user32.lib advapi32.lib wsock32.lib $(EXTLIBS) +LIBS = user32.lib advapi32.lib wsock32.lib $(EXTLIBS) winmm.lib MISSING = crypt.obj alloca.obj win32.obj isinf.obj isnan.obj LDSHARED = DLDFLAGS = --- eval.c.original Sun Mar 4 20:26:44 2001 +++ eval.c Sun Mar 4 20:03:09 2001 @@ -6771,7 +6771,7 @@ timeofday() { struct timeval tv; - gettimeofday(&tv, NULL); + rb_gettimeofday(&tv); return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6; } --- random.c.original Sun Mar 4 20:27:15 2001 +++ random.c Sun Mar 4 20:03:25 2001 @@ -119,7 +119,7 @@ static int n = 0; struct timeval tv; - gettimeofday(&tv, 0); + rb_gettimeofday(&tv); seed = tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++; } else { @@ -143,7 +143,7 @@ if (first) { struct timeval tv; - gettimeofday(&tv, 0); + rb_gettimeofday(&tv); rand_init(tv.tv_sec ^ tv.tv_usec ^ getpid()); } switch (TYPE(vmax)) { --- time.c.original Sun Mar 4 20:27:31 2001 +++ time.c Sun Mar 4 21:10:12 2001 @@ -26,6 +26,10 @@ #endif #endif /* NT */ +#ifdef NT +#include +#endif + #ifdef HAVE_SYS_TIMES_H #include #endif @@ -50,6 +54,31 @@ Data_Get_Struct(obj, struct time_object, tobj);\ } +int +rb_gettimeofday(struct timeval *tvp) +{ +#ifdef NT + static int initialized = 0; + static struct timeval tv0; + static long tm0; + long dt; + + if ( ! initialized ) { + initialized = 1; + tm0 = timeGetTime(); + if ( gettimeofday(&tv0, 0) < 0 ) + return -1; + } + dt = timeGetTime() - tm0; + *tvp = tv0; + tvp->tv_sec += dt / 1000; + tvp->tv_usec += 1000 * (dt % 1000); + return 0; +#else + return gettimeofday(tvp, 0); +#endif /* NT */ +} + static VALUE time_s_now(klass) VALUE klass; @@ -60,7 +89,7 @@ obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj); tobj->tm_got=0; - if (gettimeofday(&tobj->tv, 0) < 0) { + if (rb_gettimeofday(&tobj->tv) < 0) { rb_sys_fail("gettimeofday"); } @@ -294,7 +323,7 @@ struct tm *tm; long t, diff; - if (gettimeofday(&tv, 0) < 0) { + if (rb_gettimeofday(&tv) < 0) { rb_sys_fail("gettimeofday"); } guess = tv.tv_sec; ================================================================