* how to let all others run
@ 2001-04-02 14:05 Oliver Neukum
2001-04-04 20:11 ` John Fremlin
0 siblings, 1 reply; 8+ messages in thread
From: Oliver Neukum @ 2001-04-02 14:05 UTC (permalink / raw)
To: linux-kernel
Hi,
is there a way to let all other runable tasks run until they block or return
to user space, before the task wishing to do so is run again ?
TIA
Oliver
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-02 14:05 how to let all others run Oliver Neukum
@ 2001-04-04 20:11 ` John Fremlin
2001-04-04 21:00 ` Richard B. Johnson
0 siblings, 1 reply; 8+ messages in thread
From: John Fremlin @ 2001-04-04 20:11 UTC (permalink / raw)
To: Oliver Neukum; +Cc: linux-kernel
Hi Oliver!
Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> writes:
> is there a way to let all other runable tasks run until they block
> or return to user space, before the task wishing to do so is run
> again ?
Are you trying to do this in kernel or something? From userspace you
can use nice(2) then sched_yield(2), though I don't know if the linux
implementations will guarrantee anything.
--
http://www.penguinpowered.com/~vii
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-04 20:11 ` John Fremlin
@ 2001-04-04 21:00 ` Richard B. Johnson
2001-04-05 15:55 ` John Fremlin
0 siblings, 1 reply; 8+ messages in thread
From: Richard B. Johnson @ 2001-04-04 21:00 UTC (permalink / raw)
To: John Fremlin; +Cc: Oliver Neukum, linux-kernel
On 4 Apr 2001, John Fremlin wrote:
>
> Hi Oliver!
>
> Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> writes:
>
> > is there a way to let all other runable tasks run until they block
> > or return to user space, before the task wishing to do so is run
> > again ?
>
> Are you trying to do this in kernel or something? From userspace you
> can use nice(2) then sched_yield(2), though I don't know if the linux
> implementations will guarrantee anything.
>
I recommend using usleep(0) instead of sched_yield(). Last time I
checked, sched_yield() seemed to spin and eat CPU cycles, usleep(0)
always gives up the CPU.
Try:
for(;;) usleep();
and
for(;;) sched_yield();
.. you'll see a quiet behavior under `top` for usleep(0), and over 80%
with sched_yield().
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-04 21:00 ` Richard B. Johnson
@ 2001-04-05 15:55 ` John Fremlin
2001-04-05 16:52 ` Richard B. Johnson
0 siblings, 1 reply; 8+ messages in thread
From: John Fremlin @ 2001-04-05 15:55 UTC (permalink / raw)
To: root; +Cc: Oliver Neukum, linux-kernel
"Richard B. Johnson" <root@chaos.analogic.com> writes:
> On 4 Apr 2001, John Fremlin wrote:
> >
> > Hi Oliver!
> >
> > Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> writes:
> >
> > > is there a way to let all other runable tasks run until they block
> > > or return to user space, before the task wishing to do so is run
> > > again ?
> >
> > Are you trying to do this in kernel or something? From userspace you
> > can use nice(2) then sched_yield(2), though I don't know if the linux
> > implementations will guarrantee anything.
> >
>
> I recommend using usleep(0) instead of sched_yield(). Last time I
> checked, sched_yield() seemed to spin and eat CPU cycles, usleep(0)
> always gives up the CPU.
What is wrong with this? sched_yield only yields to processes with
lower priority (hence suggestion to use nice(2)). Does sched_yield()
fail to yield in cases when a higher priority process wants to run?
usleep() wastes time if no other such process is waiting, surely?
[...]
--
http://www.penguinpowered.com/~vii
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-05 15:55 ` John Fremlin
@ 2001-04-05 16:52 ` Richard B. Johnson
2001-04-05 20:41 ` Oliver.Neukum
2001-04-05 22:29 ` Ion Badulescu
0 siblings, 2 replies; 8+ messages in thread
From: Richard B. Johnson @ 2001-04-05 16:52 UTC (permalink / raw)
To: John Fremlin; +Cc: Oliver Neukum, linux-kernel
On 5 Apr 2001, John Fremlin wrote:
> "Richard B. Johnson" <root@chaos.analogic.com> writes:
>
> > On 4 Apr 2001, John Fremlin wrote:
> > >
> > > Hi Oliver!
> > >
> > > Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> writes:
> > >
> > > > is there a way to let all other runable tasks run until they block
> > > > or return to user space, before the task wishing to do so is run
> > > > again ?
> > >
> > > Are you trying to do this in kernel or something? From userspace you
> > > can use nice(2) then sched_yield(2), though I don't know if the linux
> > > implementations will guarrantee anything.
> > >
> >
> > I recommend using usleep(0) instead of sched_yield(). Last time I
> > checked, sched_yield() seemed to spin and eat CPU cycles, usleep(0)
> > always gives up the CPU.
>
> What is wrong with this? sched_yield only yields to processes with
> lower priority (hence suggestion to use nice(2)). Does sched_yield()
> fail to yield in cases when a higher priority process wants to run?
> usleep() wastes time if no other such process is waiting, surely?
>
> [...]
Only an observation:
main()
{
nice(19);
for(;;)
sched_yield();
}
does...
^[[H^[[J^[[H^[[1m 12:45pm up 19:10, 6 users, load average: 0.66, 0.19, 0.06^[[K
31 processes: 29 sleeping, 2 running, 0 zombie, 0 stopped^[[K
CPU states: 44.1% user, 56.9% system, 99.1% nice, 0.0% idle^[[K
Mem: 320368K av, 309608K used, 10760K free, 0K shrd, 12688K buff^[[K
Swap: 0K av, 0K used, 0K free 188272K cached^[[K
^[[m\x0f^[[K
^[[7m PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND^[[K^[[m\x0f
15902 root 20 19 212 212 176 R N 0 99.1 0.0 1:05 xxx^[[K
15921 root 13 0 568 568 432 R 0 1.9 0.1 0:00 top^[[K
1 root 8 0 148 148 116 S 0 0.0 0.0 0:00 init^[[K
It consumes 99.1 percent CPU, just spinning.
However,
for(;;)
usleep(0);
Doesn't even show on `top`. Further, it gets the CPU about 100 times
a second (HZ). This is normally what you want for something that
polls, buts needs to give up the CPU so that whatever it's waiting
for can get done as soon as possible.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-05 16:52 ` Richard B. Johnson
@ 2001-04-05 20:41 ` Oliver.Neukum
2001-04-05 21:08 ` Richard B. Johnson
2001-04-05 22:29 ` Ion Badulescu
1 sibling, 1 reply; 8+ messages in thread
From: Oliver.Neukum @ 2001-04-05 20:41 UTC (permalink / raw)
To: Richard B. Johnson; +Cc: John Fremlin, Oliver Neukum, linux-kernel
> Doesn't even show on `top`. Further, it gets the CPU about 100 times
> a second (HZ). This is normally what you want for something that
> polls, buts needs to give up the CPU so that whatever it's waiting
> for can get done as soon as possible.
Hi,
first of all I want to do this in kernel.
I need to do this to prevent a race. To handle removal of a hotpluggable
scsi device. On SMP there's a race between the task blocking the scsi
device and killing obsolete requests and other tasks queueing no requests.
If a task has passed the block before it comes into effect, but the
killing task is done with killing requests before the new request can be
queued the system will oops.
Simply calling the kernel equivalent of sched_yield() is not an option as
the number of runnable tasks can be smaller than the number of CPUs in
which case sched_yield is a nop.
Regards
Oliver
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-05 20:41 ` Oliver.Neukum
@ 2001-04-05 21:08 ` Richard B. Johnson
0 siblings, 0 replies; 8+ messages in thread
From: Richard B. Johnson @ 2001-04-05 21:08 UTC (permalink / raw)
To: Oliver Neukum; +Cc: John Fremlin, linux-kernel
On Thu, 5 Apr 2001 Oliver.Neukum@lrz.uni-muenchen.de wrote:
> > Doesn't even show on `top`. Further, it gets the CPU about 100 times
> > a second (HZ). This is normally what you want for something that
> > polls, buts needs to give up the CPU so that whatever it's waiting
> > for can get done as soon as possible.
>
> Hi,
>
> first of all I want to do this in kernel.
> I need to do this to prevent a race. To handle removal of a hotpluggable
> scsi device. On SMP there's a race between the task blocking the scsi
> device and killing obsolete requests and other tasks queueing no requests.
> If a task has passed the block before it comes into effect, but the
> killing task is done with killing requests before the new request can be
> queued the system will oops.
> Simply calling the kernel equivalent of sched_yield() is not an option as
> the number of runnable tasks can be smaller than the number of CPUs in
> which case sched_yield is a nop.
>
You never mentioned doing things within the kernel. It's a lot easier
within the kernel.
cd ../linux/drivers/char
grep schedule *.c | more
This will give an idea of the many options available. In the simpist
case, you can spin-lock entry into your code, set a semaphore, then
schedule() until it changes. You have down(&semaphore) to do the
whole thing, or you can do it yourself as in serial.c:
When the last requst to the device has been
aborted, your code sets "my_semaphore" to FALSE.
You have to do in under the "my_lock" lock to
be free of all races.
spin_lock_irqsave(&my_lock, flags);
my_semaphore = FALSE;
spin_lock_irqrestore(&my_lock, flags);
driver wait-thread does:
spin_lock_irqsave(&my_lock, flags);
my_semaphore = TRUE;
spin_lock_irqrestore(&my_lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
while(my_semaphore == TRUE)
schedule();
Note that you can even schedule with the interrupts OFF, but you can't
schedule from an interrupt-service routine. There is a difference!
Even if queued requests get cleared before you even look at your
semaphore, there is no race.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: how to let all others run
2001-04-05 16:52 ` Richard B. Johnson
2001-04-05 20:41 ` Oliver.Neukum
@ 2001-04-05 22:29 ` Ion Badulescu
1 sibling, 0 replies; 8+ messages in thread
From: Ion Badulescu @ 2001-04-05 22:29 UTC (permalink / raw)
To: root; +Cc: linux-kernel
On Thu, 5 Apr 2001 12:52:28 -0400 (EDT), Richard B. Johnson <root@chaos.analogic.com> wrote:
> Only an observation:
>
>
> main()
> {
> nice(19);
> for(;;)
> sched_yield();
> }
>
> does...
>
[...]
>
> It consumes 99.1 percent CPU, just spinning.
And, umm, what *exactly* would you expect it to do? It's the only process
consuming cpu, and sched_yield() certainly doesn't yield to the idle
task. So it's basically the same as a "for(;;);" program, except it
spends more time in kernel space and schedules faster when something
else needs the cpu.
It's 100% expected behavior.
Ion
--
It is better to keep your mouth shut and be thought a fool,
than to open it and remove all doubt.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2001-04-05 22:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-04-02 14:05 how to let all others run Oliver Neukum
2001-04-04 20:11 ` John Fremlin
2001-04-04 21:00 ` Richard B. Johnson
2001-04-05 15:55 ` John Fremlin
2001-04-05 16:52 ` Richard B. Johnson
2001-04-05 20:41 ` Oliver.Neukum
2001-04-05 21:08 ` Richard B. Johnson
2001-04-05 22:29 ` Ion Badulescu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox