Portable pthread_setschedparam with SCHED_OTHER

I am compiling a semi-portable Unix / Linux thread class (i.e. using the pthread library) for the project I'm working on. Part of the project requires the ability to prioritize certain threads so that other threads in the same process increase processor time; which the function enters pthread_setschedparam, and my class hits a brick wall.

The following is a simple example that I put together to illustrate my problem:

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <string.h>
#include <errno.h>

pthread_mutex_t m_mtx;
bool m_goahead;

void dosleep(int millis)
{
    usleep(millis*1000);
}

void domsg(const char *msg)
{
    pthread_mutex_lock(&m_mtx);
    std::cout << msg << std::endl;
    pthread_mutex_unlock(&m_mtx);
}

void dowait() {
    while (!m_goahead) {
        dosleep(1);
    }
}

void *fn1(void *param)
{
    domsg("in fn1...waiting");
    dowait();
    while (m_goahead) {
        dosleep(1000);
        domsg("in fn1 loop");
    }
}

void *fn2(void *param)
{
    domsg("in fn2...waiting");
    dowait();
    while (m_goahead) {
        dosleep(1000);
        domsg("in fn2 loop");
    }
}

int main(int argc, char **argv)
{
    // min prio = -2, max prio = 2
    int t1_pri = 2, t2_pri = 0, main_pri = 1;
    //SCHED_RR, SCHED_FIFO, SCHED_OTHER (POSIX scheduling policies)
    int sched = SCHED_OTHER; // standard
    // get the range between min and max and set the priorities base on split range
    int min = sched_get_priority_min(sched);
    int max = sched_get_priority_max(sched);
    int skip = (max - min) / 5; // 5 since -2...2
    struct sched_param main_param, t1_param, t2_param;
    memset(&main_param, 0, sizeof(sched_param));
    memset(&t1_param, 0, sizeof(sched_param));
    memset(&t2_param, 0, sizeof(sched_param));
    main_param.sched_priority = (min + ((main_pri+2) * (skip+1))) + (skip / 2);
    t1_param.sched_priority = (min + ((t1_pri+2) * (skip+1))) + (skip / 2);
    t2_param.sched_priority = (min + ((t2_pri+2) * (skip+1))) + (skip / 2);
    std::cout << "main thread will have a prio of " << main_param.sched_priority << std::endl;
    std::cout << "t1 thread will have a prio of " << t1_param.sched_priority << std::endl;
    std::cout << "t2 thread will have a prio of " << t2_param.sched_priority << std::endl;
    m_goahead = false;
    pthread_mutex_init(&m_mtx, NULL);
    pthread_t t1, t2;
    // Create the threads 
    if (pthread_create(&t1, NULL, fn1, NULL) != 0) {
        std::cout << "couldn't create t1" << std::endl;
        return -1;
    }
    if (pthread_create(&t2, NULL, fn2, NULL) != 0) {
        std::cout << "couldn't create t2" << std::endl;
        return -1;
    }
    dosleep(1000); // sleep a second before setting priorities
    // --main thread--
    if (pthread_setschedparam(pthread_self(), sched, &main_param) != 0) {
        std::cout << "error setting priority for main thread: (" << errno << "), " << strerror(errno) << std::endl;
    }
    // --t1 thread--
    if (pthread_setschedparam(t1, sched, &t1_param) != 0) {
        std::cout << "error setting priority for T1: (" << errno << "), " << strerror(errno) << std::endl;
    }
    // --t2 thread--
    if (pthread_setschedparam(t2, sched, &t2_param) != 0) {
        std::cout << "error setting priority for T2: (" << errno << "), " << strerror(errno) << std::endl;
    }
    m_goahead = true; // all start
    // loop until user interupt
    for (;;) {
        dosleep(1000);
        domsg("in main loop");
    }
    pthread_mutex_destroy(&m_mtx);
    return 0;
}

The basics on this code, if I compile this and run it on an OpenBSD system, I get the following:

main thread will have a prio of 24
t1 thread will have a prio of 31
t2 thread will have a prio of 17
in fn1...waiting
in fn2...waiting
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop

Notice how this happens in order of priority of the stream, fn1, main, fn2 ...

If I run the same test on an Ubuntu 10.04LTS system, I get the following:

main thread will have a prio of 3
t1 thread will have a prio of 4
t2 thread will have a prio of 2
in fn1...waiting
in fn2...waiting
error setting priority for main thread: (22), Invalid argument
error setting priority for T1: (22), Invalid argument
error setting priority for T2: (22), Invalid argument
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop
in main loop
in fn2 loop
in fn1 loop

, , SCHED_OTHER , 0; , ?

"" SCHED_FIFO SCHED_RR, min/max, min/max, " ", , (, ).

, , , SCHED_OTHER, , .

"" min/max? SCHED_OTHER ​​ ?

.

, , , /​​ .

+3
1

, . , , SCHED_OTHER - , , . BSD max min 0 99 SCHED_OTHER, , , . , , [0-0], nice ( nice, , ), .

+1

All Articles