Bug 115045

Summary: pthread_attr_setschedparam/policy does not work in NPTL
Product: [Fedora] Fedora Reporter: abhijeet bisain <abisain>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED WORKSFORME QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 1CC: drepper, pratik.solanki.ml
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-09-28 10:17:56 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description abhijeet bisain 2004-02-05 20:57:49 UTC
Description of problem:
I am running Fedora core one with kernel : 
2.4.22-1.2149.nptl #1 Wed Jan 7 13:08:26 EST 2004 i686
I am using the LD_ASSUME_KERNEL env variable to switch between 
Linuxthreads and NPTL.

What I see in NPTL is that if I create a pthread_attr object, set the 
sched_policy and sched_param in it so SCHED_FIFO and priority to say 
10, and then create a thread with this attr, the thread is actually 
not created with the correct policy and priority.

I check this by calling pthread_getschedparam, and this returns 
policy=0 and priority=0. 

But when I use Linuxthreads, this works as expected.

If inside the new thread, I call pthread_setschedparam, then 
pthread_getschedparam returns the correct values, both with 
Linuxthreads and NPTL.

Version-Release number of selected component (if applicable):
glibc-2.3.2-101.4

How reproducible:
Every time

Steps to Reproduce:
1. Run the following code
Following code will reproduce the problem:

#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

#define HI_PRI 20
int who_started = -1;

int taskSpawn( int prio, void *(*start_routine)(void *)) 
{
	pthread_t spawner_id;
	pthread_attr_t spawner_attr;
	struct sched_param spawner_sched_param;
	if ( pthread_attr_init(&spawner_attr) != 0 )
	{
		perror("attr_init:");
		return -1;
	}
	if(pthread_attr_setschedpolicy( &spawner_attr, SCHED_RR) != 
0)
        {
                perror("setschedpolicy:");
                return -1;
        }
        if(pthread_attr_getschedparam(&spawner_attr, & 
spawner_sched_param) != 0)
        {
                perror("getschedparam:");
                return -1;
        }
	spawner_sched_param.sched_priority = prio;
	if(pthread_attr_setschedparam(&spawner_attr, 
&spawner_sched_param) != 0)
        {
                perror("setschedparam ");
                return -1;
        }
	if (pthread_create(&spawner_id, &spawner_attr, 
start_routine, NULL) != 0)
        {
                perror("pthread_create locker");
                return -1;
        }
	return spawner_id;
}

void * high(void *tmp)
{
	if ( who_started == -1 )
		who_started = 1;
	struct sched_param hisched_param;
	hisched_param.sched_priority = HI_PRI;
	int policy;
	if ( pthread_getschedparam(pthread_self(), &policy, 
&hisched_param) != 0 )
	{
		perror("pthreadschedparamhi:");
		return NULL;
	}
	printf("Thread's priority = %d, policy = %d\n", 
hisched_param.sched_priority, policy);
}

void * spawner(void *tmp)
{
	pthread_t hi_t, low_t;

	hi_t = taskSpawn(HI_PRI, high);
	if ( who_started == -1 )
		who_started = 3;

	if( pthread_join(hi_t, NULL) != 0 )
	{
		perror("pthreadjoin:");
	}
}

int main()
{
	pthread_t spawner_id;

	spawner_id = taskSpawn(HI_PRI + 5, spawner);
	if( pthread_join(spawner_id, NULL) != 0 )
	{
		perror("pthreadjoin:");
	}
	printf("Who started = %d\n", who_started);
}

    
  
Actual results:
Thread's priority = 0, policy = 0
Who started = 1


Expected results:
Thread's priority = 20, policy = 2
Who started = 3

Additional info:

Comment 1 Ulrich Drepper 2004-09-28 10:17:56 UTC
Your test program is buggy.  You rely on the setinheritsched flag to
be PTHREAD_EXPLICIT_SCHED by default.  This is not guaranteed, read
the standard.  It has been the case in LT, but it is not with NPTL.

If you use a recent enough glibc and add a line like

pthread_attr_setinheritsched(&spawner_attr, PTHREAD_EXPLICIT_SCHED);

You'll get the result you want.

Comment 2 Pratik Solanki 2005-02-02 18:02:34 UTC
Well in that case, at least the man page should change.

"man pthread_attr_setinheritsched" says

inheritsched
       .....
   Default value: PTHREAD_EXPLICIT_SCHED.

and "man 3p pthread_attr_setinheritsched" does not make any mention of
what the default is.

Also, can you point me to the part of the POSIX spec that says that
the default should be PTHREAD_INHERIT_SCHED. I looked and it seemed to
me that spec did not specify any default. If that is the case then why
change the default in nptl?

Comment 3 Jakub Jelinek 2005-02-06 20:00:30 UTC
The manual page states it documents LinuxThreads.


Comment 4 robert king 2005-04-13 02:43:04 UTC
I add this line,

pthread_attr_setinheritsched(&spawner_attr, PTHREAD_EXPLICIT_SCHED);

but the created thread run with the policy SCHED_OTHER!

I debug the program, it seems pthread_attr_setinheritsched does not work correct.

Am I right?