Mostly technical stuff with some interesting moments of life

Get and Set Process Affinity in C

No comments
Affinity of a process can be retrieved and set within a C program using sched_getaffinity (man page) and sched_setaffinity (man page) routines available in the sched.h. The following are two examples showing these two methods in action.

Get Process Affinity

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 

int main(int argc, char* argvi[])
{
    pid_t pid = getpid();
    cpu_set_t my_set;
    int ret;

    CPU_ZERO(&my_set);
    ret = sched_getaffinity(0, sizeof(my_set), &my_set);
    char str[80];
    strcpy(str," ");
    int count = 0;
    int j;
    for (j = 0; j < CPU_SETSIZE; ++j)
    {
        if (CPU_ISSET(j, &my_set))
        {
            ++count;
            char cpunum[3];
            sprintf(cpunum, "%d ", j);
            strcat(str, cpunum);
        }
    }
    printf("pid %d affinity has %d CPUs ... %s\n", pid, count, str);
    return 0;
}
You can test this by using taskset command in linux to set the affinity of this program and checking if the program returns the same affinity you set. For example you could do something like,
taskset -c 1,2 ./a.out
Note, you could use the non-standard CPU_COUNT(&my_set) macro routine to retrieve how many cores are assigned to this process instead of using a count variable within the loop as in the above example.

Set Process Affinity

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 

int main(int argc, char* argvi[])
{
    pid_t pid = getpid();
    cpu_set_t my_set;
    int ret;

    CPU_ZERO(&my_set);
    CPU_SET(1, &my_set);
    CPU_SET(2, &my_set);

    ret = sched_setaffinity(0, sizeof(my_set), &my_set);
    printf("pid %d \n", pid);

    // A busy loop to keep the program from terminating while
    // you use taskset to check if affinity is set as you wanted
    long x = 0;
    long i;
    while (i < LONG_MAX)
    {
        x += i;
        ++i;
    }
    printf("%ld\n",x);
    return 0;
}
The program is set to bind to cores 1 and 2 (assuming you have that many cores) using the two CPU_SET macro routines. You can check if this is set correctly using the taskset command again. The output of the program will include its process id, say pid. Use this as follows to check withtaskset.
taskset -pc pid
Note, I've included a busy loop after printing the pid of the program just so that it'll keep running while you check if affinity is set correctly.

No comments :

Post a Comment