tidwall / neco

Concurrency library for C (coroutines)
MIT License
1.07k stars 77 forks source link

Is it possible to support cosmopolitan? #18

Open fonghou opened 1 week ago

fonghou commented 1 week ago

Hi, thank you for the very neat library bringing C one step closer to Go :-)

Have you look into supporting cosmopolitan?

Looking at https://justine.lol/cosmopolitan/functions.html, cosmopolitan covers most of POSIX.

I changed one line in neco.c trying to compile one example.

-#elif defined(__EMSCRIPTEN__) || defined(_WIN32)
+#elif defined(__EMSCRIPTEN__) || defined(_WIN32) || defined(__COSMOCC__)

It seems only dladdr and _Unwind_Backtrace are missing to support llco

$ cosmocc -I../ ../neco.c channels.c -o channel
../neco.c: In function ‘llco_getsymbol’:
../neco.c:1352:20: warning: implicit declaration of function ‘dladdr’ [-Wimplicit-function-declaration]
 1352 |     if (sym->ip && dladdr(sym->ip, (void*)&dlinfo)) {
      |                    ^~~~~~
../neco.c: At top level:
../neco.c:3902:18: warning: not sure if modding const structs is good

 3902 | static const int ALLOWED_SIGNALS[] = {
      |                  ^~~~~~~~~~~~~~~
../neco.c:3912:18: warning: not sure if modding const structs is good

 3912 | static const int TRAPPED_SIGNALS[] = {
      |                  ^~~~~~~~~~~~~~~
cc1: note: rewrote 2 switch statements
cc1: note: modified 3 initializations
/opt/cosmocc/bin/../libexec/gcc/x86_64-linux-cosmo/12.3.0/ld.bfd: /tmp/fatcosmocc.6206z09eh66x1.o: in function `llco_getsymbol':
neco.c:(.text+0x7f9): undefined reference to `dladdr'
/opt/cosmocc/bin/../libexec/gcc/x86_64-linux-cosmo/12.3.0/ld.bfd: /tmp/fatcosmocc.6206z09eh66x1.o: in function `llco_unwind':
neco.c:(.text+0xa5e): undefined reference to `_Unwind_Backtrace'
/opt/cosmocc/bin/../libexec/gcc/x86_64-linux-cosmo/12.3.0/ld.bfd: /tmp/fatcosmocc.6206z09eh66x1.o: in function `is_main_thread':
neco.c:(.text+0x7683): undefined reference to `pthread_main_np'
collect2: error: ld returned 1 exit status
tidwall commented 1 week ago

I haven't considered cosmopolitain support, but it does seems interesting.

Have you tried adding LLCO_NOUNWIND define?

cosmocc -DLLCO_NOUNWIND -I../ ../neco.c channels.c -o channel
fonghou commented 1 week ago

Most of example/*.c work! (except portscan/echo-server/client.c SIGV :-)

❯ ./channel ;./coroutines; ./generators; ./select
ping
coroutine: A (0)
coroutine: B (0)
coroutine: C (0)
coroutine: A (1)
coroutine: B (1)
coroutine: C (1)
coroutine: A (2)
coroutine: B (2)
coroutine: C (2)
coroutine: A (3)
coroutine: B (3)
coroutine: C (3)
coroutine: A (4)
coroutine: B (4)
coroutine: C (4)
done
0
1
2
3
4
5
6
7
8
9
received one
received two

with these two #define changes.

diff --git a/neco.c b/neco.c
index 5735360..e329b77 100644
--- a/neco.c
+++ b/neco.c
@@ -2874,7 +2874,7 @@ bool worker_submit(struct worker *worker, int64_t pin, void(*work)(void *udata),
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #define NECO_POLL_EPOLL
-#elif defined(__EMSCRIPTEN__) || defined(_WIN32)
+#elif defined(__EMSCRIPTEN__) || defined(_WIN32) || defined(__COSMOCC__)
 // #warning Webassembly has no polling
 #define NECO_POLL_DISABLED
 #else
@@ -3691,7 +3691,7 @@ static int is_main_thread(void) {
 static int is_main_thread(void) {
     return getpid() == (pid_t)syscall(SYS_gettid);
 }
-#elif defined(__EMSCRIPTEN__)
+#elif defined(__EMSCRIPTEN__)  || defined(__COSMOCC__)
 int gettid(void);
 static int is_main_thread(void) {
     return getpid() == gettid();
tidwall commented 1 week ago

Wow. That's kinda amazing actually.