2010-03-23 15:19 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbxvm.h
  * harbour/src/vm/hvm.c
    + added hb_xvmPushAliasedFieldExt() and hb_xvmPopAliasedFieldExt()

  * harbour/src/compiler/gencc.c
    % use hb_xvmPushAliasedFieldExt() and hb_xvmPopAliasedFieldExt()
      to optimize code generated for <alias> -> <name> expressions
      in -gc3 mode

  * harbour/include/hbsetup.h
    + added _HB_INLINE_ macro

  * harbour/include/hbatomic.h
    + added HB_SPINLOCK_TRY(l)
    + added support for recursive spin locks

  * harbour/src/vm/fm.c
    * use _HB_INLINE_
This commit is contained in:
Przemyslaw Czerpak
2010-03-23 14:20:25 +00:00
parent ee0a524db2
commit 766cd74186
7 changed files with 277 additions and 60 deletions

View File

@@ -17,6 +17,26 @@
past entries belonging to author(s): Viktor Szakats.
*/
2010-03-23 15:19 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbxvm.h
* harbour/src/vm/hvm.c
+ added hb_xvmPushAliasedFieldExt() and hb_xvmPopAliasedFieldExt()
* harbour/src/compiler/gencc.c
% use hb_xvmPushAliasedFieldExt() and hb_xvmPopAliasedFieldExt()
to optimize code generated for <alias> -> <name> expressions
in -gc3 mode
* harbour/include/hbsetup.h
+ added _HB_INLINE_ macro
* harbour/include/hbatomic.h
+ added HB_SPINLOCK_TRY(l)
+ added support for recursive spin locks
* harbour/src/vm/fm.c
* use _HB_INLINE_
2010-03-23 12:55 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
* harbour/contrib/rddsql/hbrddsql.h
* harbour/contrib/rddsql/sqlbase.c

View File

@@ -79,7 +79,7 @@ HB_EXTERN_BEGIN
# define HB_SCHED_YIELD() Sleep( 0 )
#elif defined( HB_OS_OS2 )
# define HB_SCHED_YIELD() DosSleep( 0 )
#elif defined( __SVR4 )
#elif defined( HB_OS_SUNOS ) || defined( __SVR4 )
# define HB_SCHED_YIELD() thr_yield()
#elif defined( HB_OS_UNIX )
# define HB_SCHED_YIELD() sched_yield()
@@ -165,7 +165,6 @@ HB_EXTERN_BEGIN
{
if( !hb_spinlock_trylock( l ) )
return;
#ifdef HB_SPINLOCK_REPEAT
if( !hb_spinlock_trylock( l ) )
return;
@@ -181,8 +180,10 @@ HB_EXTERN_BEGIN
# define HB_SPINLOCK_T volatile int
# define HB_SPINLOCK_INIT 0
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# define HB_SPINLOCK_TRY(l) (hb_spinlock_trylock(l)==0)
# define HB_SPINLOCK_RELEASE(l) hb_spinlock_release(l)
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# elif ( ( __GNUC__ > 4 ) || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 1) ) && \
!defined( __MINGW32CE__ )
@@ -209,8 +210,9 @@ HB_EXTERN_BEGIN
# define HB_SPINLOCK_T int
# define HB_SPINLOCK_INIT 0
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# define HB_SPINLOCK_TRY(l) (__sync_lock_test_and_set(l. 1)==0)
# define HB_SPINLOCK_RELEASE(l) __sync_lock_release(l)
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# elif defined( HB_CPU_PPC )
@@ -327,7 +329,7 @@ HB_EXTERN_BEGIN
"xchg eax, dword ptr [edx]" \
parm [ edx ] value [ eax ] modify exact [ eax ] ;
static inline void hb_spinlock_acquire( volatile int * l )
static __inline void hb_spinlock_acquire( volatile int * l )
{
for( ;; )
{
@@ -342,15 +344,16 @@ HB_EXTERN_BEGIN
}
}
static inline void hb_spinlock_release( volatile int * l )
static __inline void hb_spinlock_release( volatile int * l )
{
*l = 0;
}
# define HB_SPINLOCK_T volatile int
# define HB_SPINLOCK_INIT 0
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# define HB_SPINLOCK_TRY(l) (hb_spinlock_trylock(l)==0)
# define HB_SPINLOCK_RELEASE(l) hb_spinlock_release(l)
# define HB_SPINLOCK_ACQUIRE(l) hb_spinlock_acquire(l)
# endif /* x86 */
@@ -382,22 +385,8 @@ HB_EXTERN_BEGIN
# if !defined( HB_SPINLOCK_T )
# define HB_SPINLOCK_T volatile LONG
# define HB_SPINLOCK_INIT 0
# 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(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)
# define HB_SPINLOCK_TRY(l) (!InterlockedExchange( (LONG*)(l), 1 ))
# define HB_SPINLOCK_RELEASE(l) ( *(l) = 0 )
# endif
#elif defined( HB_OS_DARWIN )
@@ -425,12 +414,14 @@ HB_EXTERN_BEGIN
# if !defined( HB_SPINLOCK_T ) || 1 /* <= force using OSSpinLock */
# undef HB_SPINLOCK_T
# undef HB_SPINLOCK_INIT
# undef HB_SPINLOCK_ACQUIRE
# undef HB_SPINLOCK_TRY
# undef HB_SPINLOCK_RELEASE
# undef HB_SPINLOCK_ACQUIRE
# define HB_SPINLOCK_T OSSpinLock
# define HB_SPINLOCK_INIT OS_SPINLOCK_INIT
# define HB_SPINLOCK_ACQUIRE(l) OSSpinLockLock(l)
# define HB_SPINLOCK_TRY(l) OSSpinLockTry(l)
# define HB_SPINLOCK_RELEASE(l) OSSpinLockUnlock(l)
# define HB_SPINLOCK_ACQUIRE(l) OSSpinLockLock(l)
# endif
#elif defined( HB_OS_SUNOS )
@@ -451,26 +442,139 @@ HB_EXTERN_BEGIN
# if !defined( HB_SPINLOCK_T )
# define HB_SPINLOCK_T volatile uint_t
# define HB_SPINLOCK_INIT 0
# 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(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)
# define HB_SPINLOCK_TRY(l) ( ! atomic_swap_uint( (l), 1 ) )
# define HB_SPINLOCK_RELEASE(l) ( *(l) = 0 )
# endif
#endif /* HB_OS_??? */
#if defined( HB_SPINLOCK_T )
# if !defined( HB_SPINLOCK_ACQUIRE )
# ifdef HB_SPINLOCK_REPEAT
# define HB_SPINLOCK_ACQUIRE(l) do { \
if( HB_SPINLOCK_TRY( l ) ) \
break; \
if( HB_SPINLOCK_TRY( l ) ) \
break; \
HB_SCHED_YIELD(); \
} while(1)
# else
# define HB_SPINLOCK_ACQUIRE(l) do { \
if( HB_SPINLOCK_TRY( l ) ) \
break; \
HB_SCHED_YIELD(); \
} while(1)
# endif
# endif
# if !defined( HB_SPINLOCK_R )
struct hb_spinlock_r
{
HB_SPINLOCK_T lock;
unsigned int count;
HB_THREAD_ID thid;
};
static _HB_INLINE_ void hb_spinlock_release_r( struct hb_spinlock_r * sl )
{
if( --sl->count == 0 )
{
sl->thid = 0;
HB_SPINLOCK_RELEASE( &sl->lock );
}
}
static _HB_INLINE_ int hb_spinlock_try_r( struct hb_spinlock_r * sl )
{
HB_SPINLOCK_T * l = &(sl)->lock;
int r = 0;
if( *l != HB_SPINLOCK_INIT )
{
if( (sl)->thid == HB_THREAD_SELF() )
{
(sl)->count++;
r = 1;
}
}
else if( HB_SPINLOCK_TRY( l ) )
{
(sl)->thid = HB_THREAD_SELF();
(sl)->count = 1;
r = 1;
}
return r;
}
# ifndef HB_SPINLOCK_REPEAT
# define HB_SPINLOCK_REPEAT 63
# endif
/* workaround for borland C/C++ compiler limitation */
#if defined( __BORLANDC__ )
# define hb_spinlock_acquire_r( sl ) \
do { \
HB_SPINLOCK_T * l = &(sl)->lock; \
int count = HB_SPINLOCK_REPEAT; \
for( ;; ) \
{ \
if( *l != HB_SPINLOCK_INIT ) \
{ \
if( (sl)->thid == HB_THREAD_SELF() ) \
{ \
(sl)->count++; \
break; \
} \
} \
else if( HB_SPINLOCK_TRY( l ) ) \
{ \
(sl)->thid = HB_THREAD_SELF(); \
(sl)->count = 1; \
break; \
} \
if( --count == 0 ) \
{ \
HB_SCHED_YIELD(); \
count = HB_SPINLOCK_REPEAT; \
} \
} \
} while( 0 )
#else
static _HB_INLINE_ void hb_spinlock_acquire_r( struct hb_spinlock_r * sl )
{
HB_SPINLOCK_T * l = &(sl)->lock;
int count = HB_SPINLOCK_REPEAT;
for( ;; )
{
if( *l != HB_SPINLOCK_INIT )
{
if( (sl)->thid == HB_THREAD_SELF() )
{
(sl)->count++;
break;
}
}
else if( HB_SPINLOCK_TRY( l ) )
{
(sl)->thid = HB_THREAD_SELF();
(sl)->count = 1;
break;
}
if( --count == 0 )
{
HB_SCHED_YIELD();
count = HB_SPINLOCK_REPEAT;
}
}
}
#endif
# define HB_SPINLOCK_R struct hb_spinlock_r
# define HB_SPINLOCK_INIT_R { 0, 0, 0 }
# define HB_SPINLOCK_TRY_R(l) hb_spinlock_try_r(l)
# define HB_SPINLOCK_RELEASE_R(l) hb_spinlock_release_r(l)
# define HB_SPINLOCK_ACQUIRE_R(l) hb_spinlock_acquire_r(l)
# endif /* !HB_SPINLOCK_R */
#endif /* HB_SPINLOCK_T */
HB_EXTERN_END
#endif /* HB_ATOMIC_H_ */

View File

@@ -515,4 +515,15 @@
#define HB_RESTRICT
#endif
#if defined( __GNUC__ ) || defined( __SUNPRO_C ) || defined( __SUNPRO_CC )
#define _HB_INLINE_ __inline__
#elif defined( __BORLANDC__ ) || defined( _MSC_VER ) || \
defined( __WATCOMC__ ) || defined( __POCC__ ) || defined( __XCC__ ) || \
defined( __LCC__ ) || defined( __DMC__ )
#define _HB_INLINE_ __inline
#else /* __cplusplus */
#define _HB_INLINE_ inline
#endif
#endif /* HB_SETUP_H_ */

View File

@@ -131,6 +131,8 @@ extern HB_EXPORT HB_BOOL hb_xvmPushMemvarByRef( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPopMemvar( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPushAliasedField( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPopAliasedField( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPushAliasedFieldExt( PHB_SYMB pAlias, PHB_SYMB pField );
extern HB_EXPORT HB_BOOL hb_xvmPopAliasedFieldExt( PHB_SYMB pAlias, PHB_SYMB pField );
extern HB_EXPORT HB_BOOL hb_xvmPushAliasedVar( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPopAliasedVar( PHB_SYMB pSymbol );
extern HB_EXPORT HB_BOOL hb_xvmPushAlias( void );

View File

@@ -1401,12 +1401,39 @@ static HB_GENC_FUNC( hb_p_pushsym )
{
HB_GENC_LABEL();
if( pFunc->pCode[ lPCodePos + 3 ] == HB_P_PUSHNIL &&
HB_GENC_GETLABEL( lPCodePos + 3 ) == 0 )
if( HB_GENC_GETLABEL( lPCodePos + 3 ) == 0 )
{
fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %hu );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) );
return 4;
switch( pFunc->pCode[ lPCodePos + 3 ] )
{
case HB_P_PUSHNIL:
fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %hu );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) );
return 4;
case HB_P_PUSHALIASEDFIELDNEAR:
fprintf( cargo->yyc,
"\thb_xvmPushAliasedFieldExt( symbols + %u, symbols + %u );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
pFunc->pCode[ lPCodePos + 4 ] );
return 5;
case HB_P_PUSHALIASEDFIELD:
fprintf( cargo->yyc,
"\thb_xvmPushAliasedFieldExt( symbols + %u, symbols + %u );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 4 ] ) );
return 6;
case HB_P_POPALIASEDFIELDNEAR:
fprintf( cargo->yyc,
"\thb_xvmPopAliasedFieldExt( symbols + %u, symbols + %u );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
pFunc->pCode[ lPCodePos + 4 ] );
return 5;
case HB_P_POPALIASEDFIELD:
fprintf( cargo->yyc,
"\thb_xvmPopAliasedFieldExt( symbols + %u, symbols + %u );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 4 ] ) );
return 6;
}
}
fprintf( cargo->yyc, "\thb_xvmPushSymbol( symbols + %hu );\n",
@@ -1418,12 +1445,39 @@ static HB_GENC_FUNC( hb_p_pushsymnear )
{
HB_GENC_LABEL();
if( pFunc->pCode[ lPCodePos + 2 ] == HB_P_PUSHNIL &&
HB_GENC_GETLABEL( lPCodePos + 2 ) == 0 )
if( HB_GENC_GETLABEL( lPCodePos + 2 ) == 0 )
{
fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %hu );\n",
pFunc->pCode[ lPCodePos + 1 ] );
return 3;
switch( pFunc->pCode[ lPCodePos + 2 ] )
{
case HB_P_PUSHNIL:
fprintf( cargo->yyc, "\thb_xvmPushFuncSymbol( symbols + %u );\n",
pFunc->pCode[ lPCodePos + 1 ] );
return 3;
case HB_P_PUSHALIASEDFIELDNEAR:
fprintf( cargo->yyc,
"\thb_xvmPushAliasedFieldExt( symbols + %u, symbols + %u );\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 3 ] );
return 4;
case HB_P_PUSHALIASEDFIELD:
fprintf( cargo->yyc,
"\thb_xvmPushAliasedFieldExt( symbols + %u, symbols + %u );\n",
pFunc->pCode[ lPCodePos + 1 ],
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 3 ] ) );
return 5;
case HB_P_POPALIASEDFIELDNEAR:
fprintf( cargo->yyc,
"\thb_xvmPopAliasedFieldExt( symbols + %u, symbols + %u );\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 3 ] );
return 4;
case HB_P_POPALIASEDFIELD:
fprintf( cargo->yyc,
"\thb_xvmPopAliasedFieldExt( symbols + %u, symbols + %u );\n",
pFunc->pCode[ lPCodePos + 1 ],
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 3 ] ) );
return 5;
}
}
fprintf( cargo->yyc, "\thb_xvmPushSymbol( symbols + %d );\n",

View File

@@ -74,13 +74,6 @@
# define _GNU_SOURCE
#endif
/* For Sun C, a more generic solution would be nice */
#if defined( __SUNPRO_C ) || defined( __SUNPRO_CC )
# ifndef __inline
# define __inline __inline__
# endif
#endif
/* NOTE: Need to have these before Harbour headers,
because in MT mode, they will automatically #include <os2.h>. */
#define INCL_BASE
@@ -345,14 +338,14 @@ typedef void * PHB_MEMINFO;
# undef HB_ATOM_INC
# undef HB_ATOM_GET
# undef HB_ATOM_SET
static __inline void hb_counterIncrement( volatile HB_COUNTER * p )
static _HB_INLINE_ void hb_counterIncrement( volatile HB_COUNTER * p )
{
HB_FM_LOCK
++(*p);
HB_FM_UNLOCK
}
# define HB_ATOM_INC( p ) hb_counterIncrement( p )
static __inline int hb_counterDecrement( volatile HB_COUNTER * p )
static _HB_INLINE_ int hb_counterDecrement( volatile HB_COUNTER * p )
{
int iResult;
HB_FM_LOCK

View File

@@ -9317,6 +9317,21 @@ HB_BOOL hb_xvmPushAliasedField( PHB_SYMB pSymbol )
HB_XVM_RETURN
}
HB_BOOL hb_xvmPushAliasedFieldExt( PHB_SYMB pAlias, PHB_SYMB pField )
{
HB_STACK_TLS_PRELOAD
int iCurrArea;
HB_TRACE(HB_TR_INFO, ("hb_xvmPushAliasedFieldExt(%p,%p)", pAlias, pField));
iCurrArea = hb_rddGetCurrentWorkAreaNumber();
if( hb_rddSelectWorkAreaSymbol( pAlias ) == HB_SUCCESS )
hb_rddGetFieldValue( hb_stackAllocItem(), pField );
hb_rddSelectWorkAreaNumber( iCurrArea );
HB_XVM_RETURN
}
HB_BOOL hb_xvmPushAliasedVar( PHB_SYMB pSymbol )
{
HB_STACK_TLS_PRELOAD
@@ -9385,6 +9400,24 @@ HB_BOOL hb_xvmPopAliasedField( PHB_SYMB pSymbol )
HB_XVM_RETURN
}
HB_BOOL hb_xvmPopAliasedFieldExt( PHB_SYMB pAlias, PHB_SYMB pField )
{
HB_STACK_TLS_PRELOAD
int iCurrArea;
HB_TRACE(HB_TR_INFO, ("hb_xvmPopAliasedFieldExt(%p,%p)", pAlias, pField));
iCurrArea = hb_rddGetCurrentWorkAreaNumber();
if( hb_rddSelectWorkAreaSymbol( pAlias ) == HB_SUCCESS )
{
hb_rddPutFieldValue( hb_stackItemFromTop( -1 ), pField );
hb_stackPop();
}
hb_rddSelectWorkAreaNumber( iCurrArea );
HB_XVM_RETURN
}
HB_BOOL hb_xvmPopAliasedVar( PHB_SYMB pSymbol )
{
HB_STACK_TLS_PRELOAD