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

Reply via email to