I am using barriers to synchronise my two threads which will perform task_1 and task_2 respectively.
After they are synchronised, I would like that the task with higher priority to start executing before the tasks with lower priorities.
I was surprised to notice that even though task_2 has a lower priority than task_1, sometimes task_2 starts executing before task_1.
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#define MAX_PRIORITY 99
#define MIN_PRIORITY 1
pthread_t threads[2];
pthread_barrier_t barrier;
void set_priority(int priority, int t_id){
int policy = SCHED_FIFO;
struct sched_param param;
param.sched_priority = priority;
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_setschedparam(pthread_self(), policy, ¶m);
pthread_getschedparam(pthread_self(), &policy, ¶m);
}
int set_core(int core_id) {
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
if (core_id < 0 || core_id >= num_cores)
return EINVAL;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
void create_task(int task_number, void *task) {
int rc = pthread_create(&threads[task_number - 1], NULL, task, NULL);
if(rc != 0) {
printf("pthread_create(%d) error %d\n", task_number - 1, rc);
pthread_exit(0) ;
}
}
void schedule_task(int task_number, int priority) {
set_core(2); //running tasks only in 2nd processor core
set_priority(priority, task_number);
}
void start_task_1() {
printf("Task 1 Started \n");
sleep(1); //do task 1
printf("Task 1 Endeded\n");
}
void start_task_2() {
printf("Task 2 Started \n");
sleep(1); //do task 2
printf("Task 2 Endeded\n");
}
void task_1(void *thread_param) {
schedule_task(1, MAX_PRIORITY);
pthread_barrier_wait(&barrier);
start_task_1();
pthread_exit(NULL);
}
void task_2(void *thread_param) {
schedule_task(2, MIN_PRIORITY);
pthread_barrier_wait(&barrier);
start_task_2();
pthread_exit(NULL);
}
int main() {
pthread_barrier_init(&barrier, NULL, 2);
create_task(1, task_1);
create_task(2, task_2);
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
pthread_barrier_destroy(&barrier);
}
Is that an expected behaviour in POSIX threads? What can I do to enforce that task_1 always starts before task_2?
I am executing the program as root, and I have ensured that the tasks priorities have been set accordingly.