Re: A fix for SBCL error "thread local storage exhausted" when creating too many rules
David Scherfgen via Maxima-discuss <[email protected]> Sun, 7 Jun 2026 15:24:50 +0200
| Newsgroups | gmane.comp.mathematics.maxima.general |
|---|---|
| Message-ID | <CAMTHLKiX4hn3uifFwLcuJyAhrYWu96qtABMyK-9Ng4_v+LspMw@mail.gmail.com> |
Hi Michel, Thanks for looking into this and sharing your experiment! You are right about how special variables behave, but we have to make a distinction between executing rules and creating/destroying them. Because dynamically bound special variables are indeed thread-local, executing existing rules or functions in parallel is generally safe. When a thread executes a rule, the Lisp system dynamically binds those generated symbols strictly within that thread's local environment, without interfering with other threads. In fact, SBCL's mechanism of assigning a Thread-Local Storage (TLS) index to these special variables is exactly what guarantees this isolation. Regarding the new *rule-symbol-pool*, you are correct that it introduces shared state (it's not dynamically bound, it's a "global variable"). If two threads were to define or destroy rules concurrently, they would race on the pool. I could wrap the pool in a standard mutex, but the reality is that creating or destroying rules concurrently would break Maxima even without my patch. Currently, rule creation and destruction heavily mutate global state that is not shared safely between threads. For instance, defrule and tellsimp destructively modify global lists like $rules, and they write directly to symbol property lists. Similarly, concurrent modifications to the facts/assume database would inevitably corrupt the environment. There are many places like this in the codebase that currently prevent Maxima from working correctly if multiple threads are mutating the environment at the same time. So, while parallel evaluation without global side effects can work nicely as your experiment shows, parallel mutation of the environment is already unsafe, and I reckon it would be a "nightmare" to find and fix every thread-unsafe access to some global state, whether it's a global variable or some symbol property list. As for increasing the TLS limit: While adjusting the --tls-limit parameter in SBCL pushes the ceiling higher, it's ultimately only a delay of the inevitable for certain workflows. Because SBCL never reclaims a TLS slot once a symbol has been dynamically bound, a long-running Maxima session that programmatically defines and removes rules in a loop will eventually exhaust any limit we set. By recycling the symbols, we permanently cap the TLS consumption to the maximum number of rules that exist at any one time, completely eliminating the leak without restricting parallel execution of those rules. Best regards, David Michel Talon <[email protected]> schrieb am So., 7. Juni 2026, 15:04: > I am not sure that using threads in maxima is radically impossible. I have > made a small experiment that you can see here: > > > https://github.com/maxima-project-on-github/maxima-packages/tree/master/mtalon/maxima-parallel > /distribute_over_tranches_thread.lisp > <https://github.com/maxima-project-on-github/maxima-packages/blob/master/mtalon/maxima-parallel/distribute_over_tranches_thread.lisp> > > This seems to work. I have even tried with a collection of partfrac > invocations, which notoriously use the global variable var (perhaps *var* > nowadays) to communicate the main var between various functions, and it > worked OK. So probably all those special variables are in thread local > storage, and don't interfere between threads. As far as the problem of > local storage exhaustion is concerned i think it is no big deal since one > can easily increase the size of thread local storage in sbcl > > https://sourceforge.net/p/maxima/mailman/message/59161071/ > > https://sourceforge.net/p/maxima/mailman/message/59160998/ > > Personnally i have already increased tls-limit in the script "maxima" to > get rid of such problems. Of course you can solve it for maxima rules, but > it may reappear elsewhere, and the solution may cause problems to run > maxima threaded programs. > > > > Le 07/06/2026 à 11:01, David Scherfgen via Maxima-discuss a écrit : > > Hi Gunter, > > If we ever try to make Maxima thread-safe, then we need to protect the > access to *rule-symbol-pool* using a mutex. > To be honest, I doubt that'll happen, though. There's so much "global > state" in Maxima that's shared between threads. > > Best regards > David > > -- > Michel Talon > > _______________________________________________ Maxima-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/maxima-discuss