Open borkdude opened 1 year ago
@jart I think this can be implmented on BSD and macOS using kqueue, right? As for Windows I don't really know.
It can probably be implemented on other platforms using just poll() if necessary. I've implemented epoll() support for just Linux for now. I was hoping it'd be enough to run NodeJS hello world but alas it also wants eventfd.
I wanted to try it out but I'm getting:
blink/checked.h: In function ‘CheckedAdd’:
blink/checked.h:18:45: error: missing binary operator before token "("
18 | (defined(__has_builtin) && __has_builtin(__builtin_add_overflow))
| ^
blink/checked.h: In function ‘CheckedSub’:
blink/checked.h:39:45: error: missing binary operator before token "("
39 | (defined(__has_builtin) && __has_builtin(__builtin_sub_overflow))
| ^
blink/checked.h: In function ‘CheckedMul’:
blink/checked.h:60:45: error: missing binary operator before token "("
60 | (defined(__has_builtin) && __has_builtin(__builtin_mul_overflow))
| ^
make: *** [build/rules.mk:18: o//blink/checked.h.ok] Error 1
make: *** Waiting for unfinished jobs....
Could you try syncing to head and let me know if that fixes things?
That fixed that error. I'm trying to build on a linux aarch64 fresh ubuntu install. I installed make and gcc.
Now I'm getting:
/usr/bin/ld: /blink/blink/ssefloat.c:281: undefined reference to `sqrt'
Should I tweak some compile flags and what's the best way to do that?
Sorry for the noob questions, I don't normally work a lot with C tooling.
Blink builds fine for me on Raspberry Pi if I run:
./configure
make
If sqrt
can't be found, then maybe check less config.log
and see if -lm
is being detected.
@jart I was able to run it like this on an aarch64 mac + docker:
FROM ubuntu
RUN apt-get update
RUN apt-get -y install gcc git make sudo curl
RUN git clone https://github.com/jart/blink
WORKDIR blink
RUN ./configure
RUN make -j4
RUN sudo make install
RUN curl -sLO https://github.com/babashka/babashka/releases/download/v1.2.174/babashka-1.2.174-linux-amd64.tar.gz
RUN tar xzvf babashka-1.2.174-linux-amd64.tar.gz
RUN blink bb
docker build -t blink .
What I'm getting currently is:
#13 0.228 /lib64/ld-linux-x86-64.so.2: failed to load interpreter (errno 2)
The current epoll support seems to not be aware of vfs file descriptors and so chooses overlapping ranges for epoll_ctl fds:
$ cat test.c
#include <stdio.h>
#include <sys/epoll.h>
#include <unistd.h>
int main() {
int i;
for (i = 0; i < 3; i++) {
printf("ep - %u\n", epoll_create(1));
}
for (i = 0; i < 3; i++) {
int pfds[2];
pipe(pfds);
printf("pipe - %u %u\n", pfds[0], pfds[1]);
}
return 0;
}
aidanhs@a-winthinkpad:~$ gcc test.c && ./blink/o/blink/blink -m -j -C ubuntu-22.04 ./a.out
ep - 3
ep - 4
ep - 5
pipe - 3 4
pipe - 5 6
pipe - 7 8
I believe (though haven't double checked with a test program) that because it also doesn't do translation from vfs fds to real fds, that epoll_ctl also doesn't work to add file descriptors.
@borkdude The bb
executable is dynamic. It depends on things like Glibc being provided by the system. Possibly try downloading something like https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/x86_64/alpine-minirootfs-3.17.2-x86_64.tar.gz and using that directory as your chroot using the blink -C alpine-minirootfs-3.17.2-x86_64
flag. You would need to compile Blink using ./configure --enable-vfs
. The thing I actually recommend doing though, is try to get a statically compiled build of babashka. Then you don't need to worry about the Linux userspace when running your binaries on MacOS.
The VFS subsystem was created on a fork before blink
adds syscall passthrough support for epoll
on Linux.
This can be fixed by simply hooking all epoll
family syscalls and translate all input/output fds.
With --enable-vfs
, we can also look at supporting this on platforms other than Linux, as we fully manage all file descriptors. However, to truly implement epoll
we have to solve #92, as epoll
objects are kernel objects that may be shared between processes through fork
.
It might be possible to implement epoll
without a dedicated kernel daemon using a dedicated temporary folder instead.
When an epoll
fd is created, a temporary file can be opened in a directory hidden to all other blink
VFS functions. When the state attached to this epoll
fd is read or modified, the file can be mapped into memory using mmap
, and then a spinlock can be acquired.
The same probably applies to eventfd.
See discussion here.