G'day all, I just committed a few patches for Zero support on BSD which should be fairly safe. I've got a couple more that I'd like to get some review on before committing. So far I've tested them on FreeBSD 7.x/i386 (single processor machine) and I'm able to run a few simple Java programmes with the resulting JDK:
> ./build/bsd-i586/bin/java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-glewis_2009_11_15_11_42-b00) OpenJDK Zero VM (build 17.0-b05, interpreted mode) These are the extra settings I'm using to build Zero: ZERO_BUILD=true ZERO_ENDIANNESS=little ZERO_LIBARCH=i386 ZERO_ARCHDEF=IA32 It doesn't really seem like I should have to set the latter three, but they don't seem to get set otherwise for the HotSpot build. It really seems like the build should run something like jdk/make/jdk_generic_profile.sh which seems to set up things for Zero. Anyway, in terms of the patches, I'd like some opinions on whether the atomic changes are portable across the different BSDs (and whether they do the right thing :). Note that the changes to os_bsd_zero.cpp are fairly minimal. I suspect a careful review of the file may identify more changes that should be made. I'll include the patches inline and also attach them since I'm not sure on the mailing list policy regarding attachments. diff -r 5fb0aafeaac6 src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp --- a/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Sun Nov 15 12:43:44 2009 -0800 +++ b/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Sun Nov 15 12:45:00 2009 -0800 @@ -154,6 +154,9 @@ } #endif // ARM +#include <sys/types.h> +#include <machine/atomic.h> + inline void Atomic::store(jint store_value, volatile jint* dest) { *dest = store_value; } @@ -163,27 +166,13 @@ } inline jint Atomic::add(jint add_value, volatile jint* dest) { -#ifdef ARM - return arm_add_and_fetch(dest, add_value); -#else -#ifdef M68K - return m68k_add_and_fetch(dest, add_value); -#else - return __sync_add_and_fetch(dest, add_value); -#endif // M68K -#endif // ARM + atomic_add_int((volatile u_int*) dest, add_value); + return *dest; } inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { -#ifdef ARM - return arm_add_and_fetch(dest, add_value); -#else -#ifdef M68K - return m68k_add_and_fetch(dest, add_value); -#else - return __sync_add_and_fetch(dest, add_value); -#endif // M68K -#endif // ARM + atomic_add_ptr(dest, add_value); + return *dest; } inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { @@ -215,32 +204,16 @@ } inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { -#ifdef ARM - return arm_lock_test_and_set(dest, exchange_value); -#else -#ifdef M68K - return m68k_lock_test_and_set(dest, exchange_value); -#else - // __sync_lock_test_and_set is a bizarrely named atomic exchange - // operation. Note that some platforms only support this with the - // limitation that the only valid value to store is the immediate - // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); -#endif // M68K -#endif // ARM + jint prev = *dest; + atomic_store_rel_int((volatile u_int*) dest, exchange_value); + return prev; } inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { -#ifdef ARM - return arm_lock_test_and_set(dest, exchange_value); -#else -#ifdef M68K - return m68k_lock_test_and_set(dest, exchange_value); -#else - return __sync_lock_test_and_set (dest, exchange_value); -#endif // M68K -#endif // ARM + intptr_t prev = *dest; + atomic_store_rel_ptr(dest, exchange_value); + return prev; } inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { @@ -251,36 +224,25 @@ inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) { -#ifdef ARM - return arm_compare_and_swap(dest, compare_value, exchange_value); -#else -#ifdef M68K - return m68k_compare_and_swap(dest, compare_value, exchange_value); -#else - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -#endif // M68K -#endif // ARM + jint prev = *dest; + atomic_cmpset_int((volatile u_int*) dest, compare_value, exchange_value); + return prev; } inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value) { - - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); + jlong prev = *dest; + atomic_cmpset_long((volatile u_long*) dest, compare_value, exchange_value); + return prev; } inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { -#ifdef ARM - return arm_compare_and_swap(dest, compare_value, exchange_value); -#else -#ifdef M68K - return m68k_compare_and_swap(dest, compare_value, exchange_value); -#else - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -#endif // M68K -#endif // ARM + intptr_t prev = *dest; + atomic_cmpset_ptr(dest, compare_value, exchange_value); + return prev; } inline void* Atomic::cmpxchg_ptr(void* exchange_value, diff -r 5fb0aafeaac6 src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp --- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Sun Nov 15 12:43:44 2009 -0800 +++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Sun Nov 15 12:45:00 2009 -0800 @@ -23,6 +23,10 @@ * */ +#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__) +# include <pthread_np.h> /* For pthread_attr_get_np */ +#endif + // do not include precompiled header file #include "incls/_os_bsd_zero.cpp.incl" @@ -145,6 +149,7 @@ thread->disable_stack_red_zone(); ShouldNotCallThis(); } +#ifndef _ALLBSD_SOURCE else { // Accessing stack address below sp may cause SEGV if // current thread has MAP_GROWSDOWN stack. This should @@ -163,6 +168,7 @@ fatal("recursive segv. expanding stack."); } } +#endif } } @@ -230,6 +236,7 @@ // Nothing to do } +#ifndef _ALLBSD_SOURCE int os::Bsd::get_fpu_control_word() { ShouldNotCallThis(); } @@ -237,6 +244,7 @@ void os::Bsd::set_fpu_control_word(int fpu) { ShouldNotCallThis(); } +#endif bool os::is_allocatable(size_t bytes) { ShouldNotCallThis(); @@ -267,6 +275,48 @@ } static void current_stack_region(address *bottom, size_t *size) { + address stack_bottom; + address stack_top; + size_t stack_bytes; + +#ifdef __APPLE__ + pthread_t self = pthread_self(); + stack_top = (address) pthread_get_stackaddr_np(self); + stack_bytes = pthread_get_stacksize_np(self); + stack_bottom = stacktop - stack_bytes; +#elif defined(__OpenBSD__) + stack_t ss; + int rslt = pthread_stackseg_np(pthread_self(), &ss); + + if (rslt != 0) + fatal1("pthread_stackseg_np failed with err = %d", rslt); + + stack_top = (address) ss.ss_sp; + stack_bytes = ss.ss_size; + stack_bottom = stacktop - stack_bytes; +#elif defined(_ALLBSD_SOURCE) + pthread_attr_t attr; + + int rslt = pthread_attr_init(&attr); + + // JVM needs to know exact stack location, abort if it fails + if (rslt != 0) + fatal1("pthread_attr_init failed with err = %d", rslt); + + rslt = pthread_attr_get_np(pthread_self(), &attr); + + if (rslt != 0) + fatal1("pthread_attr_get_np failed with err = %d", rslt); + + if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 || + pthread_attr_getstacksize(&attr, &stack_bytes) != 0) { + fatal("Can not locate current stack attributes!"); + } + + pthread_attr_destroy(&attr); + + stack_top = stack_bottom + stack_bytes; +#else /* Linux */ pthread_attr_t attr; int res = pthread_getattr_np(pthread_self(), &attr); if (res != 0) { @@ -278,13 +328,11 @@ } } - address stack_bottom; - size_t stack_bytes; res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes); if (res != 0) { fatal1("pthread_attr_getstack failed with errno = %d", res); } - address stack_top = stack_bottom + stack_bytes; + stack_top = stack_bottom + stack_bytes; // The block of memory returned by pthread_attr_getstack() includes // guard pages where present. We need to trim these off. @@ -326,6 +374,7 @@ stack_bottom = stack_top - stack_bytes; } +#endif assert(os::current_stack_pointer() >= stack_bottom, "should do"); assert(os::current_stack_pointer() < stack_top, "should do"); -- Greg Lewis Email : gle...@eyesbeyond.com Eyes Beyond Web : http://www.eyesbeyond.com Information Technology FreeBSD : gle...@freebsd.org
diff -r 5fb0aafeaac6 src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp --- a/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Sun Nov 15 12:43:44 2009 -0800 +++ b/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Sun Nov 15 12:45:00 2009 -0800 @@ -154,6 +154,9 @@ } #endif // ARM +#include <sys/types.h> +#include <machine/atomic.h> + inline void Atomic::store(jint store_value, volatile jint* dest) { *dest = store_value; } @@ -163,27 +166,13 @@ } inline jint Atomic::add(jint add_value, volatile jint* dest) { -#ifdef ARM - return arm_add_and_fetch(dest, add_value); -#else -#ifdef M68K - return m68k_add_and_fetch(dest, add_value); -#else - return __sync_add_and_fetch(dest, add_value); -#endif // M68K -#endif // ARM + atomic_add_int((volatile u_int*) dest, add_value); + return *dest; } inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { -#ifdef ARM - return arm_add_and_fetch(dest, add_value); -#else -#ifdef M68K - return m68k_add_and_fetch(dest, add_value); -#else - return __sync_add_and_fetch(dest, add_value); -#endif // M68K -#endif // ARM + atomic_add_ptr(dest, add_value); + return *dest; } inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { @@ -215,32 +204,16 @@ } inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { -#ifdef ARM - return arm_lock_test_and_set(dest, exchange_value); -#else -#ifdef M68K - return m68k_lock_test_and_set(dest, exchange_value); -#else - // __sync_lock_test_and_set is a bizarrely named atomic exchange - // operation. Note that some platforms only support this with the - // limitation that the only valid value to store is the immediate - // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); -#endif // M68K -#endif // ARM + jint prev = *dest; + atomic_store_rel_int((volatile u_int*) dest, exchange_value); + return prev; } inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { -#ifdef ARM - return arm_lock_test_and_set(dest, exchange_value); -#else -#ifdef M68K - return m68k_lock_test_and_set(dest, exchange_value); -#else - return __sync_lock_test_and_set (dest, exchange_value); -#endif // M68K -#endif // ARM + intptr_t prev = *dest; + atomic_store_rel_ptr(dest, exchange_value); + return prev; } inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { @@ -251,36 +224,25 @@ inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) { -#ifdef ARM - return arm_compare_and_swap(dest, compare_value, exchange_value); -#else -#ifdef M68K - return m68k_compare_and_swap(dest, compare_value, exchange_value); -#else - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -#endif // M68K -#endif // ARM + jint prev = *dest; + atomic_cmpset_int((volatile u_int*) dest, compare_value, exchange_value); + return prev; } inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value) { - - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); + jlong prev = *dest; + atomic_cmpset_long((volatile u_long*) dest, compare_value, exchange_value); + return prev; } inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { -#ifdef ARM - return arm_compare_and_swap(dest, compare_value, exchange_value); -#else -#ifdef M68K - return m68k_compare_and_swap(dest, compare_value, exchange_value); -#else - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -#endif // M68K -#endif // ARM + intptr_t prev = *dest; + atomic_cmpset_ptr(dest, compare_value, exchange_value); + return prev; } inline void* Atomic::cmpxchg_ptr(void* exchange_value, diff -r 5fb0aafeaac6 src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp --- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Sun Nov 15 12:43:44 2009 -0800 +++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Sun Nov 15 12:45:00 2009 -0800 @@ -23,6 +23,10 @@ * */ +#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__) +# include <pthread_np.h> /* For pthread_attr_get_np */ +#endif + // do not include precompiled header file #include "incls/_os_bsd_zero.cpp.incl" @@ -145,6 +149,7 @@ thread->disable_stack_red_zone(); ShouldNotCallThis(); } +#ifndef _ALLBSD_SOURCE else { // Accessing stack address below sp may cause SEGV if // current thread has MAP_GROWSDOWN stack. This should @@ -163,6 +168,7 @@ fatal("recursive segv. expanding stack."); } } +#endif } } @@ -230,6 +236,7 @@ // Nothing to do } +#ifndef _ALLBSD_SOURCE int os::Bsd::get_fpu_control_word() { ShouldNotCallThis(); } @@ -237,6 +244,7 @@ void os::Bsd::set_fpu_control_word(int fpu) { ShouldNotCallThis(); } +#endif bool os::is_allocatable(size_t bytes) { ShouldNotCallThis(); @@ -267,6 +275,48 @@ } static void current_stack_region(address *bottom, size_t *size) { + address stack_bottom; + address stack_top; + size_t stack_bytes; + +#ifdef __APPLE__ + pthread_t self = pthread_self(); + stack_top = (address) pthread_get_stackaddr_np(self); + stack_bytes = pthread_get_stacksize_np(self); + stack_bottom = stacktop - stack_bytes; +#elif defined(__OpenBSD__) + stack_t ss; + int rslt = pthread_stackseg_np(pthread_self(), &ss); + + if (rslt != 0) + fatal1("pthread_stackseg_np failed with err = %d", rslt); + + stack_top = (address) ss.ss_sp; + stack_bytes = ss.ss_size; + stack_bottom = stacktop - stack_bytes; +#elif defined(_ALLBSD_SOURCE) + pthread_attr_t attr; + + int rslt = pthread_attr_init(&attr); + + // JVM needs to know exact stack location, abort if it fails + if (rslt != 0) + fatal1("pthread_attr_init failed with err = %d", rslt); + + rslt = pthread_attr_get_np(pthread_self(), &attr); + + if (rslt != 0) + fatal1("pthread_attr_get_np failed with err = %d", rslt); + + if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 || + pthread_attr_getstacksize(&attr, &stack_bytes) != 0) { + fatal("Can not locate current stack attributes!"); + } + + pthread_attr_destroy(&attr); + + stack_top = stack_bottom + stack_bytes; +#else /* Linux */ pthread_attr_t attr; int res = pthread_getattr_np(pthread_self(), &attr); if (res != 0) { @@ -278,13 +328,11 @@ } } - address stack_bottom; - size_t stack_bytes; res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes); if (res != 0) { fatal1("pthread_attr_getstack failed with errno = %d", res); } - address stack_top = stack_bottom + stack_bytes; + stack_top = stack_bottom + stack_bytes; // The block of memory returned by pthread_attr_getstack() includes // guard pages where present. We need to trim these off. @@ -326,6 +374,7 @@ stack_bottom = stack_top - stack_bytes; } +#endif assert(os::current_stack_pointer() >= stack_bottom, "should do"); assert(os::current_stack_pointer() < stack_top, "should do");