Created
December 13, 2021 07:56
-
-
Save sutyum/430ab9f7ff3cb6f4bf85344e0910c739 to your computer and use it in GitHub Desktop.
Use FIFO scheduling policy and Core affinity in linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <pthread.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <sched.h> | |
#include <sys/sysinfo.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <syslog.h> | |
#define NUM_OF_THREADS 128 | |
#define SCHED_POLICY SCHED_FIFO | |
typedef struct | |
{ | |
int threadIdx; | |
} threadParams_t; | |
struct sched_param fifo_param; | |
pthread_attr_t fifo_sched_attr; | |
// POSIX thread declarations and scheduling attributes | |
// | |
pthread_t threads[NUM_OF_THREADS]; | |
threadParams_t threadParams[NUM_OF_THREADS]; | |
void print_scheduler(void) | |
{ | |
int schedType = sched_getscheduler(getpid()); | |
switch(schedType) | |
{ | |
case SCHED_FIFO: | |
printf("SCHED_FIFO\n"); | |
break; | |
case SCHED_OTHER: | |
printf("SCHED_OTHER\n"); | |
break; | |
case SCHED_RR: | |
printf("SCHED_RR\n"); | |
break; | |
default: | |
printf("UNKNOWN\n"); | |
} | |
} | |
void set_scheduler(int procno, int prio) | |
{ | |
int scope, rc, cpuidx; | |
cpu_set_t cpuset; | |
printf("INITIAL "); print_scheduler(); | |
//SCHED_POLICY is set to SCHED_FIFO | |
pthread_attr_init(&fifo_sched_attr); | |
pthread_attr_setinheritsched(&fifo_sched_attr, PTHREAD_EXPLICIT_SCHED); | |
pthread_attr_setschedpolicy(&fifo_sched_attr, SCHED_POLICY); | |
//zero out the set o CPU cores | |
CPU_ZERO(&cpuset); | |
//Here we assign the threads to run ONLY on single core | |
cpuidx=procno; | |
CPU_SET(cpuidx, &cpuset); | |
pthread_attr_setaffinity_np(&fifo_sched_attr, sizeof(cpu_set_t), &cpuset); | |
//Set priority according to function parameter | |
fifo_param.sched_priority=prio; | |
if ((rc=sched_setscheduler(getpid(), SCHED_POLICY, &fifo_param)) < 0) | |
perror("sched_setscheduler"); | |
pthread_attr_setschedparam(&fifo_sched_attr, &fifo_param); | |
printf("ADJUSTED "); print_scheduler(); | |
} | |
void *Thread(void *threadp) | |
{ | |
threadParams_t *threadParams = (threadParams_t *)threadp; | |
int gsum = 0; //Local variable (for every task) | |
char str[100]; //Memory allocation for string | |
for(int i=0; i<=threadParams->threadIdx; i++) //Calculate sum from 0 to the n, where n is the task number | |
gsum=gsum+i; | |
sprintf(str, "Thread idx=%d, sum[1..%d]=%d Running on core:%d\n", threadParams->threadIdx, threadParams->threadIdx, gsum, sched_getcpu()); //Fill the string with calculated data | |
syslog(LOG_INFO, str); //Log the data | |
} | |
int main (int argc, char *argv[]) | |
{ | |
volatile int i=0; | |
openlog("[COURSE:1][ASSIGNMENT:3]:", LOG_NOWAIT, LOG_SYSLOG); //Open logger file | |
system("uname -a | logger -t '[COURSE:1][ASSIGNMENT:3]:'"); //Use system function for OS details and stream it to logger | |
for(i=0; i < NUM_OF_THREADS; i++) | |
{ | |
set_scheduler(1, 99-i); //Set scheduler to FIFO runing on core 1 with priority from 99 to 0 | |
threadParams[i].threadIdx=i; //Set thread identification number | |
pthread_create(&threads[i], //Pointer to thread descriptor | |
&fifo_sched_attr, //Use default attributes | |
Thread, //Thread function entry point | |
(void *)&(threadParams[i]) //Parameters to pass in | |
); | |
} | |
for(i=0; i < NUM_OF_THREADS; i++) | |
pthread_join(threads[i], NULL); | |
printf("TEST COMPLETE\n"); | |
} | |
/* --=== COMMENTS ON THE OUTPUT DATA ===-- | |
* | |
* Below please find few lines from the syslog file | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173145]: Linux diodetetor 5.15.5-arch1-1 #1 SMP PREEMPT Thu, 25 Nov 2021 22:09:33 +0000 x86_64 GNU/Linux | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=0, sum[1..0]=0 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=1, sum[1..1]=1 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=2, sum[1..2]=3 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=3, sum[1..3]=6 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=4, sum[1..4]=10 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=5, sum[1..5]=15 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=6, sum[1..6]=21 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=7, sum[1..7]=28 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=8, sum[1..8]=36 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=9, sum[1..9]=45 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=10, sum[1..10]=55 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=11, sum[1..11]=66 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=12, sum[1..12]=78 Running on core:1 | |
* gru 11 12:35:21 diodetetor [COURSE:1][ASSIGNMENT:3]:[173142]: Thread idx=13, sum[1..13]=91 Running on core:1 | |
* | |
* As we can see, the tasks are in the same order as the creation sequence. This is because | |
* of assymetric fifo schedduler SCHED_FIFO and proper priority settings. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment