Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to reproduce two opaque data types from the pthreads library in NASM. These data types are pthread_attr_t and cpu_set_t from pthread_attr_setaffinity_np (see http://man7.org/linux/man-pages/man3/pthread_attr_setaffinity_np.3.html).

I created a simple C program to call pthread_attr_setaffinity_np and stepped through it with gdb to examine the format of those two bitmasks (pthread_attr_t is an affinity mask).

When I debug the C version with gdb, I print the values of attr and cpus:

(gdb) p attr
$2 = {__size = '00' <repeats 17 times>, "20", '00' <repeats 37 times>, __align = 0}

(gdb) p cpus
$3 = {__bits = {1, 0 <repeats 15 times>}}

What do those two type formats translate into for assembly language?

Here is the C code:

#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* DoWork(void* args) {
    printf("ID: %lu, CPU: %d
", pthread_self(), sched_getcpu());
    return 0;
}

int main() {   

    int numberOfProcessors = sysconf(_SC_NPROCESSORS_ONLN);
    printf("Number of processors: %d
", numberOfProcessors);

    pthread_t threads[numberOfProcessors];

    pthread_attr_t attr;
    cpu_set_t cpus;
    pthread_attr_init(&attr);

    for (int i = 0; i < numberOfProcessors; i++) {
       CPU_ZERO(&cpus);
       CPU_SET(i, &cpus);
       pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus);
       pthread_create(&threads[i], &attr, DoWork, NULL);
    }

    for (int i = 0; i < numberOfProcessors; i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}

Thanks very much for any help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
191 views
Welcome To Ask or Share your Answers For Others

1 Answer

It's fairly easy to create threads in NASM using pthreads, but setting the affinity mask is another matter. It turned out to be unnecessary to reproduce the opaque types to use in assembly language, which would be very difficult.

Instead, I compiled the C program to an object file, and linked that object file with the NASM object file to produce the final executable. The main() function in C got a different name because it's not to be compiled to an .exe, and that function name is referenced with an "extern" in the NASM program. Here's the final C code:

#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

extern void * Test_fn();

int thread_create_in_C() {

    int numberOfProcessors = sysconf(_SC_NPROCESSORS_ONLN);

    if (numberOfProcessors >= 2){ // e.g. virtual cores
        numberOfProcessors = numberOfProcessors / 2; }

    printf("Number of processors: %d
", numberOfProcessors);

    pthread_t threads[numberOfProcessors];

    pthread_attr_t attr;
    cpu_set_t cpus;
    pthread_attr_init(&attr);

    for (int i = 0; i < numberOfProcessors; i++) {
       CPU_ZERO(&cpus);
       CPU_SET(i, &cpus);
       printf("Core created %d
", i);
       pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t),    &cpus);
       pthread_create(&threads[i], &attr, Test_fn, NULL);
    }

    for (int i = 0; i < numberOfProcessors; i++) {
        pthread_join(threads[i], NULL);
        printf("Core joined %d
", i);
    }

    return numberOfProcessors;
}

In the NASM code, we have an "extern thread_create_in_C" directive with the other externs, to reference the C code, and in the C code we have extern void * Test_fn(); to reference the NASM function to be called by each thread.

We call the C program at the appropriate point in the NASM program with:

call thread_create_in_C wrt ..plt

My suggestion to anyone who needs to set affinity masks for threads in assembly language is to use a C program like the one above instead of trying to replicate it in assembly. But for simple thread creation without affinity masks, the pthreads library is all you need.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...