diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c65a69e9a4..3f7bf52a0e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,28 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-11-24 16:48 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/vm/dlmalloc.c + % use harbour spin locks if available by default in all builds + + * harbour/include/hbatomic.h + * removed HB_SPINLOCK_SLEEP macro and enable code to always yield + the processor in spin locks + * cover double spin lock setting by HB_SPINLOCK_REPEAT + + * harbour/src/vm/garbage.c + * removed unused HB_SPINLOCK_SLEEP macro + + * harbour/include/hbstack.h + * harbour/src/vm/estack.c + + added new internal function hb_stackAllocator() + * disable hb_stackTotalItems() stack macro so this function can be + used also in internal HVM code to check if stack is initialized + + * harbour/src/vm/fm.c + ! use hb_stackAllocator() to access pointer to DLMALLOC mspace + It should fix GPF when DLMT was used in OS2 builds - please test. + 2009-11-24 07:43 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbxbp/xbplistbox.prg * contrib/hbxbp/xbptreeview.prg diff --git a/harbour/include/hbatomic.h b/harbour/include/hbatomic.h index f1e80e57c5..9c49924f65 100644 --- a/harbour/include/hbatomic.h +++ b/harbour/include/hbatomic.h @@ -72,6 +72,22 @@ HB_EXTERN_BEGIN +/* yield the processor */ +#if defined( HB_TASK_THREAD ) +# define HB_SCHED_YIELD() hb_taskYield() +#elif defined( HB_OS_WIN ) +# define HB_SCHED_YIELD() Sleep( 0 ) +#elif defined( HB_OS_OS2 ) +# define HB_SCHED_YIELD() DosSleep( 0 ) +#elif defined( __SVR4 ) +# define HB_SCHED_YIELD() thr_yield() +#elif defined( HB_OS_UNIX ) +# define HB_SCHED_YIELD() sched_yield() +#else +# define HB_SCHED_YIELD() sleep( 0 ); +#endif + + /* Inline assembler version of atomic operations on memory reference counters */ #if defined( __GNUC__ ) @@ -150,23 +166,11 @@ HB_EXTERN_BEGIN if( !hb_spinlock_trylock( l ) ) return; - #ifdef HB_SPINLOCK_SLEEP + #ifdef HB_SPINLOCK_REPEAT if( !hb_spinlock_trylock( l ) ) return; - #if defined( HB_TASK_THREAD ) - hb_taskYield(); - #elif defined( HB_OS_WIN ) - Sleep( 0 ); - #elif defined( HB_OS_OS2 ) - DosSleep( 0 ); - #elif defined( __SVR4 ) - thr_yield(); - #elif defined( HB_OS_UNIX ) - sched_yield(); - #else - sleep( 0 ); - #endif #endif + HB_SCHED_YIELD(); } } @@ -195,23 +199,11 @@ HB_EXTERN_BEGIN if( !__sync_lock_test_and_set( l, 1 ) ) return; - #ifdef HB_SPINLOCK_SLEEP + #ifdef HB_SPINLOCK_REPEAT if( !__sync_lock_test_and_set( l, 1 ) ) return; - #if defined( HB_TASK_THREAD ) - hb_taskYield(); - #elif defined( HB_OS_WIN ) - Sleep( 0 ); - #elif defined( HB_OS_OS2 ) - DosSleep( 0 ); - #elif defined( __SVR4 ) - thr_yield(); - #elif defined( HB_OS_UNIX ) - sched_yield(); - #else - sleep( 0 ); - #endif #endif + HB_SCHED_YIELD(); } } @@ -356,23 +348,11 @@ HB_EXTERN_BEGIN if( !hb_spinlock_trylock( l ) ) return; - #ifdef HB_SPINLOCK_SLEEP + #ifdef HB_SPINLOCK_REPEAT if( !hb_spinlock_trylock( l ) ) return; - #if defined( HB_TASK_THREAD ) - hb_taskYield(); - #elif defined( HB_OS_WIN ) - Sleep( 0 ); - #elif defined( HB_OS_OS2 ) - DosSleep( 0 ); - #elif defined( __SVR4 ) - thr_yield(); - #elif defined( HB_OS_UNIX ) - sched_yield(); - #else - sleep( 0 ); - #endif #endif + HB_SCHED_YIELD(); } } @@ -416,16 +396,21 @@ HB_EXTERN_BEGIN # if !defined( HB_SPINLOCK_T ) # define HB_SPINLOCK_T volatile LONG # define HB_SPINLOCK_INIT 0 -# define HB_SPINLOCK_ACQUIRE(l) do { \ - for( ;; ) \ - { \ +# ifdef HB_SPINLOCK_REPEAT +# define HB_SPINLOCK_ACQUIRE(l) do { \ if( !InterlockedExchange( (LONG*)(l), 1 ) ) \ break; \ if( !InterlockedExchange( (LONG*)(l), 1 ) ) \ break; \ Sleep( 0 ); \ - } \ - } while(0) + } while(1) +# else +# define HB_SPINLOCK_ACQUIRE(l) do { \ + if( !InterlockedExchange( (LONG*)(l), 1 ) ) \ + break; \ + Sleep( 0 ); \ + } while(1) +# endif # define HB_SPINLOCK_RELEASE(l) do { *(l) = 0; } while(0) # endif @@ -480,16 +465,21 @@ HB_EXTERN_BEGIN # if !defined( HB_SPINLOCK_T ) # define HB_SPINLOCK_T volatile uint_t # define HB_SPINLOCK_INIT 0 -# define HB_SPINLOCK_ACQUIRE(l) do { \ - for( ;; ) \ - { \ +# ifdef HB_SPINLOCK_REPEAT +# define HB_SPINLOCK_ACQUIRE(l) do { \ if( !atomic_swap_uint( (l), 1 ) ) \ break; \ if( !atomic_swap_uint( (l), 1 ) ) \ break; \ thr_yield(); \ - } \ - } while(0) + } while(1) +# else +# define HB_SPINLOCK_ACQUIRE(l) do { \ + if( !atomic_swap_uint( (l), 1 ) ) \ + break; \ + thr_yield(); \ + } while(1) +# endif # define HB_SPINLOCK_RELEASE(l) do { *(l) = 0; } while(0) # endif diff --git a/harbour/include/hbstack.h b/harbour/include/hbstack.h index a308b19992..7a969070e0 100644 --- a/harbour/include/hbstack.h +++ b/harbour/include/hbstack.h @@ -357,6 +357,7 @@ extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC ); extern void hb_stackSetQuitState( USHORT uiState ); extern int hb_stackUnlock( void ); extern int hb_stackLock( void ); + extern void * hb_stackAllocator( void ); #endif #endif /* _HB_API_INTERNAL_ */ @@ -372,7 +373,7 @@ extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC ); #define hb_stackItemFromBase( n ) ( * ( hb_stack.pBase + ( int ) ( n ) + 1 ) ) #define hb_stackTopOffset( ) ( hb_stack.pPos - hb_stack.pItems ) #define hb_stackBaseOffset( ) ( hb_stack.pBase - hb_stack.pItems + 1 ) -#define hb_stackTotalItems( ) ( hb_stack.wItems ) +/* #define hb_stackTotalItems( ) ( hb_stack.wItems ) */ #define hb_stackBaseItem( ) ( * hb_stack.pBase ) #define hb_stackSelfItem( ) ( * ( hb_stack.pBase + 1 ) ) #define hb_stackItem( iItemPos ) ( * ( hb_stack.pItems + ( long ) ( iItemPos ) ) ) diff --git a/harbour/src/vm/dlmalloc.c b/harbour/src/vm/dlmalloc.c index b3449574e9..7774cd1afd 100644 --- a/harbour/src/vm/dlmalloc.c +++ b/harbour/src/vm/dlmalloc.c @@ -1449,20 +1449,20 @@ static int win32munmap(void* ptr, size_t size) { unique mparams values are initialized only once. */ -#if defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) || defined( __WATCOMC__ ) +#ifdef HB_MT_VM # ifndef HB_SPINLOCK_USE # define HB_SPINLOCK_USE -# endif -#endif +# endif /* HB_SPINLOCK_USE */ +#endif /* HB_MT_VM */ #ifdef HB_SPINLOCK_USE # include "hbthread.h" # include "hbatomic.h" -#endif +#endif /* HB_SPINLOCK_USE */ #ifndef HB_SPINLOCK_T # undef HB_SPINLOCK_USE -#endif +#endif /* HB_SPINLOCK_T */ #ifdef HB_SPINLOCK_USE diff --git a/harbour/src/vm/estack.c b/harbour/src/vm/estack.c index 4133292f05..73f96b0558 100644 --- a/harbour/src/vm/estack.c +++ b/harbour/src/vm/estack.c @@ -835,6 +835,19 @@ LONG hb_stackTotalItems( void ) #endif } +#if defined( HB_MT_VM ) +void * hb_stackAllocator( void ) +{ + if( hb_stack_ready() ) + { + HB_STACK_TLS_PRELOAD + + return hb_stack.allocator; + } + return NULL; +} +#endif + #undef hb_stackDateBuffer char * hb_stackDateBuffer( void ) { diff --git a/harbour/src/vm/fm.c b/harbour/src/vm/fm.c index f4674793f2..a4d81a5a8e 100644 --- a/harbour/src/vm/fm.c +++ b/harbour/src/vm/fm.c @@ -381,10 +381,10 @@ static HB_MSPACE s_mspool[ HB_MSPACE_COUNT ]; static mspace hb_mspace( void ) { - HB_STACK_TLS_PRELOAD + PHB_MSPACE pm = ( PHB_MSPACE ) hb_stackAllocator(); - if( hb_stackId() && hb_stack.allocator ) - return ( ( PHB_MSPACE ) hb_stack.allocator )->ms; + if( pm ) + return pm->ms; if( !s_gm ) s_gm = create_mspace( 0, 1 ); diff --git a/harbour/src/vm/garbage.c b/harbour/src/vm/garbage.c index 622784fa8c..7a3381a4e1 100644 --- a/harbour/src/vm/garbage.c +++ b/harbour/src/vm/garbage.c @@ -68,8 +68,6 @@ #if defined( HB_MT_VM ) -# define HB_SPINLOCK_SLEEP - # include "hbthread.h" # include "hbatomic.h"