Re: type specifier '(simple-vector n) in defmethod
Nicolas Martyanoff <[email protected]> Sat, 06 Jan 2024 15:00:56 +0100
| Newsgroups | gmane.lisp.openmcl.devel |
|---|---|
| Message-ID | <[email protected]> |
"R. Matthew Emerson" <[email protected]> writes: > What do you mean by a “userland thread based runtime”? Does that mean > that you would prefer cooperatively-scheduled / coroutine style Lisp > processes (like old MCL had)? > > Dealing with preemptively-scheduled OS threads is a pain, but > multicore processors are extremely common, and it seems important for > Lisp to be able to make use of them. CCL processes, the same was as SBCL threads, are directly mapped to OS threads. OS threads are heavy, you cannot just create millions. So to deal with concurrent IO operations (my bread and butter), you need epoll/kqueue[1] and you end up in callback hell where your entire application is a state machine where every IO operation has to be non-blocking and you have to be incredibly careful not to block the main loop (usually delegating work to a thread pool e.g. for disk operations). In CL, this really does not map well to streams because streams are fundamentally blocking (see for example the semantic of READ-SEQUENCE). I have some experimental code for non-blocking streams [2], but it is awkward to use and you have to write your parsers very carefully. This also leads to highly complex multithreaded code (interaction between IO event handling and workers), and no one is smart enough for that. The right way, as done in Erlang and more recently Go, is to use green (userland) threads mapped to multiple OS threads. Each green thread can be very lightweight (an Erlang process starts with less than 2kB of heap), start almost instantly and you can spawn millions of them. The runtime handles scheduling; usually you yield on IO operations and every N operations ("reductions" in Erlang) otherwise. This means that you can just spawn one green threads per network connection (or per concurrent operation, really), write your code the same way as if it was a non-concurrent program and communicate using CSP as in Go. In CL, this means one could use streams with the exact same semantics while the underlying concurrent runtime would handle IO events correctly. Useless to say that modifying an existing compiler to switch to this model is a huge endeavour, which is why I'm saying that if I were to try this, I would write an implementation from scratch. [1] Not just to keep memory usage low, but because an idle network connection blocks its thread potentially forever. Impossible to expose a server with this risk. [2] https://github.com/galdor/tungsten/blob/master/tungsten-system/src/tcp-stream.lisp -- Nicolas Martyanoff https://n16f.net [email protected]