From: Eric Wong Date: 2019-02-13T09:44:52+00:00 Subject: [ruby-core:91528] Re: Technical question on ruby Thread::Light scheduling Responding to technical bits from a private email I got regarding this topic: (original asker Bcc-ed). Note: I'm focused on another project nowadays, so I have almost no time or interest in Ruby. Maybe 2020 will be different. Non-technical questions to be answered privately. > You mention in > https://80x24.org/ruby.git/commit/?h=thread-light&id=2d5766886fc6b8575daaa79d4549c944b464eab4 > : > > Thread::Light scheduling happens at a few, well-defined points > + * only when the execution context cannot proceed (e.g. waiting > on > + * a message from a socket, pipe, Queue, or similar). > > - Given the fact that Ruby Threads are rescheduled when they block on IO, > does the above mean you have some fine-grained scheduling mechanism that > switches auto-fibers in-between Thread switching? Yes. Except auto-fibers can only switch when socket/pipe I/O cannot proceed. FS I/O blocking is not easily/portably detectable. > - Regading Mutexes, if you make them 'just' auto-fiber aware then you > should get Thread-awareness for free, right? No. I've already forgotten the exact details (but maybe my old emails/docs describe it); but I seem to recall doing deadlock checking right is difficult. So preventing auto-fiber switching inside a mutex lock seemed to be the most logical way towards predictable/safe behavior (similar to Thread.exclusive in 1.8). > - you mention you need native threads yourself to support FS access with > high-throughput/low latencies. Is this because ruby 'provides' time-slicing > sheduling ? No, not at all. It's because the ONLY way to get any sort of parallelism for most FS syscalls is to use native threads. POSIX AIO only offers functionality of read/write/fsync. Stuff like open/stat/unlink/link/rename/readdir/pread/pwrite requires native threads (or processes) for parallelism. > - In golang they have an integrated netpoller, which I wager is in line > with your idea of a single IO events 'distributor'. It relies on epoll for > linux, kqueu for bsd, iocp for windows etc. > Just mentioning in case you want to look for some inspiration: > https://golang.org/src/runtime/netpoll.go (OS-generic), > https://golang.org/src/runtime/netpoll_epoll.go, > https://golang.org/src/runtime/netpoll_kqueue.go. Maybe... but no mention of EV_ONESHOT or EPOLLONESHOT; so it looks like they'll get extra/unneeded wakeups and netpollready/netpollunblock needs to filter out duplicate events. > - Regarding fiber/coroutine/auto-fiber migration between ruby Threads, > golang has solved the problem in an elegant way: goroutine stack lives in > program heap with malloc, switching goroutines need only to save and > restore 3 registers: Program Counter, Stack Pointer and DX. Ruby seems to > be a bit stuck into "moving stacks between threads" mentality, when the > ligher abstractions should be oblivious to underlying OS threads. This > allows you to schedule the next goroutine/auto-fiber in the runq into > another unblocked thread and run it right away. Care to share some thoughts? Ruby could do this if we dropped support for C-extensions, too. But the current VM itself is like one giant C-extension, and critical parts which benefit from auto-fiber scheduling ("socket"), are, too; as are popular gems which would benefit from this feature, such as "pg" or "mysql2" Unsubscribe: