< prev index next >
src/os/solaris/vm/os_solaris.cpp
Print this page
*** 180,258 ****
static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
}
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
- // Thread Local Storage
- // This is common to all Solaris platforms so it is defined here,
- // in this common file.
- // The declarations are in the os_cpu threadLS*.hpp files.
- //
- // Static member initialization for TLS
- Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
-
- #ifndef PRODUCT
- #define _PCT(n,d) ((100.0*(double)(n))/(double)(d))
-
- int ThreadLocalStorage::_tcacheHit = 0;
- int ThreadLocalStorage::_tcacheMiss = 0;
-
- void ThreadLocalStorage::print_statistics() {
- int total = _tcacheMiss+_tcacheHit;
- tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
- _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
- }
- #undef _PCT
- #endif // PRODUCT
-
- Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
- int index) {
- Thread *thread = get_thread_slow();
- if (thread != NULL) {
- address sp = os::current_stack_pointer();
- guarantee(thread->_stack_base == NULL ||
- (sp <= thread->_stack_base &&
- sp >= thread->_stack_base - thread->_stack_size) ||
- is_error_reported(),
- "sp must be inside of selected thread stack");
-
- thread->set_self_raw_id(raw_id); // mark for quick retrieval
- _get_thread_cache[index] = thread;
- }
- return thread;
- }
-
-
- static const double all_zero[sizeof(Thread) / sizeof(double) + 1] = {0};
- #define NO_CACHED_THREAD ((Thread*)all_zero)
-
- void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-
- // Store the new value before updating the cache to prevent a race
- // between get_thread_via_cache_slowly() and this store operation.
- os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-
- // Update thread cache with new thread if setting on thread create,
- // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
- uintptr_t raw = pd_raw_thread_id();
- int ix = pd_cache_index(raw);
- _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
- }
-
- void ThreadLocalStorage::pd_init() {
- for (int i = 0; i < _pd_cache_size; i++) {
- _get_thread_cache[i] = NO_CACHED_THREAD;
- }
- }
-
- // Invalidate all the caches (happens to be the same as pd_init).
- void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
-
- #undef NO_CACHED_THREAD
-
- // END Thread Local Storage
-
static inline size_t adjust_stack_size(address base, size_t size) {
if ((ssize_t)size < 0) {
// 4759953: Compensate for ridiculous stack size.
size = max_intx;
}
--- 180,189 ----
*** 1287,1357 ****
int os::current_process_id() {
return (int)(_initial_pid ? _initial_pid : getpid());
}
- int os::allocate_thread_local_storage() {
- // %%% in Win32 this allocates a memory segment pointed to by a
- // register. Dan Stein can implement a similar feature in
- // Solaris. Alternatively, the VM can do the same thing
- // explicitly: malloc some storage and keep the pointer in a
- // register (which is part of the thread's context) (or keep it
- // in TLS).
- // %%% In current versions of Solaris, thr_self and TSD can
- // be accessed via short sequences of displaced indirections.
- // The value of thr_self is available as %g7(36).
- // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
- // assuming that the current thread already has a value bound to k.
- // It may be worth experimenting with such access patterns,
- // and later having the parameters formally exported from a Solaris
- // interface. I think, however, that it will be faster to
- // maintain the invariant that %g2 always contains the
- // JavaThread in Java code, and have stubs simply
- // treat %g2 as a caller-save register, preserving it in a %lN.
- thread_key_t tk;
- if (thr_keycreate(&tk, NULL)) {
- fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
- "(%s)", strerror(errno)));
- }
- return int(tk);
- }
-
- void os::free_thread_local_storage(int index) {
- // %%% don't think we need anything here
- // if (pthread_key_delete((pthread_key_t) tk)) {
- // fatal("os::free_thread_local_storage: pthread_key_delete failed");
- // }
- }
-
- // libthread allocate for tsd_common is a version specific
- // small number - point is NO swap space available
- #define SMALLINT 32
- void os::thread_local_storage_at_put(int index, void* value) {
- // %%% this is used only in threadLocalStorage.cpp
- if (thr_setspecific((thread_key_t)index, value)) {
- if (errno == ENOMEM) {
- vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR,
- "thr_setspecific: out of swap space");
- } else {
- fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
- "(%s)", strerror(errno)));
- }
- } else {
- ThreadLocalStorage::set_thread_in_slot((Thread *) value);
- }
- }
-
- // This function could be called before TLS is initialized, for example, when
- // VM receives an async signal or when VM causes a fatal error during
- // initialization. Return NULL if thr_getspecific() fails.
- void* os::thread_local_storage_at(int index) {
- // %%% this is used only in threadLocalStorage.cpp
- void* r = NULL;
- return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
- }
-
-
// gethrtime() should be monotonic according to the documentation,
// but some virtualized platforms are known to break this guarantee.
// getTimeNanos() must be guaranteed not to move backwards, so we
// are forced to add a check here.
inline hrtime_t getTimeNanos() {
--- 1218,1227 ----
< prev index next >