5

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?

5
  • 1
    Are you writing a kernel module? Commented Apr 22, 2014 at 16:08
  • First check they are actually installed on your system (package linux-header*) Commented Apr 22, 2014 at 16:08
  • @n.m. No, I need the getcpu() function at user level. Commented Apr 22, 2014 at 16:09
  • Normally you don't really need it, you can pass NULL as the third parameter (and you should, if you want up-to-date uncached answer). Commented Apr 22, 2014 at 16:14
  • BTW it's usually in /usr/src/linux/include/linux/getcpu.h (if you have linux-header* installed on your system). Commented Apr 22, 2014 at 16:16

2 Answers 2

12

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.