Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I include Linux header files like linux/getcpu.h?

I'm using Linux 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 GNU/Linux, and I need to #include<linux/getcpu.h>. The compiler complains that it cannot find the file. Where are the header files for linux?

like image 421
Dervin Thunk Avatar asked Apr 22 '14 16:04

Dervin Thunk


2 Answers

Short answer: usually, you don't include those headers directly.

Most OS/Machine specific headers in there are automatically included for you by a more general header. Those that are not are linux only features which may or may not be available for the version you are running.

As to getcpu, there is a more standardised version called sched_getcpu which is found in sched.h and has the same function.

Alternatively you can test wether that system call is available on your system and call it manually:

#define _GNU_SOURCE  
#include <unistd.h>
#include <sys/syscall.h>

static inline int getcpu() {
    #ifdef SYS_getcpu
    int cpu, status;
    status = syscall(SYS_getcpu, &cpu, NULL, NULL);
    return (status == -1) ? status : cpu;
    #else
    return -1; // unavailable
    #endif
}

The variable errno (#include <errno.h>) gives the error code, if syscall returns -1.

like image 129
Sergey L. Avatar answered Oct 04 '22 03:10

Sergey L.


glibc now defines getcpu() under sched.h

Tested as of Ubuntu 20.04 glibc 2.31, #include <sched.h> already defines a getcpu function via #include <bits/sched.h> with prototype:

extern int getcpu (unsigned int *, unsigned int *) __THROW;

and it seems to work fine:

getcpu.c

#define _GNU_SOURCE
#include <assert.h>
#include <sched.h> /* getcpu */
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

void* main_thread(void *arg) {
    (void)arg;
    unsigned cpu, numa;
    getcpu(&cpu, &numa);
    printf("%u %u\n", cpu, numa);
    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;
}

GitHub upstream.

Compile and run:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o getcpu.out getcpu.c -pthread
./getcpu.out 4

sample output on my 8 core laptop:

5 0
4 0
7 0
3 0

man getcpu says it can be found in #include <linux/getcpu.h> but that's just wrong for my system. A locate getcpu.h shows that he only hit is: /usr/src/linux-headers-5.4.0-29/include/linux/getcpu.h but that only defines struct getcpu_cache and nothing else.