Most recent kernel where this bug did not occur: n/a Distribution: n/a Hardware Environment: x86 and others Software Environment: n/a Problem Description: According to POSIX.1, the process nice value (as set by setpriority(), http://www.opengroup.org/onlinepubs/009695399/functions/getpriority.html ) is a process-wide attribute (at least for System Contention Scope threads, which is the kind of thread model used on Linux). However, on Linux it is a per-thread attribute. This is a violation of POSIX.1,and should be remedied. Steps to reproduce: The following program can be used to demonstrate that the nice value is not shared by the threads of a process: /* thread_share_nice.c */ #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/resource.h> #include <limits.h> #include <string.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #define errExit(msg) { perror(msg); exit(EXIT_FAILURE); } #define errExitEN(en, msg) { errno = en; perror(msg); \ exit(EXIT_FAILURE); } #define fatalExit(msg) { fprintf(stderr, "%s\n", msg); \ exit(EXIT_FAILURE); } #define NEW_NICE 1 /* Must not be non-negative */ static void * tf1_nice(void *x) { int nval; errno = 0; nval = getpriority(PRIO_PROCESS, 0); if (nval == -1 && errno != 0) errExit("getpriority"); printf("Thread 1: initial nice value is %d\n", nval); if (setpriority(PRIO_PROCESS, 0, NEW_NICE) == -1) errExit("setpriority"); errno = 0; nval = getpriority(PRIO_PROCESS, 0); if (nval == -1 && errno != 0) errExit("getpriority"); printf("Thread 1: nice value is %d\n", nval); printf("Thread 1 terminating\n"); return NULL; } static void * tf2_nice(void *x) { int nval; errno = 0; nval = getpriority(PRIO_PROCESS, 0); if (nval == -1 && errno != 0) errExit("getpriority"); printf("Thread 2: nice value is %d\n", nval); printf("nice value %s shared\n", (nval == NEW_NICE) ? "is" : "**IS NOT**"); return NULL; } int main(int argc, char *argv[]) { pthread_t t1, t2; void *res; int s; system("uname -a; date"); printf("-------- nice value test --------\n"); s = pthread_create(&t1, NULL, tf1_nice, (void *) 1); if (s != 0) errExitEN(s, "pthread_create"); s = pthread_join(t1, &res); if (s != 0) errExitEN(s, "pthread_join"); printf("About to create thread 2\n"); s = pthread_create(&t2, NULL, tf2_nice, (void *) 2); if (s != 0) errExitEN(s, "pthread_create"); s = pthread_join(t2, &res); if (s != 0) errExitEN(s, "pthread_join"); exit(EXIT_SUCCESS); } /* main */
(CC'ing Ingo Molnar, who might have an answer)
CCing Ulrich Drepper, who may have an answer
Glibc issue There are very good kernel reasons to do per thread priority, remember POXIX threads are crippled at the spec level to make them implementable in user space on cruddy old systems. The C library should enforce any POSIXism here, perhaps with kernel help as a special option.
Alan, could you please give me some pointers to the "very good kernel reasons to do per thread priority"? I may ad a line or two to the pthreads.7 man page.