I am running a multi-threaded program on my computer which has 4 cores. I am creating threads that run with SCHED_FIFO, SCHED_OTHER, and SCHED_RR priorities. What is the maximum number of each type of thread that can run simultaneously?
For example, I'm pretty sure only four SCHED_FIFO threads can run at a time (one per core) but I'm not sure about the other two.
edit my code, as asked (it's long, but most of it is for testing how long each thread completes a delay task)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
void *ThreadRunner(void *vargp);
void DisplayThreadSchdStats(void);
void delayTask(void);
int threadNumber = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
#define NUM_THREADS 9
//used to store the information of each thread
typedef struct{
pthread_t threadID;
int policy;
struct sched_param param;
long startTime;
long taskStartTime;
long endTime1;
long endTime2;
long endTime3;
long runTime;
char startDate[30];
char endDate[30];
}ThreadInfo;
ThreadInfo myThreadInfo[NUM_THREADS];
//main function
int main(void){
printf("running...\n");
int fifoPri = 60;
int rrPri = 30;
//create the 9 threads and assign their scheduling policies
for(int i=0; i<NUM_THREADS; i++){
if(i%3 == SCHED_OTHER){
myThreadInfo[i].policy = SCHED_OTHER;
myThreadInfo[i].param.sched_priority = 0;
}
else if (i%3 == SCHED_FIFO){
myThreadInfo[i].policy = SCHED_RR;
myThreadInfo[i].param.sched_priority = rrPri++;
}
else{
myThreadInfo[i].policy = SCHED_FIFO;
myThreadInfo[i].param.sched_priority = fifoPri++;
}
pthread_create( &myThreadInfo[i].threadID, NULL, ThreadRunner, &myThreadInfo[i]);
pthread_cond_wait(&cond, &mutex);
}
printf("\n\n");
//join each thread
for(int g = 0; g < NUM_THREADS; g++){
pthread_join(myThreadInfo[g].threadID, NULL);
}
//print out the stats for each thread
DisplayThreadSchdStats();
return 0;
}
//used to print out all of the threads, along with their stats
void DisplayThreadSchdStats(void){
int otherNum = 0;
long task1RR = 0;
long task2RR = 0;
long task3RR = 0;
long task1FIFO = 0;
long task2FIFO = 0;
long task3FIFO = 0;
long task1OTHER = 0;
long task2OTHER = 0;
long task3OTHER = 0;
for(int g = 0; g < threadNumber; g++){
printf("\nThread# [%d] id [0x%x] exiting...\n", g + 1, (int) myThreadInfo[g].threadID);
printf("DisplayThreadSchdStats:\n");
printf(" threadID = 0x%x \n", (int) myThreadInfo[g].threadID);
if(myThreadInfo[g].policy == 0){
printf(" policy = SHED_OTHER\n");
task1OTHER += (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2OTHER += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3OTHER += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);
otherNum++;
}
if(myThreadInfo[g].policy == 1){
printf(" policy = SHED_FIFO\n");
task1FIFO += (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2FIFO += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3FIFO += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);
}
if(myThreadInfo[g].policy == 2){
printf(" policy = SHED_RR\n");
task1RR+= (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2RR += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3RR += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);
}
printf(" priority = %d \n", myThreadInfo[g].param.sched_priority);
printf(" startTime = %s\n", myThreadInfo[g].startDate);
printf(" endTime = %s\n", myThreadInfo[g].endDate);
printf(" Task start TimeStamp in micro seconds [%ld]\n", myThreadInfo[g].taskStartTime);
printf(" Task end TimeStamp in micro seconds [%ld] Delta [%lu]us\n", myThreadInfo[g].endTime1 , (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime));
printf(" Task end Timestamp in micro seconds [%ld] Delta [%lu]us\n", myThreadInfo[g].endTime2, (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1));
printf(" Task end Timestamp in micro seconds [%ld] Delta [%lu]us\n\n\n", myThreadInfo[g].endTime3, (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2));
printf("\n\n");
}
printf("Analysis: \n");
printf(" for SCHED_OTHER, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1OTHER/otherNum), (task2OTHER/otherNum), (task3OTHER/otherNum), (task1OTHER/otherNum + task2OTHER/otherNum + task3OTHER/otherNum)/3 );
printf(" for SCHED_RR, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1RR/otherNum), (task2RR/otherNum), (task3RR/otherNum), (task1RR/otherNum + task2RR/otherNum + task3RR/otherNum)/3 );
printf(" for SCHED_FIFO, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1FIFO/otherNum), (task2FIFO/otherNum), (task3FIFO/otherNum) , (task1FIFO/otherNum + task2FIFO/otherNum + task3FIFO/otherNum)/3);
}
//the function that runs the threads
void *ThreadRunner(void *vargp){
pthread_mutex_lock(&mutex);
char date[30];
struct tm *ts;
size_t last;
time_t timestamp = time(NULL);
ts = localtime(×tamp);
last = strftime(date, 30, "%c", ts);
threadNumber++;
ThreadInfo* currentThread;
currentThread = (ThreadInfo*)vargp;
//set the start time
struct timeval tv;
gettimeofday(&tv, NULL);
long milltime0 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->startTime = milltime0;
//set the start date
strcpy(currentThread->startDate, date);
if(pthread_setschedparam(pthread_self(), currentThread->policy,(const struct sched_param *) &(currentThread->param))){
perror("pthread_setschedparam failed");
pthread_exit(NULL);
}
if(pthread_getschedparam(pthread_self(), ¤tThread->policy,(struct sched_param *) ¤tThread->param)){
perror("pthread_getschedparam failed");
pthread_exit(NULL);
}
gettimeofday(&tv, NULL);
long startTime = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->taskStartTime = startTime;
//delay task #1
delayTask();
//set the end time of task 1
gettimeofday(&tv, NULL);
long milltime1 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime1 = milltime1;
//delay task #2
delayTask();
//set the end time of task 2
gettimeofday(&tv, NULL);
long milltime2 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime2 = milltime2;
//delay task #3
delayTask();
//set the end time of task 3
gettimeofday(&tv, NULL);
long milltime3 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime3 = milltime3;
//set the end date
timestamp = time(NULL);
ts = localtime(×tamp);
last = strftime(date, 30, "%c", ts);
strcpy(currentThread->endDate, date);
//set the total run time of the thread
long runTime = milltime3 - milltime0;
currentThread->runTime = runTime;
//unlock mutex
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
pthread_exit(NULL);
}
//used to delay each thread
void delayTask(void){
for(int i = 0; i < 5000000; i++){
printf("%d", i % 2);
}
}