diff --git a/README.adoc b/README.adoc index 56fee0b..0e9cae0 100644 --- a/README.adoc +++ b/README.adoc @@ -17294,6 +17294,17 @@ The best article to understand spinlocks is: https://eli.thegreenplace.net/2018/ The example in `man futex` is also a must. +[[getcpu]] +==== `getcpu` system call and the `sched_getaffinity` glibc wrapper + +Example: link:userland/linux/sched_getcpu.c[] + +Returns the CPU that the process/thread is currently running on: https://stackoverflow.com/questions/491520/how-can-i-get-the-cpu-core-number-from-within-a-user-space-app-linux-c + +So when running a multicore program, we may see that each thread can be running on a different core. + +The cores in which the process runs can be fixed with `sched_setaffinity` as shown at: link:userland/linux/sched_getaffinity.c[]. + === Linux calling conventions A summary of results is shown at: xref:table-linux-calling-conventions[xrefstyle=full]. diff --git a/path_properties.py b/path_properties.py index 5521f88..f34de8e 100644 --- a/path_properties.py +++ b/path_properties.py @@ -750,6 +750,7 @@ path_properties_tuples = ( 'more_than_1s': True, 'requires_syscall_getcpu': True, }, + 'sched_getcpu.c': {'requires_syscall_getcpu': True}, 'time_boot.c': {'requires_sudo': True}, 'virt_to_phys_user.c': {'requires_argument': True}, } diff --git a/userland/linux/sched_getcpu.c b/userland/linux/sched_getcpu.c new file mode 100644 index 0000000..294a1b3 --- /dev/null +++ b/userland/linux/sched_getcpu.c @@ -0,0 +1,41 @@ +/* https://cirosantilli.com/linux-kernel-module-cheat#getcpu */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +void* main_thread(void *arg) { + (void)arg; + printf("sched_getcpu = %d\n", sched_getcpu()); + return NULL; +} + +int main(int argc, char **argv) { + pthread_t *threads; + unsigned int nthreads, i; + if (argc > 1) { + nthreads = strtoll(argv[1], NULL, 0); + } else { + nthreads = 1; + } + threads = malloc(nthreads * sizeof(*threads)); + for (i = 0; i < nthreads; ++i) { + assert(pthread_create( + &threads[i], + NULL, + main_thread, + NULL + ) == 0); + } + for (i = 0; i < nthreads; ++i) { + pthread_join(threads[i], NULL); + } + free(threads); + return EXIT_SUCCESS; +}