2001-02-03 22:54:05

by Mohit Aron

[permalink] [raw]
Subject: system call sched_yield() doesn't work on Linux 2.2

#include <stdio.h>
#include <sched.h>
#include <pthread.h>

static pthread_t thread1, thread2;


static void *thread1_func(void *arg)
{
int i;

for (i=0; i < 5 ;i++) {
printf("Thread1\n");
if (sched_yield()) printf("error in yielding\n");
}
}

static void *thread2_func(void *arg)
{
int i;

for (i=0; i < 5 ;i++) {
printf("Thread2\n");
if (sched_yield()) printf("error in yielding\n");
}
}


int main(int argc, char **argv)
{
pthread_create(&thread1, NULL, thread1_func, NULL);
pthread_create(&thread2, NULL, thread2_func, NULL);

sleep(10);

return 0;
}


Attachments:
sched_yield.c (591.00 B)

2001-02-04 11:08:59

by David Schwartz

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


The program you attached worked perfectly for me. You need to
'fflush(stdout);' after each 'printf'. You didn't expect perfect alternation
did you? That's totally unrealistic. You cannot use the scheduler as a
synchronization mechanism.

--

Thread1
Thread1
Thread2
Thread1
Thread1
Thread2
Thread1
Thread2
Thread2
Thread2

--

DS

> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]]On Behalf Of Mohit Aron
> Sent: Saturday, February 03, 2001 2:53 PM
> To: [email protected]
> Subject: system call sched_yield() doesn't work on Linux 2.2
>
>
> Hi,
> the system call sched_yield() doesn't seem to work on Linux
> 2.2. Does
> anyone know of a kernel patch that fixes this ?
>
> Attached below is a small program that uses pthreads and demonstrates that
> sched_yield() doesn't work. Basically, the program creates two
> threads that
> alternatively try to yield CPU to each other.
>
>
> - Mohit
>
>

2001-02-04 17:46:13

by Mohit Aron

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


What version of Linux are you using ? What I see is the following:
Thread1
Thread1
Thread1
Thread1
Thread1
Thread2
Thread2
Thread2
Thread2
Thread2

Also, it is NOT unrealistic to expect perfect alternation. The definition
of sched_yield in the manpage says that sched_yield() puts the thread under
question last in the run queue. So perfect alternation should have occurred.
I've also tested the code on Solaris - there is perfect alternation there.


- Mohit


-----Original Message-----
From: David Schwartz [mailto:[email protected]]
Sent: Sunday, February 04, 2001 3:09 AM
To: Mohit Aron; [email protected]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2



The program you attached worked perfectly for me. You need to
'fflush(stdout);' after each 'printf'. You didn't expect perfect alternation
did you? That's totally unrealistic. You cannot use the scheduler as a
synchronization mechanism.

--

Thread1
Thread1
Thread2
Thread1
Thread1
Thread2
Thread1
Thread2
Thread2
Thread2

--

DS

> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]]On Behalf Of Mohit Aron
> Sent: Saturday, February 03, 2001 2:53 PM
> To: [email protected]
> Subject: system call sched_yield() doesn't work on Linux 2.2
>
>
> Hi,
> the system call sched_yield() doesn't seem to work on Linux
> 2.2. Does
> anyone know of a kernel patch that fixes this ?
>
> Attached below is a small program that uses pthreads and demonstrates that
> sched_yield() doesn't work. Basically, the program creates two
> threads that
> alternatively try to yield CPU to each other.
>
>
> - Mohit
>
>

2001-02-05 00:22:38

by David Schwartz

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


> What version of Linux are you using ? What I see is the following:

I'm using 2.4.1-pre10, glibc 2.1.3.

> Thread1
> Thread1
> Thread1
> Thread1
> Thread1
> Thread2
> Thread2
> Thread2
> Thread2
> Thread2

That's totally reasonable, although you probably just forgot to fflush.

It's also possible Thread1 did all its work, yields and all, before Thread2
even got started. Thus Thread1 had no 'ready to run' thread to yield to.
(The main thread may not have been ready to run, it may still have been
waiting to synchronize to the new thread it created.)

> Also, it is NOT unrealistic to expect perfect alternation.

Find one pthreads expert who agrees with this claim. Post it to
comp.programming.threads and let the guys who created the standard laugh at
you. Scheduling is not a substitute for synchronization, ever.

> The definition
> of sched_yield in the manpage says that sched_yield() puts the
> thread under
> question last in the run queue. So perfect alternation should
> have occurred.

Your reasoning is totally invalid and ignores so many possible other
factors. For example, who says that the writes that your threads are doing
don't block?

> I've also tested the code on Solaris - there is perfect alternation there.

I'm not sure I understand what this has to do with anything. If you think
so, then I don't think you appreciate with a standard actually is. Perfect
alternation is reasonable, expecting perfect alternation is not. Probably
the reason you got perfect alternation in Solaris is because you only had
one kernel execution vehicle. Try it with system contention scope threads.

DS


2001-02-05 04:03:03

by Mohit Aron

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


> I'm using 2.4.1-pre10, glibc 2.1.3.

And I'm using Linux 2.2. And the sched_yield bug exists in Linux 2.2. I
found
a huge number of posted bug reports on linux-kernel regarding this issue.
Check http://boudicca.tux.org/hypermail/linux-kernel/2000week21/0858.html
for one.


> Thread1
> Thread1
> Thread1
> Thread1
> Thread1
> Thread2
> Thread2
> Thread2
> Thread2
> Thread2
>
> That's totally reasonable, although you probably just forgot to
fflush.

Maybe to you. Not to anyone else who knows anything about systems. FYI,
stdout
is line buffered - so a printf ending in a "\n" is an automatic flush.


> It's also possible Thread1 did all its work, yields and all, before
Thread2
> even got started. Thus Thread1 had no 'ready to run' thread to yield to.
> (The main thread may not have been ready to run, it may still have been
> waiting to synchronize to the new thread it created.)

What synchronization ? Even if thread1 started before main thread has a
chance to
create thread2, the first sched_yield would give main thread a chance to
create
thread2.


> Find one pthreads expert who agrees with this claim. Post it to
> comp.programming.threads and let the guys who created the standard laugh
at
> you. Scheduling is not a substitute for synchronization, ever.

I for one am one. And I find your statement about laughable. Try posting
your
stuff on comp.programming.threads and see if you don't get the laughter that

you're expecting is lying in wait for me. Here is simple
logic for you to figure out - if you have one run queue, and two threads
calling sched_yield() (and hence theoretically putting themselves at the end
of run queue), perfect alternation should be seen. Also, who's said I'm
trying to
synchronize based on scheduling - sched_yield() just isn't working, that's
all.


> Your reasoning is totally invalid and ignores so many possible other
>factors. For example, who says that the writes that your threads are doing
> don't block?

If the printfs are blocking, then there's even more reason that the other
thread should run. And print its stuff. Put some pressure on your brain and
it might come to you.

> I'm not sure I understand what this has to do with anything. If you
think
>so, then I don't think you appreciate with a standard actually is. Perfect
>alternation is reasonable, expecting perfect alternation is not. Probably
>the reason you got perfect alternation in Solaris is because you only had
>one kernel execution vehicle. Try it with system contention scope threads.


My Linux system is also idle. Even if one assumes that a sched_yield causes
some other process to run on the CPU, the thread that caused sched_yield is
theoretically the last on the run queue. Hence no matter what other system
process is run first, the other thread should always run before the thread
that called sched_queue. Again my point of putting some pressure on your
brain ...

Also, I won't reply any further to anything you post. If you don't
understand
systems, kindly stay out of this discussion.


- Mohit

2001-02-05 04:34:16

by Robert Guerra

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2

David,
please try to reply courteously to queries by other people. And specially
when you're the one who's wrong. Mohit is right - Linux had a
long standing problem where sched_yield() system call didn't work. It
was only fixed in Linux 2.4.

> > Also, it is NOT unrealistic to expect perfect alternation.
>
> Find one pthreads expert who agrees with this claim. Post it to
> comp.programming.threads and let the guys who created the standard
> laugh at you. Scheduling is not a substitute for synchronization, ever.

I don't claim mastery over threads. But I have been programming with threads
for a very long time and am well aware of the way OS schedulers
work. In the example that Mohit posted, it is reasonable to expect
perfect alternation once both threads have started. And it certainly isn't
something to laugh at (even if it were wrong).


- Robert Guerra




____________________________________________________________________
Get free email and a permanent address at http://www.netaddress.com/?N=1

2001-02-05 05:29:55

by Matt

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2

mohit,
to expect perfect alternation is not reasonable. the scheduler
(or one of its subsidiary and/or supporting functions) decides what
should run and what shouldn't. the linux scheduler did have problems
in 2.2 (and still does in some places). however last i checked
sched_yield() is at best a hint to the scheduler not a command. the
man page even suggests this. it says that if the process (or thread)
yields and if it is the highest priority task at the time it will be
re-run. so you can not guarantee that it will not re-run. this i think
was the point david was trying to make (albiet with some possibly
misplaced "fervour").

however i did notice one small change wrt to SCHED_YIELD
semantics from 2.2.18 and 2.4.1-ac1 (one would assume that this change
happened during the schedule() re-writes during 2.3.x).

xref line 119 of kernel/sched.c in 2.2.18

and

xref line 148 of kernel/sched.c in 2.4.1-ac1

in this case you will see that in 2.2.18 a SCHED_YIELD process will
get a "goodness" value of 0, however in 2.4.1-ac1 you will find that
it gets a value of -1 (and hence a lower scheduling priority). i dont
have a machine handy that is running 2.2.18 that i can patch and
reboot, how ever you may wish to change the return value on line 119
of kernel/sched.c in 2.2.18 to -1 and you may find that it might give
the behaviour you are looking for. it may also cause other
problems. caveat emptor and all that..

matt

2001-02-05 06:03:17

by Davide Libenzi

[permalink] [raw]
Subject: Re: system call sched_yield() doesn't work on Linux 2.2

On Sunday 04 February 2001 21:50, Matt wrote:
> in this case you will see that in 2.2.18 a SCHED_YIELD process will
> get a "goodness" value of 0, however in 2.4.1-ac1 you will find that
> it gets a value of -1 (and hence a lower scheduling priority). i dont
> have a machine handy that is running 2.2.18 that i can patch and
> reboot, how ever you may wish to change the return value on line 119
> of kernel/sched.c in 2.2.18 to -1 and you may find that it might give
> the behaviour you are looking for. it may also cause other
> problems. caveat emptor and all that..

I don't have a copy of POSIX 1003.1 (Realtime Extensions) with me now but if
I remember well this states that sched_yield() should release the CPU to
other threads with the same priority and never schedule task with lower ones.
Now, if for priority We mean static priority the current behaviour of 2.4.x
is correct, but if We mean dynamic priority the current implementation does
not respect the standard.
This coz the goodness() for that task will return -1, and this will make this
process a loser even compared to ones with lower ( dynamic ) priority.
If the POSIX standard concept of priority is nearest to the dynamic one,
probably a better solution would be a move_last_runqueue + clean_yield_flag.
Not that this will change the universe anyway ...



- Davide

2001-02-05 07:28:04

by Mohit Aron

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


Thanks for a reasonable/thoughtful reply.

> to expect perfect alternation is not reasonable. the scheduler
> (or one of its subsidiary and/or supporting functions) decides what
> should run and what shouldn't. the linux scheduler did have problems
> in 2.2 (and still does in some places). however last i checked
> sched_yield() is at best a hint to the scheduler not a command. the
> man page even suggests this. it says that if the process (or thread)
> yields and if it is the highest priority task at the time it will be
> re-run. so you can not guarantee that it will not re-run. this i think
> was the point david was trying to make (albiet with some possibly
> misplaced "fervour").

It looks like what you're saying above is that the scheduling
priority of a thread might be changed dynamically by the scheduler.
Hence, even though it called sched_yield(), its resulting priority might
still be higher than the other thread and hence there may not be
perfect alternation. This makes sense.

However, I just had a chance to run my program on a Linux 2.4 kernel.
I got almost perfect alternation every time I ran it. The output was:

Thread1
Thread1
Thread2
Thread1
Thread2
Thread1
Thread2
Thread1
Thread2
Thread2

Basically, the first thread prints twice in the beginning but after
that there's perfect alternation. This might however be because of
startup delays in Thread2.

I might add that I've tested my program on two other operating systems -
Solaris 2.7 and DUNIX V4.0D. In both I got perfect alternation every
time I ran the program. And with Linux 2.4 there was "almost" perfect
alternation.


- Mohit

2001-02-05 16:51:05

by Rik van Riel

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2

On Sun, 4 Feb 2001, Mohit Aron wrote:

> you're expecting is lying in wait for me. Here is simple logic
> for you to figure out - if you have one run queue, and two
> threads calling sched_yield() (and hence theoretically putting
> themselves at the end of run queue), perfect alternation should
> be seen.

If you really feel as strongly about this as this
email suggests, why don't you send us a patch ?

Rik
--
Linux MM bugzilla: http://linux-mm.org/bugzilla.shtml

Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...

http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com/

2001-02-05 20:03:31

by David Schwartz

[permalink] [raw]
Subject: RE: system call sched_yield() doesn't work on Linux 2.2


> David,

> please try to reply courteously to queries by other people.
> And specially
> when you're the one who's wrong. Mohit is right - Linux had a
> long standing problem where sched_yield() system call didn't work. It
> was only fixed in Linux 2.4.

Didn't work in accordance with what standard? I just checked SuSv2, and it
appears to me that a 'sched_yield' that had no user-visible affects would be
fully compliant.

> > > Also, it is NOT unrealistic to expect perfect alternation.
> >
> > Find one pthreads expert who agrees with this claim. Post it to
> > comp.programming.threads and let the guys who created the standard
> > laugh at you. Scheduling is not a substitute for synchronization, ever.
>
> I don't claim mastery over threads. But I have been programming
> with threads
> for a very long time and am well aware of the way OS schedulers
> work. In the example that Mohit posted, it is reasonable to expect
> perfect alternation once both threads have started. And it certainly isn't
> something to laugh at (even if it were wrong).

No, it is completely unreasonable to expect the scheduler to provide
perfect thread synchronization. Implementations that provide threads in user
space may easily be able to provide this, but implementations of kernel
threads will not have it so easy.

DS