1 // natThreadLocal.cc - Native part of ThreadLocal class.
3 // Fast thread local storage for systems that support the __thread
6 /* Copyright (C) 2006 Free Software Foundation
8 This file is part of libgcj.
10 This software is copyrighted work licensed under the terms of the
11 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
20 #include <java-threads.h>
22 #include <gnu/gcj/RawDataManaged.h>
23 #include <java/lang/ThreadLocal.h>
24 #include <java/lang/IllegalArgumentException.h>
25 #include <java/lang/IllegalThreadStateException.h>
26 #include <java/lang/InterruptedException.h>
27 #include <java/util/Map.h>
31 /* We would like to have fast thread local variables that behave in
32 the same way as C and C++ thread local variables. This would mean
33 having an field attribute "thread" (like static, final, etc.).
34 However, this is not compatible with java semantics, which we wish
35 to support transparently. The problems we must overcome are:
37 * In Java, ThreadLocal variables are not statically allocated: they
38 are objects, created at runtime.
40 * Class ThreadLocal is not final and neither are its methods, so it
41 is possible to create a subclass of ThreadLocal that overrides
44 * __thread variables in DSOs are not visible to the garbage
45 collector, so we must ensure that we keep a copy of every thread
46 local variable somewhere on the heap.
48 * Once a ThreadLocal instance has been created and assigned to a
49 static field, that field may be reassigned to a different
50 ThreadLocal instance or null.
52 So, we can't simply replace get() and set() with accesses of a
55 So, we create a pthread_key in each ThreadLocal object and use that
56 as a kind of "look-aside cache". When a ThreadLocal is set, we
57 also set the corresponding thread-specific value. When the
58 ThreadLocal is collected, we delete the key.
60 This scheme is biased towards efficiency when get() is called much
61 more frequently than set(). It is slightly internaler than the
62 all-Java solution using the underlying map in the set() case.
63 However, get() is very much more frequently invoked than set().
68 #ifdef _POSIX_PTHREAD_SEMANTICS
77 java::lang::ThreadLocal::constructNative (void)
79 tls_t *tls = (tls_t *)_Jv_Malloc (sizeof (tls_t));
80 if (pthread_key_create (&tls->key, NULL) == 0)
81 TLSPointer = (::gnu::gcj::RawData *)tls;
87 java::lang::ThreadLocal::set (::java::lang::Object *value)
89 if (TLSPointer != NULL)
91 tls_t* tls = (tls_t*)TLSPointer;
92 pthread_setspecific (tls->key, value);
98 ::java::lang::Object *
99 java::lang::ThreadLocal::get (void)
101 if (TLSPointer == NULL)
102 return internalGet ();
104 tls_t* tls = (tls_t*)TLSPointer;
105 void *obj = pthread_getspecific(tls->key);
108 return (::java::lang::Object *)obj;
110 ::java::lang::Object *value = internalGet ();
111 pthread_setspecific (tls->key, value);
117 java::lang::ThreadLocal::remove (void)
119 if (TLSPointer != NULL)
121 tls_t* tls = (tls_t*)TLSPointer;
122 pthread_setspecific (tls->key, NULL);
129 java::lang::ThreadLocal::finalize (void)
131 if (TLSPointer != NULL)
133 tls_t* tls = (tls_t*)TLSPointer;
134 pthread_key_delete (tls->key);
142 java::lang::ThreadLocal::constructNative (void)
147 java::lang::ThreadLocal::set (::java::lang::Object *value)
152 ::java::lang::Object *
153 java::lang::ThreadLocal::get (void)
155 return internalGet ();
159 java::lang::ThreadLocal::remove (void)
165 java::lang::ThreadLocal::finalize (void)