Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make riscv64-unknown-elf-gcc support multi-threaded compilation #1550

Closed
TonyXinPlus opened this issue Sep 11, 2024 · 4 comments
Closed

Comments

@TonyXinPlus
Copy link

My riscv64-unknown-elf-gcc configuration is
riscv-gnu-toolchain/gcc/configure --target=rble-threads --enable-languages=c,c++ --with-pkgversion=gc891d8dc23e --with-systiscv64-unknown-elf --with-native-system-header-dir=/include --disable-libmudflaable-nls --disable-tm-clone-registry --src=.././gcc --disable-multilib --with-aec=20191213 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os
Thread model: single
Compile multithreaded C program
#include <stdio.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdlib.h>

atomic_int x = 0;
atomic_int y = 0;

void* thread1(void* arg) {
atomic_store_explicit(&x, 1, memory_order_release);
int r1 = atomic_load_explicit(&y, memory_order_acquire);
printf("T1: x = %d r1 = %d ", x, r1);
return NULL;
}

void* thread2(void* arg) {
atomic_store_explicit(&y, 1, memory_order_release);
int r2 = atomic_load_explicit(&x, memory_order_acquire);
printf(" T2: y = %d r2 = %d ", y, r2);
return NULL;
}
int main() {
int i, n=20;
pthread_t t1, t2;
for (i = 0; i < n; i++) {

  if (pthread_create(&t1, NULL, thread1, NULL)) {
                            perror("pthread_create:p0");
                            exit(1);
                    }
                    if (pthread_create(&t2, NULL, thread2, NULL)) {
                            perror("pthread_create:p1");
                            exit(1);
                    }

                    if (pthread_join(t1, NULL)) {
                            perror("pthread_join:p0");
                            exit(1);
                    }
                    if (pthread_join(t2, NULL)) {
                            perror("pthread_join:p1");
                            exit(1);
                    }
                    x = 0;
                    y = 0;
                    printf("%d\n", i);
            }
return 0;

}
error
test_mem_S-L.c: In function 'main':
test_mem_S-L.c:41:11: warning: implicit declaration of function 'pthread_create' [-Wimplicit-function-declaration]
41 | if (pthread_create(&t1, NULL, thread1, NULL)) {
| ^~~~~~~~~~~~~~
test_mem_S-L.c:50:29: warning: implicit declaration of function 'pthread_join'; did you mean 'pthread_atfork'? [-Wimplicit-function-declaration]
50 | if (pthread_join(t1, NULL)) {
| ^~~~~~~~~~~~
| pthread_atfork
/opt/riscv64/lib/gcc/riscv64-unknown-elf/13.2.0/../../../../riscv64-unknown-elf/bin/ld: /tmp/ccD3qZ6r.o: in function main': test_mem_S-L.c:(.text+0x12c): undefined reference to pthread_create'
/opt/riscv64/lib/gcc/riscv64-unknown-elf/13.2.0/../../../../riscv64-unknown-elf/bin/ld: test_mem_S-L.c:(.text+0x158): undefined reference to pthread_create' /opt/riscv64/lib/gcc/riscv64-unknown-elf/13.2.0/../../../../riscv64-unknown-elf/bin/ld: test_mem_S-L.c:(.text+0x17c): undefined reference to pthread_join'
/opt/riscv64/lib/gcc/riscv64-unknown-elf/13.2.0/../../../../riscv64-unknown-elf/bin/ld: test_mem_S-L.c:(.text+0x1a0): undefined reference to `pthread_join'

How to make riscv64-unknown-elf-gcc support multi-threaded compilation

@TommyMurphyTM1234
Copy link
Collaborator

TommyMurphyTM1234 commented Sep 11, 2024

I suspect that this still applies:

There is no RISC-V thread support in newlib yet. Thread support usually requires some kind of OS support, and no one has defined a standard way for RISC-V embedded elf systems to support threads yet.

Similarly (I suspect) for Picolibc:

I think pthread support would be provided in the particular OS environment as you say, there's lots of OS support needed for that anyways. Figuring out how this would work in a couple of specific OSes, like FreeRTOS, RIOT and Zephyr, would let us learn what picolibc would need to provide beyond its current library mutex support.

Picolibc support in riscv-gnu-toolchain is still a pending PR with no progress for a long time anyway:

So it's arguably less of a toolchain issue than something that requires specific implementation in a standard library for a particular target OS environment.

Or maybe using a particular RTOS's specific implementation of multitasking support - for example:

Can you use the Linux toolchain which has thread support?

@TonyXinPlus
Copy link
Author

Thank you for your answer. My riscv64-unknown-linux-gnu-gcc can support multi-threaded program compilation. I just want to use riscv64-unknown-elf-gcc to compile.

@TommyMurphyTM1234
Copy link
Collaborator

I just want to use riscv64-unknown-elf-gcc to compile.

In that case there's no easy way to use pthreads in a pure bare-metal context for the reasons outlined and linked to above. The only pragmatic option that I can see is to use a suitable RTOS and its specific task/thread support APIs. Otherwise you'll have to figure out a (custom) way to add pthread support to the bare metal toolchain/standard library (Newlib, Picolibc, or similar).

@TommyMurphyTM1234
Copy link
Collaborator

Closing this as I think that the issue has been explained adequately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants