public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Stephen Satchell <list@satchell.net>
To: jesse <jessezx@yahoo.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Gurus, a silly question for preemptive behavior
Date: Sun, 26 Dec 2004 11:30:52 -0800	[thread overview]
Message-ID: <41CF116C.1030202@satchell.net> (raw)
In-Reply-To: <20041221024347.3004.qmail@web52606.mail.yahoo.com>

jesse wrote:
>  
> As i know, in linux, user space application is
> preemptive at any time. however, linux kernel is NOT
> preemptive, that means, even some event is finished,
> Linux kernel scheduler itself still can't have
> opportunity to interrupt the current user application
> and switch it out. it is called scheduler latency.
> normally , the latency is about 88us in mean , maximum
> : 200ms. Thus, the short latency shouldn't impact user
> applications too much and is not a problem. It is an
> issue in those embedded voice processing systems by
> introducing jitters, thus smart people came up with
> two kernel schedule patch: preemptive patch and low
> latency patch. 
> 
> My application which has nice value as 10 of low
> priority, however, it holds the CPU and excludes other
> applciations that have higher priority (nice 0) to
> run, my application causes CPU pegging. 
> 
> Thus, I am wondering: why  user space application
> can't be effectively interrupted? why there is CPU
> pegging?   Could you please educate me 
> on this particular issue and shed me some light to
> address it? 
> 
> my system: 
> [root@sa-c2-7 proc]# uname  -a 
> Linux sa-c2-7 2.4.21-15.ELsmp #1 SMP Thu Apr 22
> 00:18:24 EDT 2004 i686 i686 i386 GNU/Linux 

First, a pre-emption happens when an external event occurs that makes a 
higher priority task change state from blocked to ready-to-run, and the 
scheduling algorithm says that the new task should be run in place of 
the old task -- and the complexity of the time-slice schedule is such 
that your assumption doesn't always hold true.

If you have a low-priority task that needs to make sure that 
higher-priority functions *always* run, and you can't move up to the 2.6 
kernel (or even after moving up you find yourself with problems) the 
userland solution is a simple one:

   if (1) {
    struct timeval delay = {0,20000};
    select(0, NULL, NULL, NULL, &delay);
    }

(DON'T declare the variable delay as constant, because select modifies 
the contents of this variable.)

A number of real-time operating systems provide for a give-up-control 
system call, which says "if you have something better to do than to run 
me, then do it" for just this sort of thing.  The legacy of the Linux 
schedules being from a classic time-sharing system, which trys to 
implement "fairness" in allocating CPU resources,  there is no 
equivalent call that I'm aware of.

So you have to make your program block in order to guarantee that you 
give up the CPU.  The delay of 20 ms in my example call assumes your HZ 
value is 100, and that you really don't mind having a few idle CPU 
cycles if your higher-priority program isn't ready to run when you make 
the select call.  In my Web servers, I use 100 ms delays to ensure that 
I/O for other processes is allowed to take place; Webalizer stats, for 
example, have hogged disk access to the point that it impacts the entire 
system, so I've inserted the Perl equivalent of the above code in key 
places so that background tasks really do run in the background.

A delay value of zero to select is, I believe, an effective no-operation 
which may or may not trigger a scheduling event.  (I looked a long time 
ago at this -- many, MANY kernels ago -- and it's as though you didn't 
make the call at all, absent the CPU cycles expended to make the call 
and for the kernel to get back to the userland task.)  A value of 10 ms 
(on a system with HZ set to 100) can also be taken as though you coded 
zero in some cases -- at least some code I wrote a couple of years ago 
suggests this.

Why select?  I write portable code, and this is in my cookbook.  There 
is a nanosleep system call that is part of POSIX, and that looks to be a 
preferable way to deal with things.  You would need to look at the Linux 
source code to see what a nanosleep with a value of one nanosecond does, 
and whether that's guaranteed to block your code for one scheduling cycle.

How frequently you put scheduling breaks into your code is up to you.  I 
typicall profile code, and try to put in scheduling breaks at 1/4 of the 
desired system response latency.  For a 100 ms latency, that means that 
I do scheduling breaks no less frequently than 25 ms., and in many cases 
more often than that.  Don't forget that I/O provides breaks, too, so 
the number of places where you need to put in explicit scheduling breaks 
may be small, indeed.

For Webalizer, I run a scheduling break every 100 lines read from the 
log files.  That count, by experimentation, has shown to provide a good 
balance between throughout of the background process and system reaction 
latency.  That's stuff running on a 2.4 kernel, by the way, because I'm 
slow to adopt new, bleeding-edge stuff in my production environments.

A couple of thoughts from a different place in the trenches.

Stephen Satchell


      parent reply	other threads:[~2004-12-26 19:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-21  2:43 Gurus, a silly question for preemptive behavior jesse
2004-12-21  5:59 ` Con Kolivas
2004-12-21 18:32   ` jesse
2004-12-21 18:44     ` Paulo Marques
2004-12-21 19:03       ` jesse
2004-12-21 19:23         ` Paulo Marques
2004-12-21 21:35         ` Con Kolivas
2004-12-21 23:07           ` jesse
2004-12-22  2:16             ` Con Kolivas
2004-12-22 12:39             ` K.R. Foley
2004-12-26 19:30 ` Stephen Satchell [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41CF116C.1030202@satchell.net \
    --to=list@satchell.net \
    --cc=jessezx@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox