Bug 6258 - nice value should be process-wide, not per-thread
Summary: nice value should be process-wide, not per-thread
Status: REJECTED WILL_NOT_FIX
Alias: None
Product: Process Management
Classification: Unclassified
Component: Other (show other bugs)
Hardware: i386 Linux
: P2 normal
Assignee: process_other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-20 19:20 UTC by Michael Kerrisk
Modified: 2007-09-27 09:58 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.16
Subsystem:
Regression: ---
Bisected commit-id:


Attachments

Description Michael Kerrisk 2006-03-20 19:20:30 UTC
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 */
Comment 1 Diego Calleja 2006-05-08 13:43:43 UTC
(CC'ing Ingo Molnar, who might have an answer)
Comment 2 Michael Kerrisk 2006-09-17 00:22:18 UTC
CCing Ulrich Drepper, who may have an answer
Comment 3 Alan 2007-09-27 05:51:24 UTC
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.
Comment 4 Michael Kerrisk 2007-09-27 09:58:58 UTC
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.

Note You need to log in before you can comment on or make changes to this bug.