Re: A fix for SBCL error "thread local storage exhausted" when creating too many rules
Richard Fateman <[email protected]> Sat, 6 Jun 2026 14:58:44 -0700
| Newsgroups | gmane.comp.mathematics.maxima.general |
|---|---|
| Message-ID | <CADB8Zm60Nhre1HBndVBbexXCWB22i_D8+bC6h28ifZDcok662g@mail.gmail.com> |
Maclisp garbage collection used to collect TWAs ... truly worthless atoms. These are symbols with no binding -- just a print name. Maybe that would cure the problem? Maybe other lisps can do this? Anyway your fix seems harmless. RJF On Fri, Jun 5, 2026 at 6:58 AM 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 > _______________________________________________ Maxima-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/maxima-discuss