On Tue, 23 Jul 2002, Aldo Calpini wrote: > Nicholas Clark wrote: > > Does Microsoft give you (well, us) a select() implementation that > > really does honour the microsecond field of the struct timeval > > it's passed? > > AFAIK, microseconds are honoured only on sockets, not on filehandles.
I'm not at all sure on this one, but I do know Time::HiRes falls back onto select() if usleep isn't defined. > > I seem to remember reading somewhere that the most portable way of > > achieving a sub second sleep was to call select() for that period > > waiting on no file descriptors. > > well, that was perl5, and guess what the implementation does in > src/win32/win32sck.c ? > > if (!(rd || wr || ex)) { > if (timeout) > Sleep(timeout->tv_sec * 1000 + > timeout->tv_usec / 1000); /* do the best we can */ As does Time::HiRes: void hrt_usleep(unsigned long usec) { long msec; msec = usec / 1000; Sleep (msec); } So that's what I've done. See attached for a patch, tested on Win32 and linux. I've patched darwin.c (& ansi.c) too, but haven't had a chance to test it. And I haven't fallen back onto using select - if that proves to be a problem we can add support in the future. There's also an example attached for fun :). Regards, +-- Steve Purkis <[EMAIL PROTECTED]>
diff -cr parrot/ChangeLog parrot-usleep/ChangeLog *** parrot/ChangeLog Tue Mar 19 23:03:05 2002 --- parrot-usleep/ChangeLog Tue Jul 23 14:35:00 2002 *************** *** 1,3 **** --- 1,7 ---- + 2002-07-23 13:39 spurkis + + * added usleep(INT), sleep(NUM) ops + docs, tests + 2002-03-19 22:54 nicholas * docs/running.pod: Patch from Simon Glover <[EMAIL PROTECTED]>: diff -cr parrot/config/gen/platform/ansi.c parrot-usleep/config/gen/platform/ansi.c *** parrot/config/gen/platform/ansi.c Sun Jun 9 19:17:41 2002 --- parrot-usleep/config/gen/platform/ansi.c Tue Jul 23 14:33:14 2002 *************** *** 45,50 **** --- 45,62 ---- /* + ** Parrot_usleep() + */ + + void + Parrot_usleep(unsigned int microseconds) + { + fprintf(stderr, "[ANSI] Parrot_usleep not implemented!\n"); + return; + } + + + /* ** Parrot_setenv() */ void diff -cr parrot/config/gen/platform/ansi.h parrot-usleep/config/gen/platform/ansi.h *** parrot/config/gen/platform/ansi.h Thu Jul 18 05:11:49 2002 --- parrot-usleep/config/gen/platform/ansi.h Tue Jul 23 14:33:42 2002 *************** *** 17,22 **** --- 17,23 ---- */ void Parrot_sleep(unsigned int seconds); + void Parrot_usleep(unsigned int microseconds); INTVAL Parrot_intval_time(void); FLOATVAL Parrot_floatval_time(void); void Parrot_setenv(const char *name, const char *value); diff -cr parrot/config/gen/platform/darwin.c parrot-usleep/config/gen/platform/darwin.c *** parrot/config/gen/platform/darwin.c Sun Jun 9 19:17:41 2002 --- parrot-usleep/config/gen/platform/darwin.c Tue Jul 23 14:32:56 2002 *************** *** 49,54 **** --- 49,65 ---- /* + ** Parrot_usleep() + */ + + void + Parrot_usleep(unsigned int microseconds) + { + usleep(microseconds); + } + + + /* ** Parrot_setenv() */ diff -cr parrot/config/gen/platform/darwin.h parrot-usleep/config/gen/platform/darwin.h *** parrot/config/gen/platform/darwin.h Thu Jul 18 05:11:49 2002 --- parrot-usleep/config/gen/platform/darwin.h Tue Jul 23 14:33:36 2002 *************** *** 17,22 **** --- 17,23 ---- */ void Parrot_sleep(unsigned int seconds); + void Parrot_usleep(unsigned int microseconds); INTVAL Parrot_intval_time(void); FLOATVAL Parrot_floatval_time(void); void Parrot_setenv(const char *name, const char *value); diff -cr parrot/config/gen/platform/generic.c parrot-usleep/config/gen/platform/generic.c *** parrot/config/gen/platform/generic.c Sun Jun 9 22:12:42 2002 --- parrot-usleep/config/gen/platform/generic.c Tue Jul 23 13:16:03 2002 *************** *** 47,52 **** --- 47,63 ---- /* + ** Parrot_usleep() + */ + + void + Parrot_usleep(unsigned int microseconds) + { + usleep(microseconds); + } + + + /* ** Parrot_setenv() */ diff -cr parrot/config/gen/platform/generic.h parrot-usleep/config/gen/platform/generic.h *** parrot/config/gen/platform/generic.h Thu Jul 18 05:11:49 2002 --- parrot-usleep/config/gen/platform/generic.h Tue Jul 23 13:16:03 2002 *************** *** 17,22 **** --- 17,23 ---- */ void Parrot_sleep(unsigned int seconds); + void Parrot_usleep(unsigned int microseconds); INTVAL Parrot_intval_time(void); FLOATVAL Parrot_floatval_time(void); void Parrot_setenv(const char *name, const char *value); diff -cr parrot/config/gen/platform/win32.c parrot-usleep/config/gen/platform/win32.c *** parrot/config/gen/platform/win32.c Sun Jun 9 19:17:41 2002 --- parrot-usleep/config/gen/platform/win32.c Tue Jul 23 14:31:22 2002 *************** *** 50,55 **** --- 50,69 ---- /* + ** Parrot_usleep() + */ + + void + Parrot_usleep(unsigned int microseconds) + { + if (microseconds < 1000) { + fprintf(stderr, "[WIN32] Parrot_usleep cannot sleep for less than +1000us!\n"); + } else { + Sleep(microseconds / 1000); + } + } + + /* ** Parrot_setenv() */ diff -cr parrot/config/gen/platform/win32.h parrot-usleep/config/gen/platform/win32.h *** parrot/config/gen/platform/win32.h Tue Jul 23 08:25:36 2002 --- parrot-usleep/config/gen/platform/win32.h Tue Jul 23 14:33:25 2002 *************** *** 26,31 **** --- 26,32 ---- */ void Parrot_sleep(unsigned int seconds); + void Parrot_usleep(unsigned int microseconds); INTVAL Parrot_intval_time(void); FLOATVAL Parrot_floatval_time(void); void Parrot_setenv(const char *name, const char *value); diff -cr parrot/core.ops parrot-usleep/core.ops *** parrot/core.ops Thu Jul 18 05:29:39 2002 --- parrot-usleep/core.ops Tue Jul 23 14:37:42 2002 *************** *** 3983,3998 **** Sleep for $1 seconds. =cut inline op sleep(in INT) { if ($1 < 0) { ! internal_exception(NEG_SLEEP, "Cannot go back in time"); } Parrot_sleep((UINTVAL)$1); goto NEXT(); } ####################################### --- 3983,4022 ---- Sleep for $1 seconds. + =item B<sleep>(in NUM) + + Sleep for $1 fractions of a second + + =item B<usleep>(in INT) + + Sleep for $1 microseconds + =cut inline op sleep(in INT) { if ($1 < 0) { ! internal_exception(NEG_SLEEP, "Cannot sleep back in time"); } Parrot_sleep((UINTVAL)$1); goto NEXT(); } + inline op sleep(in NUM) { + if ((FLOATVAL) $1 < (FLOATVAL) 0.0) { + internal_exception(NEG_SLEEP, "Cannot sleep back in time"); + } + Parrot_usleep((UINTVAL) ($1 * (FLOATVAL) 1000000.0)); + goto NEXT(); + } + + inline op usleep(in INT) { + if ($1 < 0) { + internal_exception(NEG_SLEEP, "Cannot sleep back in time"); + } + Parrot_usleep((UINTVAL)$1); + goto NEXT(); + } + ####################################### diff -cr parrot/t/op/time.t parrot-usleep/t/op/time.t *** parrot/t/op/time.t Sat Jun 1 04:54:19 2002 --- parrot-usleep/t/op/time.t Tue Jul 23 13:16:03 2002 *************** *** 1,6 **** #! perl -w ! use Parrot::Test tests => 4; output_is(<<'CODE', <<'OUTPUT', "time_i"); time I0 --- 1,6 ---- #! perl -w ! use Parrot::Test tests => 8; output_is(<<'CODE', <<'OUTPUT', "time_i"); time I0 *************** *** 65,73 **** done OUTPUT ! output_is(<<CODE, 'Cannot go back in time', "sleep"); sleep -1 end CODE 1; --- 65,127 ---- done OUTPUT ! output_is(<<CODE, <<OUTPUT, "usleep"); ! print "start\\n" ! ! time N1 ! ! usleep 100000 ! set I0, 100000 ! usleep I0 ! ! time N0 ! ! gt N0, N1, ALLOK ! print "no, usleeping made time go the wrong way " ! ! ALLOK: ! print "done\\n" ! end ! CODE ! start ! done ! OUTPUT ! ! output_is(<<CODE, <<OUTPUT, "sleep"); ! print "start\\n" ! ! time N1 ! ! sleep 0.1 ! set N0, 0.1 ! sleep N0 ! ! time N0 ! ! gt N0, N1, ALLOK ! print "no, sleeping (fractional time) made time go the wrong way " ! ! ALLOK: ! print "done\\n" ! end ! CODE ! start ! done ! OUTPUT ! ! output_is(<<CODE, 'Cannot sleep back in time', "sleep"); sleep -1 end CODE + output_is(<<CODE, 'Cannot sleep back in time', "sleep"); + sleep -1.0 + end + CODE + + output_is(<<CODE, 'Cannot sleep back in time', "usleep"); + usleep -1 + end + CODE + 1;
# # sleep.pasm # # Copyright (C) 2002 Steve Purkis. All rights reserved. # This program is free software. It is subject to the same # license as The Parrot Interpreter. # # $Id: $ # MAIN: set I0, 100000 print "sleeping for " print I0 print " microseconds\n" usleep I0 print "sleeping for 999 microseconds (should produce a warning on Win32)\n" usleep 999 print "sleeping for 1.75 seconds\n" time N0 sleep 1.75 time N1 sub N0, N1, N0 print "actual time: " print N0 print "\n" print "sleeping for 1 second\n" sleep 1 print "done.\n" end