< 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 >