The POSIX.1-2001 specification of pthread_attr_init() says: The pthread_attr_init() function shall initialize a thread attributes object attr with the default value for all of the individual attributes used by a given implementation. Among other things, pthread_attr_init() (quite reasonably) initializes the scheduling policy to SCHED_OTHER, and the scheduling priority to 0. The POSIX.1-2001 specification of pthread_attr_setinheritsched() says: PTHREAD_INHERIT_SCHED Specifies that the thread scheduling attributes shall be inherited from the creating thread, and the scheduling attributes in this attr argument shall be ignored. PTHREAD_EXPLICIT_SCHED Specifies that the thread scheduling attributes shall be set to the corresponding values from this attributes object. Thus, as I read the standard, if we initialize a thread attribute object to the defaults (using pthread_attr_init()), and then set the inheritsched attribute to PTHREAD_EXPLICIT_SCHED, then a new thread created using this attribute object should have its scheduling policy and priority set to SCHED_OTHER and 0, respectively. However, instead, these values are taken from the calling thread (i.e., as though the inheritsched attribute had been set to PTHREAD_INHERIT_SCHED). As far as I can see this is in violation of the specification and should be changed.
Created attachment 3042 [details] test program The attached test program can be used to demonstrate the reported behavior using the following command: $ sudo ./pthreads_sched_test -mf10 -i e root's password: Scheduler settings of main thread policy=SCHED_FIFO, priority=10 Scheduler settings in 'attr' policy=SCHED_OTHER, priority=0 inheritsched is EXPLICIT About to call pthread_create() with attrp=0xbfeacb54 Scheduler attributes of new thread policy=SCHED_FIFO, priority=10
POSIX is wonderfully vague in this area. While pthread_attr_init() is definite about the result being the defaults for all attributes, it is silent on what happens when any one of the connected scheduling attributes -- inheritance, scope, policy and params -- are changed. Amongst the difficulties: (1) if the default is PTHREAD_INHERIT_SCHED, what are the scope, policy and params set to ? They obviously cannot reflect what a thread is going to receive. They could (sensibly) be the defaults if PTHREAD_EXPLICIT_SCHED were then to be set. But POSIX doesn't quite say that. IMO, it would make life easier if the default were to be specified to be PTHREAD_EXPLICIT_SCHED -- but it isn't. (2) one would hope that after setting PTHREAD_EXPLICIT_SCHED the scope, policy and params would then be the defaults... but POSIX doesn't say. If those attributes are initialised that way, then the semantics are straightforward. If not, then there's an issue if any of those attributes are set before PTHREAD_EXPLICIT_SCHED is. In any case, POSIX leaves it open for some implementation to require the scope, policy and params to be set explicitly if PTHREAD_EXPLICIT_SCHED is set. (3) where there is a choice between PTHREAD_SCOPE_SYSTEM and PTHREAD_SCOPE_PROCESS, POSIX is silent on what happens when the scope is changed. If the the default policy and params were to be different for different scopes (and POSIX neither allows nor disallows this), should changing the scope change the "defaults" ? (Not many systems seem to support more than one scope, but that doesn't change the basic problem.) (4) POSIX specifies that the params are at a minimum the sched_priority -- though it does not specify a meaning for that for SCHED_OTHER. It is clearly allowing for there to be additional, implementation-defined param fields. When setting SCHED_XXX policy, are the params then set to defaults for that policy ? If not, then the application needs to have perfect knowledge of the local system if it is to set any policy other than the default. I have an application where PTHREAD_SCOPE_SYSTEM is the obvious choice... but given the ambiguities, I have struggled to find a POSIX-safe way to do this. In the end I have simply assumed that the policy and params used by the main thread will be suitable for PTHREAD_SCOPE_SYSTEM, so I can set PTHREAD_EXPLICIT_SCHED, and then all of scope, policy and params to unambiguous values. Which has the happy side effect of avoiding this particular "bug". Anyway... my point is that this whole area is a steaming pit of poorly defined icky-ness, and I suggest it would be no bad thing if glibc took a lead on sorting out. For my money, I would go with: * disallowing PTHREAD_INHERIT_SCHED as a default. * defining the setting of scope to, as a side effect, set the system default policy and params for that scope... * defining the setting of policy to, as a side effect, set the system default params for that policy... * ... or a new function which sets scope, policy and params all in one got, and invent PTHREAD_SCOPE_DEFAULT and SCHED_DEFAULT, so that (by using NULL to mean default params) an application can unambiguously set as much scheduling attributes as it wishes, allowing for many things to be implementation defined, without requiring the application to have perfect knowledge. Chris