The local_storage member of execution context is lazy initialized and drives the Thread#[] and Thread#[]= APIs, which are Fiber local and not Thread local storage. I think the same lazy init pattern should be applied to the APIs below as well - reduces one Hash alloc per thread created that does not use thread locals.
Lazy allocates thread local storage for the following APIs¶
Thread#thread_variable_get - early returns nil on locals Hash not initialised
Thread#thread_variable_set - forces allocation of the locals Hash if not initilalised
Thread#thread_variables - early returns the empty array AND saves on Hash iteration if locals Hash not initialised
Thread#thread_variable? - early returns false on locals Hash not initialised
Moved initial implementation from internal.h to thread.c local to call sites.
Preferred defs/id.def for the locals ID (seeing this pattern used more often, but not sure if that is preferred to inline rb_intern yet. Either way there's quite a few different conventions around IDs in the codebase at the moment and happy to help converging to a standard instead.
Maybe a flag is overkill and NIL_P on locals ivar could also work ...
I'm positive about this, except for the performance.
Do you have any numbers?
Apologies for the delay in replying.
Using benchmark-driver script (running set last as it would taint the others by initializing the locals table on the thread object initialized in prelude):