I'm running Newlisp on Solaris 8 and when I run the following
program:
#!/usr/local/bin/newlisp
#
# Demonstrate bug in (sleep) on Solaris 8
(println "n(sleep 999) interval is too short.")
(dotimes (i 10)
(println (format "%02d " i) (date (apply date-value (now))))
(sleep 999)
)
(println "n(sleep 1000) is correct.")
(dotimes (i 10)
(println (format "%02d " i) (date (apply date-value (now))))
(sleep 1000)
)
(exit)
I get the following results:
ca1$ date_clock
(sleep 999) interval is too short.
00 Wed Aug 11 00:34:11 2004
01 Wed Aug 11 00:34:11 2004
02 Wed Aug 11 00:34:11 2004
03 Wed Aug 11 00:34:11 2004
04 Wed Aug 11 00:34:11 2004
05 Wed Aug 11 00:34:11 2004
06 Wed Aug 11 00:34:11 2004
07 Wed Aug 11 00:34:11 2004
08 Wed Aug 11 00:34:11 2004
09 Wed Aug 11 00:34:11 2004
(sleep 1000) is correct.
00 Wed Aug 11 00:34:11 2004
01 Wed Aug 11 00:34:12 2004
02 Wed Aug 11 00:34:13 2004
03 Wed Aug 11 00:34:14 2004
04 Wed Aug 11 00:34:15 2004
05 Wed Aug 11 00:34:16 2004
06 Wed Aug 11 00:34:17 2004
07 Wed Aug 11 00:34:18 2004
08 Wed Aug 11 00:34:19 2004
09 Wed Aug 11 00:34:20 2004
ca1$
If I can do anything to help track this down, please let me know.
Thanks.
Looking at the source nl-filesys.c the section involved seems to be
void mySleep(UINT ms)
{
#ifdef NANOSLEEP
struct timespec tm;
tm.tv_sec = ms/1000;
tm.tv_nsec = (ms - tm.tv_sec * 1000) * 1000000;
nanosleep(&tm, 0);
#else
#ifdef MINGW
_sleep(ms);
#else
sleep(ms/1000);
#endif
#endif
}
Is nanosleep used on Sol8?
if not the code is
sleep(ms/1000);
with ms UINT so I guess integer division is giving
999/1000=0
If nanosleep is enabled someone else will need to comment on that section.
Nigel
NANOSLEEP is not enabled for Solaris compiles (see makefile_solaris) and most likely not available on your machine.
For that reason (sleep milliseconds) has only 1 second resolution on your machine.
If you happen to know how to do a 'sleep' with finer resolution on your platform, let me know and I can build it in.
Lutz
On Solaris 5.9 nanosleep() is available, use the following changes in the makefile:
in CFLAGS include -DNANOSLEEP
CFLAGS = -Wall -pedantic -Wno-uninitialized -c -O2 -g -DNANOSLEEP -DSOLARIS -DOPSYS=4
in the compile line include the library -lrt
$(CC) $(OBJS) -g -lm -ldl -lrt -lsocket -lnsl -o newlisp
I just tried in on a X86 with Solaris 5.9 and it gives you millisec resolution. This option will be included in the next makefile_solaris as default, if it works for you. Perhaps HPW has also a feedback on this from his Solaris people running on a Sparc station.
Lutz
Perhaps for any non-NANOSLEEP situation the code
sleep(ms/1000);
with ms UINT so I guess integer division is giving
999/1000=0
could be
sleep((ms + 500)/1000);
to round to the nearest second rather than truncate?
Nigel
Quote from: "Lutz"
On Solaris 5.9 nanosleep() is available, use the following changes in the makefile:
in CFLAGS include -DNANOSLEEP
CFLAGS = -Wall -pedantic -Wno-uninitialized -c -O2 -g -DNANOSLEEP -DSOLARIS -DOPSYS=4
in the compile line include the library -lrt
$(CC) $(OBJS) -g -lm -ldl -lrt -lsocket -lnsl -o newlisp
I just tried in on a X86 with Solaris 5.9 and it gives you millisec resolution. This option will be included in the next makefile_solaris as default, if it works for you. Perhaps HPW has also a feedback on this from his Solaris people running on a Sparc station.
Lutz
This worked fine. Thank you.
uname -a on my machine shows:
SunOS carbon 5.8 Generic_108528-17 sun4u sparc SUNW,Ultra-2