I have encountered a strange behaviour with usleep(3C) C function. I have a
client-server program where both server and client wait in a
while (1) {
if (condition met)
break;
usleep(100); /* or 10 or 1000 ... */
}
type of loop (at different time) and the processing of 2000 requests takes
about 40 seconds on any Solaris machine (regardless of CPU, speed etc.) and
it takes less than a second on a AIX machine (of the similar speed as one
of Solaris machines), so it seems that usleep() is a rather expensive call
on Solaris.
If I try to implement usleep() using poll(2) system call or using
nanosleep(3RT) C function, instead of 40 seconds, the whole process takes
about 20 seconds (I have converted microseconds argument of usleep() to
milliseconds for poll() and nanoseconds for nanosleep())! Somehow, it
doesn't make much sense to me.
OK, I know that busy--loop is probably not the best approach waiting for
resources (in the meantime I have found and implemented a better method),
but these differences (40s vs. 20s using poll()) and especially the
difference between Solaris and AIX machines (40s vs. < 1s) don't make much
sense to me.
What's so terribly wrong with usleep? OS in questions are Solaris 8 and
Solaris 2.6 (one Enterprise 220R with 2 CPUs and one Ultra 5).
Thanks a lot.
Dragan
--
Dragan Cvetkovic,
To be or not to be is true. G. Boole
usleep is not recommended. From the man page:
---
USAGE
The usleep() function is included for its historical usage.
The setitimer(2) function is preferred over this function.
---
nanosleep() is the recommended replacement.
The problem you run into when you call nanosleep() 2000 times, trying
to sleep for 100盜 at a time is that the shortest time you can sleep
is one tick. One tick is normally 10ms on a sun system, which makes
your 2000 one tick sleeps 20s.
If you set "hires_tick" to 1 in /etc/system, the tick will be 1ms,
which is the shortest supported.
The kernel variable "hires_hz" is normally 1000 and this is the rate
you get when setting hires_tick to 1. Setting "hires_hz" to 10000
would give you a basic tick of 100盜 at the expense of a higher system
time. This is also not supported, so you can't complain if you have a
problem with it.
Thomas
Thomas Tornblom <tho...@Hax.SE.remove-to-reply> writes:
>nanosleep() is the recommended replacement.
>The problem you run into when you call nanosleep() 2000 times, trying
>to sleep for 100盜 at a time is that the shortest time you can sleep
>is one tick. One tick is normally 10ms on a sun system, which makes
>your 2000 one tick sleeps 20s.
And because various standards require *minimum sleeps*, Solaris must
wait until it sees *tw* clock ticks. I.e., on average 15ms and is
this code more likely 20ms for each sleep (the next usleep() starts
when a tick has just passed; it waits for two more, so you get 20ms)
>If you set "hires_tick" to 1 in /etc/system, the tick will be 1ms,
>which is the shortest supported.
In which case each wait will be 2ms (for 4 seconds).
>The kernel variable "hires_hz" is normally 1000 and this is the rate
>you get when setting hires_tick to 1. Setting "hires_hz" to 10000
>would give you a basic tick of 100盜 at the expense of a higher system
>time. This is also not supported, so you can't complain if you have a
>problem with it.
Does probably work.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Thomas and Casper, thanks a lot for your answers. Now I have much clearer
picture about usleep (and why should I avoid using it). I still don't
understand why is AIX implementation of usleep() so much faster.
Thanks again,
Dragan Cvetkovic <dragan...@99.soliton.com> writes:
>Thomas and Casper, thanks a lot for your answers. Now I have much clearer
>picture about usleep (and why should I avoid using it). I still don't
>understand why is AIX implementation of usleep() so much faster.
It probably uses a different underlying mechanism; i.e., it does
sleep for the amount of time requested rather than the amount of time
rounded up to the nearest clock tick.
In Solaris 8, you can achieve a similar thing using certain real time
timeouts (but those are restricted)
> And because various standards require *minimum sleeps*, Solaris must
Speaking of various standards:
Solaris 8 man page:
The usleep() function suspends the current process from execution
Unix 98[1]:
The usleep() function suspends the calling thread from execution
Any explanation for the difference?
--
.-. .-. Sarcasm is just one more service we offer.
(_ \ / _)
| da...@arsdigita.com
|
> It probably uses a different underlying mechanism; i.e., it does
> sleep for the amount of time requested rather than the amount of time
> rounded up to the nearest clock tick.
>
> In Solaris 8, you can achieve a similar thing using certain real time
> timeouts (but those are restricted)
>
Thanks. Do you mean timer_gettime(3RT), timer_settime(3RT) etc. functions
from librt?
da...@arsdigita.com (Drazen Kacar) writes:
>Casper H.S. Dik - Network Security Engineer wrote:
>> And because various standards require *minimum sleeps*, Solaris must
>Speaking of various standards:
>Solaris 8 man page:
> The usleep() function suspends the current process from execution
>Unix 98[1]:
> The usleep() function suspends the calling thread from execution
>Any explanation for the difference?
I'd suspect: "error in Solaris 8 manual".