I need to manage a pool of threads having different priorities, so I wrote the following thread startup procedure:
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
assert(pthread_attr_init(&attr) == 0);
assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0);
assert(pthread_attr_setschedparam(&attr, ¶m) == 0);
err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd);
pthread_attr_destroy(&attr);
return err;
}
In principle the unprivileged user should not be allowed to execute this code: the pthread_create() call should return EPERM because of the security implications of running a thread with high priority.
Unexpectedly it works for the normal user, but it doesn't respect the given priority at all.
I tried to modify the code by removing the pthread_attr_t
and by setting the scheduling attribute once the thread has been created:
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine,
(void *)thrd);
if (err != 0) return err;
err = pthread_setschedparam(thrd->handler, SCHED_FIFO, ¶m);
if (err != 0) return err;
return err;
}
This approach by the way is much more difficult to manage, since in case of error I need to kill the newly created thread. At least it seems to work properly with respect to permission requirements (only root can execute this), but still priorities are not respected.
Am I doing something wrong?
EDIT
I've just added the following piece of code which is executed by every thread:
static
void getinfo ()
{
struct sched_param param;
int policy;
sched_getparam(0, ¶m);
DEBUG_FMT("Priority of this process: %d", param.sched_priority);
pthread_getschedparam(pthread_self(), &policy, ¶m);
DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d",
param.sched_priority, policy, SCHED_FIFO);
}
With the first method (namely pthread_attr_t
approach) it turns out that the pthread_attr_setschedpolicy is totally not effective, since the priority is 0 and the policy is not SCHED_FIFO.
With the second method (namely pthread_setschedparam
approach) the function prints the expected data, but the execution keeps behaving in a wrong way.