Better solution [was: Re: [BUG][Linux] VM2.8 port eats processor cycles]
Stephan Rudlof
sr at evolgo.de
Thu Jun 29 16:10:50 UTC 2000
Below there is described a better solution for sleeping parts of seconds
in the idle process.
I wrote:
>
> Tim Rowledge wrote:
> >
> > In message <395A8532.6272A67E at evolgo.de> you wrote:
> >
> > > There is a bug somewhere. Possibly I have found the origin, see below.
> > [snip]
> > > There is a socketPollFunction, which has to be set by
> > > setSocketPollFunction( int spf), because it is initialized to 0;
> > > grep'ing for setSocketPollFunction() reveals:
> > >
> > > sr at Klaus:~/Squeak/2.8/src > grep setSocketPollFunction *.c *.h
> > > ../interp.c
> > > sqXWindow.c:void setSocketPollFunction( int spf) {
> > >
> > > . It won't be called! So ioRelinquishProcessorForMicroseconds() returns
> > > *very* fast and the idle process doesn't give processor cycles to the
> > > OS.
> > Well, sorta.
> > The setSocketPollFunction is called by the socket plugin (remember, you
> > have to grep _all_ the sources)
>
> Ooops, sorry, I have missed this.
>
> > in its initialiseModule() code. So if
> > you haven't done a socket call, then yes I guess you never go to sleep.
>
> That's it.
>
> > Hmm, anyone know how to handle something like this? Is there a sleep
> > type of call that will do partial seconds? Seems kind of poor to require
> > people to do a socket call in order to sleep!
>
> Solution:
>
> Just evaluate
> NetNameResolver resolverError
> (shouldn't do too much ;-) ) and the module will be initialized:
> initialiseModule() -> socketInit() -> setSocketPollFunction()
> .
>
> This is a workaround!
A better solution is desribed in the following.
This C-function allows sleeping partial seconds:
NANOSLEEP(2) Linux Programmer's Manual NANOSLEEP(2)
NAME
nanosleep - pause execution for a specified time
SYNOPSIS
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec
*rem);
DESCRIPTION
nanosleep delays the execution of the program for at least
the time specified in *req. The function can return ear
lier if a signal has been delivered to the process. In
this case, it returns -1, sets errno to EINTR, and writes
the remaining time into the structure pointed to by rem
unless rem is NULL. The value of *rem can then be used to
call nanosleep again and complete the specified pause.
The structure timespec is used to specify intervals of
time with nanosecond precision. It is specified in
<time.h> and has the form
struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
The value of the nanoseconds field must be in the range 0
to 999 999 999.
Compared to sleep(3) and usleep(3), nanosleep has the
advantage of not affecting any signals, it is standardized
by POSIX, it provides higher timing resolution, and it
allows to continue a sleep that has been interrupted by a
signal more easily.
...
BUGS
The current implementation of nanosleep is based on the
normal kernel timer mechanism, which has a resolution of
Linux 1.3.85 1996-04-10 1
NANOSLEEP(2) Linux Programmer's Manual NANOSLEEP(2)
1/HZ s (i.e, 10 ms on Linux/i386 and 1 ms on Linux/Alpha).
Therefore, nanosleep pauses always for at least the speci
fied time, however it can take up to 10 ms longer than
specified until the process becomes runnable again. For
the same reason, the value returned in case of a delivered
signal in *rem is usually rounded to the next larger mul
tiple of 1/HZ s.
...
Probably a 10 ms resolution is sufficient.
sqXWindow.c ioRelinquishProcessorForMicroseconds() could be changed from
int ioRelinquishProcessorForMicroseconds(int microSeconds)
{
/* sleep in select() for immediate response to socket i/o */
#ifdef HEADLESS
if ( socketPollFunction ) { socketPollFunction(microSeconds,0);}
/* aioPollForIO(microSeconds, 0); */
#else
if ( socketPollFunction ) { socketPollFunction(microSeconds,stXfd);}
/* aioPollForIO(microSeconds, stXfd); */
#endif
return microSeconds;
}
to
int ioRelinquishProcessorForMicroseconds(int microSeconds)
{
if ( socketPollFunction ) {
/* sleep in select() for immediate response to socket i/o */
#ifdef HEADLESS
socketPollFunction(microSeconds,0);
/* aioPollForIO(microSeconds, 0); */
#else
socketPollFunction(microSeconds,stXfd);
/* aioPollForIO(microSeconds, stXfd); */
#endif
}
else {
struct timespec sleepTime, reminderTime;
sleepTime.tv_sec = microSeconds / 1000000;
sleepTime.tv_nsec = microSeconds % 1000000 * 1000;
nanosleep(&sleepTime, &reminderTime);
}
return microSeconds; "BTW: What's the sense of this return here? [sr]"
}
Stephan
> Greetings,
>
> Stephan
>
> >
> > tim
> >
> > --
> > Tim Rowledge, tim at sumeru.stanford.edu, http://sumeru.stanford.edu/tim
> > Useful Latin Phrases:- Ventis secundis, tene cursum. = Go with the flow.
>
> --
> Stephan Rudlof (sr at evolgo.de)
> "Genius doesn't work on an assembly line basis.
> You can't simply say, 'Today I will be brilliant.'"
> -- Kirk, "The Ultimate Computer", stardate 4731.3
--
Stephan Rudlof (sr at evolgo.de)
"Genius doesn't work on an assembly line basis.
You can't simply say, 'Today I will be brilliant.'"
-- Kirk, "The Ultimate Computer", stardate 4731.3
More information about the Squeak-dev
mailing list
|