sleep() for less than a second

1,121 views
Skip to first unread message

mermaldad

unread,
Mar 14, 2006, 6:50:55 AM3/14/06
to gg95
I'm working on a program using g95 which involves sending commands to
an I/O controller. Some of the actions that the I/O controller is
performing should last less than one second. g95 has an intrinsic
procedure sleep() which allows one to suspend operation of the program,
but the argument is the integer number of seconds to sleep. I want to
suspend program operation for less than a second. I know I could
repeatedly check the time until I reach a desired time, but that wastes
cycles which other processes may need. Is there a better way?

Joost

unread,
Mar 14, 2006, 9:21:07 AM3/14/06
to gg95
Hi,

sleep in g95 is a basically a wrapper for the libc sleep, which also
sleeps in seconds. If you read the libc info for sleep

http://www.delorie.com/gnu/docs/glibc/libc_445.html

you'll find that they suggest to use 'select'

http://www.delorie.com/gnu/docs/glibc/libc_248.html

so I would suggest that you code a simple 'sleep' function that takes
a real argument and write the corresponding C code based on select to
do just that. If you have something working, I would suggest to send
the code to Andy, I think that a sleep command that takes a real would
be a nice extension.

Cheers,

Joost

Helge Avlesen

unread,
Mar 14, 2006, 3:15:58 PM3/14/06
to gg95
Joost wrote:
> so I would suggest that you code a simple 'sleep' function that takes
> a real argument and write the corresponding C code based on select to

an integer number of nano seconds is another option, like e.g. below

Helge


/avle@fimm: > cat sleep.c
#include <time.h>
int ftnsleep_(long *nano_seconds, int *ierr){
struct timespec sleeptime ;
sleeptime.tv_sec = 0 ;
sleeptime.tv_nsec = *nano_seconds ;
*ierr = nanosleep(&sleeptime, NULL);
}
/avle@fimm: > cat wait.f90
integer(8) :: ns=800000000
call ftnsleep(ns,ierr)
print *,'waited',ns,'nano seconds',ierr
end
/avle@fimm: > gcc -c sleep.c
/avle@fimm: > g95 wait.f90 sleep.o && ./a.out
waited 800000000 nano seconds 0
/avle@fimm: >

mermaldad

unread,
Mar 18, 2006, 8:20:45 AM3/18/06
to gg95
Thanks for the suggestions. However, both select and nanosleep are, if
I'm not mistaken, BSD Unix functions. So they work on my Fedora Core 3
systems, but not on my Windows/MinGW systems. Unfortunately the
Windows systems are where I really need this functionality. Any
suggestions?

Helge Avlesen

unread,
Mar 18, 2006, 3:38:52 PM3/18/06
to gg95
right. so you need the native windows sleep, not the g95 one. the
windows
sleep function takes milliseconds as the argument I think.

Helge

Joost

unread,
Mar 19, 2006, 3:45:30 AM3/19/06
to gg95
I think that the ISO_C_BINDING (again .. :-) provides a way to access
this function directly from fortran. I.e. the following does what it
should:

MODULE TEST
USE ISO_C_BINDING, ONLY : C_INT
IMPLICIT NONE

INTERFACE
SUBROUTINE millisleep(n) BIND(C,name="Sleep")
USE ISO_C_BINDING, ONLY : C_INT
INTEGER(C_INT), VALUE :: n
END SUBROUTINE millisleep
END INTERFACE

END MODULE TEST

USE TEST
INTEGER :: count1,count2,count_rate
REAL :: t1,t2
write(6,*) "Hi 1"
CALL sleep(1)
write(6,*) "Hi 2"
CALL CPU_TIME(t1)
CALL SYSTEM_CLOCK(count=count1,count_rate=count_rate)
CALL millisleep(%VAL(150_C_INT))
CALL SYSTEM_CLOCK(count=count2)
CALL CPU_TIME(t2)
write(6,*) "Hi 3, CPU TIME: ",t2-t1," REAL TIME
",REAL(count2-count1)/count_rate
END

> ./a.exe
Hi 1
Hi 2
Hi 3, CPU TIME: 0. REAL TIME 0.1492

However, I also think it highlights some bugs in the g95 ISO_C_BINDING
implementation, since I seem to need the first call to sleep to pull in
the Sleep, the %VAL should also be unneeded, and there are some
warnings at link time concerning stdcall... However,all of this is just
tested in a cygwin setup, things might be different from mingw.

Joost

Joost

unread,
Mar 19, 2006, 11:47:36 AM3/19/06
to gg95
as a follow-up, Andy fixed the problem with the %VAL, so that it won't
be needed for recent versions of g95, and I played around a bit with
the linking The call seems to be resolved using:

SUBROUTINE millisleep(n) BIND(C,name="Sleep@4")

instead of the original declaration. I don't know if this is papering
over a real problem...

Joost

mermaldad

unread,
Mar 19, 2006, 1:52:23 PM3/19/06
to gg95
Excellent!

The need for a first call to sleep must be a cygwin thing, because I
can comment that out without effect under MinGW. Thanks to both of
you. Although I really needed the Win32 solution, I'm sure someone
will be glad to find the BSD solution as well. And having them both on
the same thread points to the portability issues here.

Thanks again!

Joost

unread,
Mar 20, 2006, 2:17:53 AM3/20/06
to gg95
Another mistake I found in my example ... C_INT should be C_LONG.

Joost

Reply all
Reply to author
Forward
0 new messages