Scoped variables
David Lloyd
david.lloyd at redhat.com
Tue Dec 4 22:56:05 UTC 2018
They would, I presume, be largely similar in form and function to what
you get if you create a _Thread_local static variable in C11. This is
complicated somewhat by the fact of multiple classes/class loaders
(this is akin to the DSO problem on UNIX-like systems) and the fact of
lazy class loading (meaning it's generally not practical to simply
allocate all your thread locals up front).
As for implementation specifics - I would say that the simplest
approach (with existing technology) would be an array of objects on
Thread, where the indexes are (as you suggested) allocated and freed
based on the introduction and eventual GC of the corresponding class
loaders and the object is some blob of memory holding the actual
values at predictable offsets. So a lookup would be something like:
currentThread().threadLocals[idx].actualThreadLocal, which looks like
maybe three or four memory loads to my untrained eye, compared the
(presumably) single memory load for fields-on-thread. The "blob"
object could be a regular Java object corresponding to the set of
static thread locals for each class. But it's probably possible to do
a little better than that with the help of the JVM; for example if you
could derive the address of the array from the thread ID, or better
yet if you could derive the address of the actual thread local storage
area based on both thread ID *and* class[loader] (skipping an array
altogether), you could probably cut out one or two loads and get close
to field-on-thread-like performance, give or take the cost of probably
worse memory locality in this case (TLB as well as cache misses,
probably) compared to having all those fields nestled together on
Thread.
Putting the array on the thread (instead of having an array containing
values for each thread) means (in addition to avoiding false sharing
problems) that if the array must grow, it can do so without any
contention or interference from other threads (barring GC events that
might arise from growing the array itself).
Regardless of the details of implementation, this kind of static
thread local, by virtue of its relative efficiency, can be used to
pass invisible parameters in the obvious manner, but also can be used
to support various lexically scoped constructs simply by setting and
replacing values on a lexical basis:
// lifted syntax for C11 for illustration
static _Thread_local Thing threadLocal;
// [...]
public void doWithNewThing(Runnable action) {
Thing oldVal = threadLocal;
threadLocal = new Thing();
try {
action.run();
} finally {
threadLocal = oldVal;
}
}
Also if you pass oldVal to Thing's constructor, you can have a cheap
singly linked list which can be a performant alternative to stack
walking in many cases. This technique was part of the basis of my
pure-Java access controller prototype.
Beyond that, anything that can be done with a field on Thread can be
done with static thread locals (albeit at a slight increase in cost,
though still substantially less than that of ThreadLocal).
Per-instance thread locals in the vein of today's ThreadLocal (in the
non-static case) could be implemented via map or weak-map of instance
to value within a static, at a similar cost to what ThreadLocal has
today. A task-local object with fields representing the
task-local-scoped items could be stashed in a single static thread
local, allowing rapid switching between task contexts. A static
thread local could be used to store a pointer to a previous stack
frame or to an object allocated therein which could be dereferenced to
access stack-scoped variables. It's hard to imagine a better (whether
simpler or with better performance potential) fundamental building
block for any of the constructs suggested in this (email) thread,
other than fields on Thread itself.
On Tue, Dec 4, 2018 at 4:06 PM <dean.long at oracle.com> wrote:
>
> I'd like to hear more about static thread locals and how they could be
> implemented. It's not clear to me how we would implement something
> dynamic on top of the something static.
>
> dl
>
> On 12/4/18 1:46 PM, David Lloyd wrote:
> > Passing hidden values is a good use case for static thread locals
> > (assuming they would utilize just a couple of lookups). In fact
> > static thread locals can be used to implement probably most of the
> > suggested mechanisms...
>
--
- DML
More information about the loom-dev
mailing list