Last active
January 18, 2024 08:39
-
-
Save j4cobgarby/b6e9eb7ffbe4b3d9288c147e3de31c0c to your computer and use it in GitHub Desktop.
A simple C program to test thread pinning
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
/* pintest.c | |
* Runs n threads, pinned to the first n CPUs, until you press enter. | |
* n is specified as a command line argument. | |
* Each thread runs an infinite loop (100% cpu usage in theory). | |
*/ | |
#define _GNU_SOURCE | |
#include <pthread.h> | |
#include <sched.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
void *func(void *arg __attribute__((unused))) | |
{ | |
for (;;) | |
; | |
} | |
int pin_thread(pthread_t thr, int core) | |
{ | |
cpu_set_t cpuset; | |
CPU_ZERO(&cpuset); | |
CPU_SET(core, &cpuset); | |
return pthread_setaffinity_np(thr, sizeof(cpu_set_t), &cpuset); | |
} | |
int main(int argc, char **argv) | |
{ | |
int n_threads, n_cores_total; | |
pthread_t *thread_ids; | |
if (argc != 2) | |
{ | |
printf("Usage: %s [n threads]\n", argv[0]); | |
return EXIT_FAILURE; | |
} | |
n_threads = atoi(argv[1]); | |
n_cores_total = sysconf(_SC_NPROCESSORS_ONLN); | |
printf("n_threads = %d\nn_cpus = %d\n", n_threads, n_cores_total); | |
if (n_threads > n_cores_total) | |
{ | |
printf("n_threads > n_cores, quitting...\n"); | |
return EXIT_FAILURE; | |
} | |
else if (n_threads <= 0) | |
{ | |
printf("n_threads < 1, quitting...\n"); | |
return EXIT_FAILURE; | |
} | |
thread_ids = malloc(sizeof(pthread_t) * n_threads); | |
if (!thread_ids) | |
{ | |
printf("Couldn't allocate memory for thread array."); | |
return EXIT_FAILURE; | |
} | |
for (int i = 0; i < n_threads; i++) | |
{ | |
if (pthread_create(&thread_ids[i], NULL, func, NULL) != 0) | |
{ | |
printf("Failed to create thread %d.\n", i); | |
goto error; | |
} | |
if (pin_thread(thread_ids[i], i) != 0) | |
{ | |
printf("Failed to pin thread %d.\n", i); | |
goto error; | |
} | |
} | |
printf("Threads are running. Press ENTER to stop.\n"); | |
getchar(); | |
for (int i = 0; i < n_threads; i++) | |
{ | |
if (pthread_cancel(thread_ids[i]) != 0) | |
{ | |
printf("Failed to cancel thread %d. Skipping...\n", i); | |
} | |
} | |
free(thread_ids); | |
return EXIT_SUCCESS; | |
error: | |
free(thread_ids); | |
return EXIT_FAILURE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment