What are you waiting for?

One of the common problems I’ve helped customers with is optimising their device startup time.

There are many things you can do to squeeze a few precious seconds out of your startup sequence, but one of the simplest may not be immediately obvious.

The sequence

devb-eide
waitfor /dev/hd0 30

is an all too common one, but it’s surprisingly damaging if you are trying to not waste cycles.

For one thing, it means that you can’t really start anything after the waitfor until devb-eide has gone through its sometimes lengthy initialization sequence (sorry devb, don’t mean to pick on you…).

Really all the system can do is to finish off the initialization of any servers you already started and poll for the device to appear.

Wait a second – POLL??!!!

Hmmm, in RTOS speak, Poll=BAD, WaitForAnEvent=GOOD!

Yes, my friends, it’s sad to say that /bin/waitfor (actually the amazingly versatile /bin/on) does actually poll, with a period of 100ms to boot, as does the builtin version that procnto provides when running your image’s startup script.

There are a number of nasties associated with this, one of the most annoying being that if your device appears 1ms after that 100ms poll (which is just a stat()) then you’re going to wait around for ANOTHER 99ms before waitfor notices!

And unless you have plenty else going on in the meantime then that means the dreaded idle thread will happily be using up your precious cpu. Another good reason to have plenty of servers started BEFORE you do the waitfor.

So how about a remedy?

Well, the basic version of waitfor looks something like this…

while we haven’t reached the max limit
do
stat the device
if it’s there, break out
delay 100ms
done

Wouldn’t it be nice if we could do something more like

while we haven’t reached the max limit
do
sleep for the remaining timeout, but wakeup if the device appears?
done

Well, as it happens, if you are running QNX6.3.0 SP2 or later, then there is actually a facility you can use. It’s a new flag to procmgr_event_notify, PROCMGR_EVENT_NAMESPACE,which will see a sigevent winging it’s way to you whenever the pathspace changes, which is basically whenever someone attaches or detaches a pathname.

So here’s a revised version of waitfor that waits until something changes, then hopefully stats the device.

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/procmgr.h>
#include <sys/siginfo.h>

int main( int argc, char *argv[] )
{
struct sigevent event;
struct stat sbuf;
int timeout;
int total;
char *path;
time_t start, now;

path = argv[1];
timeout = atoi(argv[2]);

if ( stat( argv[1], &sbuf ) == 0 ) {
printf(“Found %s!\n”, path );
return EXIT_SUCCESS;
}

SIGEV_UNBLOCK_INIT( &event );
procmgr_event_notify( PROCMGR_EVENT_PATHSPACE, &event );

start = time(NULL);
do {
sleep( timeout );
if ( stat( argv[1], &sbuf ) == 0 ) {
printf(“Found %s!\n”, path );
return EXIT_SUCCESS;
}
now = time(NULL);
timeout -= (now – start);
start = now;
} while( timeout > 0 );
return EXIT_FAILURE;
}

If 99ms of idle time upsets you, this might help you sleep better.

Colin

PS – yes, this will be fixed in the next release of the kernel/utils, if I have anything to do with it.

PPS – I should mention that there is yet another location that waitfor is defined, that is the ewaitfor builtin in /bin/fesh. This version at least lets you set the poll period, as a third argument to ewaitfor. Again, that should be in 6.3.0 SP2 or later.

About these ads

12 comments so far

  1. Mario on

    On that subject, there are scripts ( ph for example ) that will use sleep 1 inside while loop to detect the startup of things like pwm and shelf.

    On the system I’m working I removed the sleep all together because it’s a dual core and I don’t care if the shell uses all of one core, i just want to have the machine boot AFAP. Result is my custom ph script start a little more then twice as fast as the one with the sleep.

    That being said I think it would be nice if “sleep” could take fraction of second as argument. Something like sleep .1, would help make scripts like ph more cpu friendly while decreasing startup time.

  2. Mario on

    The program doesn’t work if the device already exists. I added an extra stat check before the do/while.

  3. colinburgess on

    WRT changing sleep to take a shorter timeout, while I appreciate what you are trying to do, it’s just going to use more CPU.

    It would be far better to use the PATHSPACE event for waiting for /dev/phfont etc to appear.

    The loops which wait for phin to succeed would be more problematic, since they aren’t waiting for a device name, rather for various regions to appear.

    Colin

    PS – thanks for the comment on the program. I’ve moved the sleep to after the stat() for now.

  4. Mario on

    As far as ph, yes I was making reference to the usage of phin to detect the presence of a region and the related use of sleep in these loops.

    Having sleep with smaller values would take an insignificant amount of CPU cycles, mainly when taking into account the time the loop takes. What’s a few extra invocation of sleep to get photon to start twice as fast ;-)

    Cheers

  5. Mario on

    Hum are you sure that when sleep() gets interrupted that the path really exists. I put the program in a image instead of waitfor and sometimes it seems to exit because of the timeout.

  6. colinburgess on

    Yeah, again a good point – I’ve added the extra stat. But there is a small window it could miss, so I’m thinking of a slightly different approach… more soon.

  7. Xiaodan Tang on

    Think you need to register the event first, then do your first stat().

  8. colinburgess on

    in fact I’ve completely re-written it – new version will be posted soon…

  9. Kevin on

    Colin,

    Would love to have that new and improved waitfor, any progress on getting it posted?

    Thanks
    Kevin

  10. Kevin on

    Never mind…you put it in the article already, I guess I was expecting a new post…

    Thanks
    Kevin

  11. colinburgess on

    Actually I do have a completely new version ready to go – thanks for reminding me, I’ll try to have it out tomorrow.

  12. [...] been waiting long enough! Posted May 27, 2007 In my previous post on the problems with a polling waitfor, I mentioned that there was a timing window in which we [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: