[Ecls-list] Special symbols that might benefit from implicit locking or thread-local bindings

Matthew Mondor mm_lists at pulsar-zone.net
Mon Aug 1 09:35:53 UTC 2011

On Mon, 1 Aug 2011 10:09:20 +0200
Juan Jose Garcia-Ripoll <juanjose.garciaripoll at googlemail.com> wrote:

> Doesn't the fact that the user may change *gensym-counter* invalidate the
> purpose of the lock? The compiler itself sets *gensym-counter* to 0, binding
> it locally so there may be no race condition there, since the symbols are
> never interned.

Hmm you may be right; in which case a user who wants process-global
(not thread-global) unique symbols might expect to himself use a lock
where required around GENSYM.  I understand that those symbols are not
interned normally, but for some algorithms it might still be needed for
those to be globally unique...

Well, I just now read http://trac.clozure.com/ccl/ticket/799 showing
that *gensym-counter* was now made global in CCL requireing user code
to lock it if necessary; yet I didn't check if GENSYM itself uses some
kind of lock for reentrancy.

As for SBCL, I checked the source and it doesn't seem to do any
thread-safe locking either in GENSYM.  So let's not worry about this
one anymore for now.  We should keep *GENSYM-COUNTER* global by default
and let threads use locks around it and/or create local bindings of it.

> This is indeed more important: what bindings should become local for a
> thread by default. Currently the list of variables that become thread-local
> is by default empty. Maybe we should at least add *package* to it? Maybe
> also create a global binding with the default list of variables so that each
> invocation of make-process uses it by default? What do you think?

The discussion above made me wonder if user code using IN-PACKAGE
and/or accessing *PACKAGE* might want to also explicitely use a lock
where needed... although I guess that *PACKAGE* is sort of a special

Another solution might be to automatically use an implicit lock
whenever a thread accesses a non-locally rebound special variable for
safety, although this would require multiple changes and would affect
performance; notably the performance of functions using a number of
parameters such as those of the printer, where most parameters are read
often yet rarely globally modified.  And if I understand, it seems that
multiple implementations also avoid such implicit locking.

So this list of special variables to automatically locally bind when
creating a new thread is probably a good compromise.

Other than *PACKAGE*, I suppose that a number of parameters might also
merit a local binding, such as those used by the printer?  There
remains the problem of deciding what to leave global and what to
rebind :)

More information about the ecl-devel mailing list