mbf82
mbf82

Reputation: 192

Setting scheduling policy SCHED_IDLE or SCHED_BATCH fails with EINVAL (22)

I'm trying to create threads which are unlikely to be scheduled (this is for a test case, not production code), so I wanted to create a thread with SCHED_IDLE scheduling policy.

Unfortunately this fails with EINVAL (even if running as root) on every distro/kernel version I tried.

Note that this fails when calling pthread_attr_setschedpolicy(), while usually what fails is the creation of a thread with a non-authorised scheduling policy (for instance if you try to use SCHED_RR as non-root).

This is some code to demostrate the problem:

#define _GNU_SOURCE

#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>

typedef struct
{
    const char *name;
    int value;
} policy_t;

policy_t policies[] = {
    { "SCHED_OTHER",  SCHED_OTHER },
    { "SCHED_IDLE",   SCHED_IDLE },
    { "SCHED_BATCH",  SCHED_BATCH },
    { "SCHED_FIFO",   SCHED_FIFO },
    { "SCHED_RR",     SCHED_RR },
};

int main(int argc, char *argv[])
{
    for (int i = 0; i < sizeof(policies) / sizeof(policies[0]); i++) {
        policy_t policy = policies[i];

        pthread_attr_t attr;
        pthread_attr_init(&attr);

        int e = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
        assert(e == 0);

        e = pthread_attr_setschedpolicy(&attr, policy.value);
        if (e != 0)
            printf("Cannot set sched policy %s (%d): %s (%d)\n",
                   policy.name,
                   policy.value,
                   strerror(e),
                   e);
    }

    return 0;
}

The output I get is:

Cannot set sched policy SCHED_IDLE (5): Invalid argument (22)
Cannot set sched policy SCHED_BATCH (3): Invalid argument (22)

Upvotes: 3

Views: 1908

Answers (1)

caf
caf

Reputation: 239341

The glibc code that implements pthread_attr_setschedpolicy() currently rejects the non-POSIX-defined scheduler policies.

You can set the thread's scheduler policy to SCHED_IDLE or SCHED_BATCH once it's running using pthread_setschedparam(), though. Eg. the first thing the new thread does can be to set its own scheduler policy.

Upvotes: 3

Related Questions