Question

When you've got a tight loop polling the status of something, I'm not quite sure how to do the polling without getting in the way of other processes wanting to use the CPU. For instance, doing this:

while (state == BUSY) state = check_state();

seems like a waste of resources. I would think the best way to do this would be:

while (state == BUSY) {
    sched_yield();
    state = check_state();
}

I'd expect that top would list the process as sleeping, even if it does consume 100% of the CPU while it's doing this. This way, the process would (I hope) poll "nicely". But that's not what happens. At the moment I have

while (state == BUSY) {
    sleep(1);
    state = check_state();
}

which is perfectly acceptable, but I feel like it could be done better than this. Is there a standard practice for doing this?

Was it helpful?

Solution

Don't spin on sched_yield(), it mucks up the scheduler's priority detection very badly and even when it interoperates well from a performance perspective will do things like wreck battery life and power consumption metrics. If your application can tolerate the latencies, polling with a timeout (even short ones like 10Hz) is very much preferable, if still not ideal.

The right answer depends on what check_state() actually needs to do. Are you absolutely sure you can't arrange things so that your state changes are kernel-visible events that you can block on?

OTHER TIPS

I don't suppose this is something you can use poll or epoll on?

Unfortunately, there's no such thing as conscientious polling. Polling is always a trade-off between reaction time and resource consumption: the shorter the polling period, the better the reaction time but the higher the resource consumption. The longer the polling period, the more energy you save but the less reactive your application becomes.

Polling is always ugly, no matter how you look at it. If you're trying to do things the right way, you'll have to use a better mechanism, i.e. notification. What that means is that your check_state() API is a bad one, because it only allows you to poll for the state; you need a function designed to notify you when the state changes. Typically, such a function would make some fd readable when the state changes, so you can synchronously or asynchronously wait for events on the fd, and only wake up when such an event occurs.

I think you could use libevent or libev.

Both provide facilities for handling things like this.

In my realtime work, I typically pick a reasonable timeout (like 10us), and spin on the condition and RDTSC (the time stamp counter).

If you want to spin for really long periods of time (like longer than 10ms), I'd suggest putting a small sleep statement in there so other stuff gets some chance to run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top