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 11:01:13 +0200
| Newsgroups | gmane.comp.mathematics.maxima.general |
|---|---|
| Message-ID | <CAMTHLKj3qdDGakbEHsWCQ6yABrn-oPdX0gU3RSPo0fVfZLwEYA@mail.gmail.com> |
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 Am So., 7. Juni 2026 um 10:56 Uhr schrieb Gunter K�nigsmann < [email protected]>: > My only question would be: if we ever introduce multi-threaded work... ... > as far as I understand stuff stored in thread-local memory won't be shared > between threads so each thread could make its own assumptions without > having to fea race conditions. > > Didn't look closely enough at the new code to see if the new code would > allow that, as well. > > Having said that I hate running out of thread-local memory as it normally > is a clear game over situation. > > Kind regards, > > Gunter. > > > On 5 June 2026 15:57:21 CEST, David Scherfgen via Maxima-discuss < > [email protected]> wrote: > >> Hi everyone, >> >> I've been looking into the annoying bug #4517 >> <https://sourceforge.net/p/maxima/bugs/4517/>, where Maxima crashes on >> SBCL due to Thread-Local Storage (TLS) exhaustion after repeatedly >> generating and destroying rules (via defrule, tellsimp, etc.). It >> famously can be triggered by running the rtest_rules test a few times. >> >> The root cause is that the pattern-matching compiler dynamically binds >> new symbols generated during rule creation. On SBCL, every newly >> dynamically bound special variable permanently consumes a TLS slot. Even if >> the rule is subsequently removed, SBCL cannot free the underlying TLS >> index, eventually causing a hard crash once the limit is reached. >> >> To resolve this, I've implemented a reusable symbol pool ( >> *rule-symbol-pool*). The patch modifies matcom.lisp to track all symbols >> generated for a specific rule via its property list. When a rule is >> overwritten, or when it is destroyed via kill1-atom in suprv1.lisp, >> those symbols are completely scrubbed (makunbound, fmakunbound, and >> property list cleared) and pushed back into the pool for the next rule to >> recycle. Now, the TLS consumption strictly depends on the rules that exist >> at the same time, rather than all rules ever created over the lifetime of >> the session. >> >> I'd love to get some feedback on this approach, and I have a specific >> question for the veterans regarding the historical design: In my patch, I >> replaced the tr-gensym call in genref with the new pool allocator ( >> get-rule-symbol). Does anyone recall the original rationale for using >> tr-gensym (which interns the symbol) in genref instead of a standard >> uninterned gensym, as it is the case in other places in the relevant >> code? I want to ensure I'm not breaking a subtle dependency with the >> translator. >> >> Note: A visible side effect of this change is that these match variables >> will now be named RULE-SYMBOL-... rather than TR-GENSYM~... in >> macro-expanded code. >> >> Best regards >> David Scherfgen >> > _______________________________________________ Maxima-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/maxima-discuss