1

I have an application which uses boost asio and I would like to use poll() to detect ready network events (packets) and process them as quickly as possible.

Additionally, I would like to use SCHED_FIFO for this process (which is single threaded) try to control the jitter (main problem I'm trying to solve..)

Now the limitation, the kernel is 2.6.32 (without real-time patch.) Which has the additional problem that there are some kernel processes which run on the core where my app is running which I cannot move out (i.e. the kernel doesn't appear to have true isolation - I know this comes in a later kernel - but I can't upgrade to that yet.)

So, now if I'm unfriendly, and I do the following:

while(some_condition)
  service.poll();

This process will spin the core, and because SCHED_FIFO is set, it will never relinquish to the other kernel processes that need to run on this core, and all sort of unpredictable bad stuff happens. Now my question is, how I can do this poll loop and ensure that I relinquish so that the other threads get to run for a little bit at least?

I see two options,

  1. Some sort of sleep
  2. if no events were handled by poll(), I could call run_one() which blocks for one event only, but the problem here is that this event could be the packet I want, and now I have jitter again...

Have I missed any other approaches?

  • 2
    If you're talking about the poll syscall, the poll syscall blocks (assuming timeout!=0), it doesn't immediately return unless there is activity. If it blocks, the kernel will schedule something else. – Patrick Jul 11 '14 at 15:17
1

I have not used Boost::asio, but it looks at first glance like you want to use .run() and not .poll(). As Patrick points out, the normative poll() system call can block passively, whereas asio::poll() explicitly will not (requiring you to busy loop), but run() does:

The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.

Of course, this doesn't solve the problem if you are dealing with an unrelenting stream of packets -- but then I think you've been backed into a corner. If the system must make periodic use of that core, and you must also use only that core, and giving it up introduces latency into your handling, that's a rock and a hard place.

  • Thanks for your input, yes, I understand that run() will block, however the downside of this is that I'm now waiting on an interrupt to pick up the next packet. The poll() approach means I don't need to wait for this - the downside being I'm blocking other kernel level stuff running, it seems evident that an upgrade to the latest kernel is the only way forward... – Nim Jul 14 '14 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.