diff -ru jdk-1_5_0-scsl.b4/hotspot/src/os/bsd/vm/os_bsd.cpp jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm/os_bsd.cpp --- jdk-1_5_0-scsl.b4/hotspot/src/os/bsd/vm/os_bsd.cpp 2007-01-24 11:12:39.000000000 +0100 +++ jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm/os_bsd.cpp 2007-02-22 23:53:00.000000000 +0100 @@ -138,15 +138,39 @@ // thread value in thread local storage. #endif + uintptr_t raw = pd_raw_thread_id(); + int ix = pd_cache_index(raw); + + if (thread != NULL) { + // first make sure that nobody gets a cache collision pointing to + // this thread by updating its raw id + thread->_self_raw_id = raw; + // 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; + // Update thread cache with new thread if setting on thread create + _get_thread_cache[ix] = thread; + } else { + // deleting current thread, must get old value first + Thread* was_thread = Thread::current(); + + // first make sure that nobody gets a cache collision pointing to + // the old thread data (soon to be free'd) by updating the raw id + was_thread->_self_raw_id = raw; + + // again, update the "real" value first: + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); + + // then invalidate all cache elements that pointed to this thread + // by setting them to NO_CACHED_THREAD (zeroed thread) + for (int ix = 0; ix < _pd_cache_size; ++ix) { + if (_get_thread_cache[ix] == was_thread) { + _get_thread_cache[ix] = NO_CACHED_THREAD; + } + } + } } void ThreadLocalStorage::pd_init() { @@ -1190,7 +1214,7 @@ // XXXBSD: hmm... really do not need? void os::free_thread_local_storage(int index) { // %%% don't think we need anything here - // if ( pthread_key_delete((pthread_key_t) tk) ) + // if ( pthread_key_delete((pthread_key_t) index) ) // fatal("os::free_thread_local_storage: pthread_key_delete failed"); } Only in jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm: os_bsd.cpp.orig diff -ru jdk-1_5_0-scsl.b4/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp --- jdk-1_5_0-scsl.b4/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp 2007-01-24 11:12:39.000000000 +0100 +++ jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp 2007-02-22 23:53:00.000000000 +0100 @@ -19,18 +19,31 @@ uintptr_t raw = pd_raw_thread_id(); int ix = pd_cache_index(raw); -// XXXBSD: disable fast case. there is a race condition where the -// fast case returns a different thread from the slow case and has -// been seen on both OpenBSD and FreeBSD. +// XXXBSD: fast case. +// there was a race condition where the fast case returned a different +// thread from the slow case and has been seen on both OpenBSD and +// FreeBSD, but I think it's fixed, so enable it for now: #if 1 - return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix); -#else Thread *Candidate = ThreadLocalStorage::_get_thread_cache[ix]; + if (Candidate->_self_raw_id == raw) { - // hit + // direct hit return Candidate; - } else { - return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix); } + + address stacktop = Candidate->_stack_base; + address stackbot = Candidate->_stack_base - Candidate->_stack_size; + + address sp = pd_sp_address(); + + // is this still the right thread? Check if current stack pointer + // is within the thread's stack, if ok update it with current raw id. + if (stacktop > sp && stackbot <= sp ) { + Candidate->_self_raw_id = raw; + // indirect hit + return Candidate; + } + ix = pd_cache_index(raw); #endif + return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix); } Only in jdk-1_5_0-scsl.b4.fct2/hotspot/src/os/bsd/vm: thread_bsd.inline.hpp.orig diff -ru jdk-1_5_0-scsl.b4/hotspot/src/os_cpu/bsd_amd64/vm/threadLS_bsd_amd64.hpp jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_amd64/vm/threadLS_bsd_amd64.hpp --- jdk-1_5_0-scsl.b4/hotspot/src/os_cpu/bsd_amd64/vm/threadLS_bsd_amd64.hpp 2007-01-24 11:12:39.000000000 +0100 +++ jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_amd64/vm/threadLS_bsd_amd64.hpp 2007-02-22 23:53:00.000000000 +0100 @@ -9,7 +9,7 @@ // Processor dependent parts of ThreadLocalStorage private: - static Thread* _get_thread_cache[]; // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size] + static Thread* _get_thread_cache[]; // index by [(raw_id^(raw_id>>10)) % _pd_cache_size] static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index); NOT_PRODUCT(static int _tcacheHit;) @@ -20,8 +20,8 @@ static void print_statistics() PRODUCT_RETURN; enum Constants { - _pd_cache_size = 128*2, // projected typical # of threads * 2 - + // projected typical # of threads * 2 * typical active stack pages + _pd_cache_size = 128*2*4, _pd_min_page_size = 4*K, _pd_typical_stack_size = 512*K }; @@ -37,9 +37,8 @@ } static int pd_cache_index(uintptr_t sp_page) { - return ((sp_page / 2) /* pages tend to come in pairs */ - ^ (sp_page / (_pd_typical_stack_size/_pd_min_page_size))) - % _pd_cache_size; + // _pd_cache_size == 1<<10 + return (sp_page ^ (sp_page >> 10)) % _pd_cache_size; } // Java Thread Only in jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_amd64/vm: threadLS_bsd_amd64.hpp.orig diff -ru jdk-1_5_0-scsl.b4/hotspot/src/os_cpu/bsd_i486/vm/threadLS_bsd_i486.hpp jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_i486/vm/threadLS_bsd_i486.hpp --- jdk-1_5_0-scsl.b4/hotspot/src/os_cpu/bsd_i486/vm/threadLS_bsd_i486.hpp 2007-01-24 11:12:39.000000000 +0100 +++ jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_i486/vm/threadLS_bsd_i486.hpp 2007-02-22 23:53:00.000000000 +0100 @@ -9,7 +9,7 @@ // Processor dependent parts of ThreadLocalStorage private: - static Thread* _get_thread_cache[]; // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size] + static Thread* _get_thread_cache[]; // index by [(raw_id^(raw_id>>10)) % _pd_cache_size] static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index); NOT_PRODUCT(static int _tcacheHit;) @@ -20,26 +20,26 @@ static void print_statistics() PRODUCT_RETURN; enum Constants { - _pd_cache_size = 128*2, // projected typical # of threads * 2 - + // projected typical # of threads * typical active stack pages * 2 + _pd_cache_size = 128*2*4, _pd_min_page_size = 4*K, _pd_typical_stack_size = 512*K }; static address pd_sp_address() { - int junk; - return (address)&junk; + address sp; + __asm__ volatile ("movl %%esp, %0" : "=r" (sp)); + return sp; } static uintptr_t pd_raw_thread_id() { - address sp = pd_sp_address(); - return (unsigned int)sp / _pd_min_page_size; + // _pd_min_page_size == 1 << 12 + return ((unsigned int)pd_sp_address()) >> 12; } static int pd_cache_index(uintptr_t sp_page) { - return ((sp_page / 2) /* pages tend to come in pairs */ - ^ (sp_page / (_pd_typical_stack_size/_pd_min_page_size))) - % _pd_cache_size; + // _pd_cache_size == 1<<10 + return (sp_page ^ (sp_page >> 10)) % _pd_cache_size; } // Java Thread Only in jdk-1_5_0-scsl.b4.fct2/hotspot/src/os_cpu/bsd_i486/vm: threadLS_bsd_i486.hpp.orig diff -ru jdk-1_5_0-scsl.b4/hotspot/src/share/vm/runtime/thread.cpp jdk-1_5_0-scsl.b4.fct2/hotspot/src/share/vm/runtime/thread.cpp --- jdk-1_5_0-scsl.b4/hotspot/src/share/vm/runtime/thread.cpp 2007-01-24 10:40:33.000000000 +0100 +++ jdk-1_5_0-scsl.b4.fct2/hotspot/src/share/vm/runtime/thread.cpp 2007-02-22 23:53:01.000000000 +0100 @@ -104,6 +104,11 @@ delete _SR_lock; + // to make sure nobody finds the deleted thread as a current thread + // in the cache (when comparing stack pointers) + set_stack_base(0); + set_stack_size(0); + // clear thread local storage if the Thread is deleting itself if (this == Thread::current()) { ThreadLocalStorage::set_thread(NULL); Only in jdk-1_5_0-scsl.b4.fct2/hotspot/src/share/vm/runtime: thread.cpp.orig