digitalmars.D.learn - How to sleep accurately
- Jason House (24/24) Jun 27 2007 I've been trying for a while now to get a sleep routine that actually
- Daniel Giddings (12/47) Jun 27 2007 I'm not sure of the best way to do it but I'm interested in what people
- Jason House (4/19) Jun 27 2007 Thanks. I'm using that and it seems to be working well... I'll have to...
- Daniel Giddings (4/24) Jun 27 2007 I don't thin so, but to be honest I've never tried it. The man page
- Bill Baxter (11/30) Jun 27 2007 """
- BCS (20/51) Jun 28 2007 if you are on x86 and if you can get the clock speed and if you don't mi...
- Jason House (4/6) Jun 28 2007 I'm trying to stay as cross platform as possible. It's currently used
- BCS (4/13) Jul 02 2007 well if you are using x86 mac you would be potable and PPC has a similar...
I've been trying for a while now to get a sleep routine that actually works as I expect it to (sleeping for the time specified within a practical error margin). Let's say you want to sleep for 0.1 seconds (wall clock). msleep(100); // Not available under linux usleep(100000); // Not guaranteed to be reentrant... timespec ts; ts.sec = 0; ts.nsec = 100000000; nanosleep(ts,cast(timespec)null); // Thread safe Unfortunately, all of those can be interrupted by signals (such as the garbage collector running). Ignoring the reentrant issue (which seems to not affect stuff in practice), I tried the following: time_t now = clock(); time_t stop = now + 100000/CLOCKS_PER_SECOND; while(now<stop){ usleep(stop-now); now = clock(); } On windows, that seemed to work. Under linux, clock() keeps returning zero! It appears that it returns the process time that elapsed since the last call to clock rather than using any kind of absolute reference and is useless. Does anyone have a good way of doing this?
Jun 27 2007
I'm not sure of the best way to do it but I'm interested in what people think ;-) You can use gettimeofday under linux instead of clock. It's in std.c.linux.linux. long getTime() // in ms { timeval t; struct_timezone z; gettimeofday(&t, &z); return t.tv_sec * 1000 + t.tv_usec / 1000; } Jason House wrote:I've been trying for a while now to get a sleep routine that actually works as I expect it to (sleeping for the time specified within a practical error margin). Let's say you want to sleep for 0.1 seconds (wall clock). msleep(100); // Not available under linux usleep(100000); // Not guaranteed to be reentrant... timespec ts; ts.sec = 0; ts.nsec = 100000000; nanosleep(ts,cast(timespec)null); // Thread safe Unfortunately, all of those can be interrupted by signals (such as the garbage collector running). Ignoring the reentrant issue (which seems to not affect stuff in practice), I tried the following: time_t now = clock(); time_t stop = now + 100000/CLOCKS_PER_SECOND; while(now<stop){ usleep(stop-now); now = clock(); } On windows, that seemed to work. Under linux, clock() keeps returning zero! It appears that it returns the process time that elapsed since the last call to clock rather than using any kind of absolute reference and is useless. Does anyone have a good way of doing this?
Jun 27 2007
Daniel Giddings wrote:I'm not sure of the best way to do it but I'm interested in what people think ;-) You can use gettimeofday under linux instead of clock. It's in std.c.linux.linux. long getTime() // in ms { timeval t; struct_timezone z; gettimeofday(&t, &z); return t.tv_sec * 1000 + t.tv_usec / 1000; }Thanks. I'm using that and it seems to be working well... I'll have to add some kind of check for the end of the day. Will this have issues with daylight savings time? Can I force it to use a timezone without that?
Jun 27 2007
I don't thin so, but to be honest I've never tried it. The man page indicates that the timezone field is obsolete and null can be passed: http://www.rt.com/man/gettimeofday.2.html Jason House wrote:Daniel Giddings wrote:I'm not sure of the best way to do it but I'm interested in what people think ;-) You can use gettimeofday under linux instead of clock. It's in std.c.linux.linux. long getTime() // in ms { timeval t; struct_timezone z; gettimeofday(&t, &z); return t.tv_sec * 1000 + t.tv_usec / 1000; }Thanks. I'm using that and it seems to be working well... I'll have to add some kind of check for the end of the day. Will this have issues with daylight savings time? Can I force it to use a timezone without that?
Jun 27 2007
Jason House wrote:Daniel Giddings wrote:""" The gettimeofday() function shall obtain the current time, expressed as seconds and microseconds since the Epoch, and store it in the timeval structure pointed to by tp. The resolution of the system clock is unspecified. """ So no, you don't have to worry about the end of the day, just the end of something like 2^32 or 2^64 seconds from around January 1970, depending on your platform. --bbI'm not sure of the best way to do it but I'm interested in what people think ;-) You can use gettimeofday under linux instead of clock. It's in std.c.linux.linux. long getTime() // in ms { timeval t; struct_timezone z; gettimeofday(&t, &z); return t.tv_sec * 1000 + t.tv_usec / 1000; }Thanks. I'm using that and it seems to be working well... I'll have to add some kind of check for the end of the day.
Jun 27 2007
Reply to Jason,I've been trying for a while now to get a sleep routine that actually works as I expect it to (sleeping for the time specified within a practical error margin). Let's say you want to sleep for 0.1 seconds (wall clock). msleep(100); // Not available under linux usleep(100000); // Not guaranteed to be reentrant... timespec ts; ts.sec = 0; ts.nsec = 100000000; nanosleep(ts,cast(timespec)null); // Thread safe Unfortunately, all of those can be interrupted by signals (such as the garbage collector running). Ignoring the reentrant issue (which seems to not affect stuff in practice), I tried the following: time_t now = clock(); time_t stop = now + 100000/CLOCKS_PER_SECOND; while(now<stop){ usleep(stop-now); now = clock(); } On windows, that seemed to work. Under linux, clock() keeps returning zero! It appears that it returns the process time that elapsed since the last call to clock rather than using any kind of absolute reference and is useless. Does anyone have a good way of doing this?if you are on x86 and if you can get the clock speed and if you don't mind asm you can get a clock cycle resolution busy wait using: |long first,stop; |asm |{ | rdtsc; | mov first, EAX; | mov 4+first, EDX; |} | |stop = first + TimeInCPUCycles(); | |while(first < stop) | asm | { | rdtsc; | mov first, EAX; | mov 4+first, EDX; | }
Jun 28 2007
BCS wrote:if you are on x86 and if you can get the clock speed and if you don't mind asm you can get a clock cycle resolution busy wait using:I'm trying to stay as cross platform as possible. It's currently used on x86 and mac. I'm discovering that gettimeofday is not available on the mac. I still have to find another solution.
Jun 28 2007
Reply to Jason,BCS wrote:well if you are using x86 mac you would be potable and PPC has a similar CPU clock counter. But you would still need something else for any other system.if you are on x86 and if you can get the clock speed and if you don't mind asm you can get a clock cycle resolution busy wait using:I'm trying to stay as cross platform as possible. It's currently used on x86 and mac. I'm discovering that gettimeofday is not available on the mac. I still have to find another solution.
Jul 02 2007