2008-10-06 15:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbthread.h
  * harbour/source/vm/thread.c
  * harbour/source/vm/hvm.c
    + add numeric HVM thread identifiers to thread structure. Now
      HB_THREADID() returns numbers in all OSes

  * harbour/include/hbexprop.h
  * harbour/include/hbexprb.c
  * harbour/source/common/expropt2.c
    + added compile time optimization for MIN() and MAX() functions

  * harbour/source/rtl/minmax.c
    * removed trailing spaces from source code
This commit is contained in:
Przemyslaw Czerpak
2008-10-06 13:30:47 +00:00
parent 12ac680ed3
commit 67cc2f7ebe
8 changed files with 239 additions and 53 deletions

View File

@@ -8,6 +8,21 @@
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
*/
2008-10-06 15:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbthread.h
* harbour/source/vm/thread.c
* harbour/source/vm/hvm.c
+ add numeric HVM thread identifiers to thread structure. Now
HB_THREADID() returns numbers in all OSes
* harbour/include/hbexprop.h
* harbour/include/hbexprb.c
* harbour/source/common/expropt2.c
+ added compile time optimization for MIN() and MAX() functions
* harbour/source/rtl/minmax.c
* removed trailing spaces from source code
2008-10-06 12:38 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbclass.ch
* harbour/include/hboo.ch

View File

@@ -1654,6 +1654,16 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall )
if( usCount && HB_SUPPORT_HARBOUR )
hb_compExprReduceCTOD( pSelf, HB_COMP_PARAM );
}
else if( strcmp( "MIN", pName->value.asSymbol ) == 0 )
{
if( usCount == 2 && HB_SUPPORT_HARBOUR )
hb_compExprReduceMIN( pSelf, HB_COMP_PARAM );
}
else if( strcmp( "MAX", pName->value.asSymbol ) == 0 )
{
if( usCount == 2 && HB_SUPPORT_HARBOUR )
hb_compExprReduceMAX( pSelf, HB_COMP_PARAM );
}
else if( strcmp( "UPPER", pName->value.asSymbol ) == 0 )
{
if( usCount )
@@ -1762,7 +1772,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall )
HB_EXPR_PTR pArg = pParms->value.asList.pExprList;
char buf[ 16 ];
BOOL fStrict;
/* TODO: warning message does not fit very well, because it requires
type of used parameter. Let's print "unknown", to avoid deeper
analysis of parameter.
@@ -1848,7 +1858,7 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall )
snprintf( buf, sizeof( buf ), "%d", (int) usCount );
hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_COUNT, buf, "1 or 2" );
}
/* hb_i18n_gettext_noop() is not a real function. It is used to
force writing of string to .pot file. So, we should try to
replaced function call by first argument regardless fI18n flag

View File

@@ -203,6 +203,8 @@ extern BOOL hb_compExprReduceSTOD( HB_EXPR_PTR, USHORT usCount, HB_COMP_DECL );
extern BOOL hb_compExprReduceDTOS( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceCTOD( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceUPPER( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceMIN( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceMAX( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceBitFunc( HB_EXPR_PTR, HB_LONG, BOOL, HB_COMP_DECL );
extern void hb_compI18nAdd( HB_COMP_DECL, const char* szText, const char* szContext, UINT uiLine );

View File

@@ -99,8 +99,9 @@ HB_EXTERN_BEGIN
#if defined( HB_PTHREAD_API )
typedef HB_LONG HB_THREAD_NO;
typedef pthread_t HB_THREAD_ID;
typedef pthread_t HB_THREAD_T;
typedef pthread_t HB_THREAD_HANDLE;
typedef pthread_mutex_t HB_RAWCRITICAL_T;
typedef pthread_cond_t HB_RAWCOND_T;
@@ -139,8 +140,9 @@ HB_EXTERN_BEGIN
# define HB_MAX_THREAD 32768
typedef HB_LONG HB_THREAD_NO;
typedef unsigned HB_THREAD_ID;
typedef HANDLE HB_THREAD_T;
typedef HANDLE HB_THREAD_HANDLE;
typedef CRITICAL_SECTION HB_RAWCRITICAL_T;
typedef HANDLE HB_RAWCOND_T;
@@ -184,8 +186,14 @@ HB_EXTERN_BEGIN
#elif defined( HB_OS_OS2 )
/* In OS2 thread ID is continuous integer number so we can use it directly
* anyhow I'd prefer to not make such strict binding to OS values because
* it make cause troubles when code will be ported to other platforms.
*/
/* typedef TID HB_THREAD_NO; */
typedef HB_LONG HB_THREAD_NO;
typedef TID HB_THREAD_ID;
typedef TID HB_THREAD_T;
typedef TID HB_THREAD_HANDLE;
typedef HMTX HB_RAWCRITICAL_T;
typedef HEV HB_RAWCOND_T;
@@ -210,8 +218,9 @@ HB_EXTERN_BEGIN
#else
typedef int HB_THREAD_NO;
typedef int HB_THREAD_ID;
typedef int HB_THREAD_T;
typedef int HB_THREAD_HANDLE;
typedef int HB_CRITICAL_T;
typedef int HB_RAWCRITICAL_T;
typedef int HB_COND_T;
@@ -273,7 +282,9 @@ typedef struct _HB_THREADSTATE
PHB_ITEM pMemvars;
PHB_ITEM pResult;
PHB_ITEM pThItm;
HB_THREAD_T th_id;
HB_THREAD_NO th_no;
HB_THREAD_ID th_id;
HB_THREAD_HANDLE th_h;
struct _HB_THREADSTATE * pPrev;
struct _HB_THREADSTATE * pNext;
} HB_THREADSTATE, * PHB_THREADSTATE;
@@ -292,9 +303,9 @@ extern BOOL hb_threadCondBroadcast( HB_COND_T * cond );
extern BOOL hb_threadCondWait( HB_COND_T * cond, HB_CRITICAL_T * mutex );
extern BOOL hb_threadCondTimedWait( HB_COND_T * cond, HB_CRITICAL_T * mutex, ULONG ulMilliSec );
extern HB_THREAD_T hb_threadCreate( PHB_THREAD_STARTFUNC start_func, void * Cargo );
extern BOOL hb_threadJoin( HB_THREAD_T th_id );
extern BOOL hb_threadDetach( HB_THREAD_T th_id );
extern HB_THREAD_HANDLE hb_threadCreate( HB_THREAD_ID * th_id, PHB_THREAD_STARTFUNC start_func, void * Cargo );
extern BOOL hb_threadJoin( HB_THREAD_HANDLE th_h );
extern BOOL hb_threadDetach( HB_THREAD_HANDLE th_h );
/* used by .prg code */
extern PHB_ITEM hb_threadMutexCreate( BOOL fSync );

View File

@@ -1904,6 +1904,144 @@ BOOL hb_compExprReduceUPPER( HB_EXPR_PTR pSelf, HB_COMP_DECL )
return FALSE;
}
BOOL hb_compExprReduceMIN( HB_EXPR_PTR pSelf, HB_COMP_DECL )
{
HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms;
HB_EXPR_PTR pFirst = pParms->value.asList.pExprList;
HB_EXPR_PTR pNext = pFirst->pNext;
if( pFirst->ExprType == pNext->ExprType )
{
HB_EXPR_PTR pExpr = NULL;
if( pNext->ExprType == HB_ET_NUMERIC )
{
BYTE bType = ( pFirst->value.asNum.NumType & pNext->value.asNum.NumType );
switch( bType )
{
case HB_ET_LONG:
pExpr = pFirst->value.asNum.val.l <= pNext->value.asNum.val.l ?
pFirst : pNext;
break;
case HB_ET_DOUBLE:
pExpr = pFirst->value.asNum.val.d <= pNext->value.asNum.val.d ?
pFirst : pNext;
break;
default:
if( pFirst->value.asNum.NumType == HB_ET_DOUBLE )
pExpr = pFirst->value.asNum.val.d <= ( double ) pNext->value.asNum.val.l ?
pFirst : pNext;
else
pExpr = ( double ) pFirst->value.asNum.val.l <= pNext->value.asNum.val.d ?
pFirst : pNext;
}
}
else if( pFirst->ExprType == HB_ET_DATE )
{
pExpr = pFirst->value.asNum.val.l <= pNext->value.asNum.val.l ?
pFirst : pNext;
}
else if( pFirst->ExprType == HB_ET_LOGICAL )
{
pExpr = !pFirst->value.asLogical ? pFirst : pNext;
}
if( pExpr )
{
HB_EXPR_PTR * pExprPtr = &pParms->value.asList.pExprList;
while( *pExprPtr )
{
if( *pExprPtr == pExpr )
{
*pExprPtr = pExpr->pNext;
break;
}
pExprPtr = &( *pExprPtr )->pNext;
}
HB_COMP_EXPR_FREE( pParms );
HB_COMP_EXPR_FREE( pSelf->value.asFunCall.pFunName );
memcpy( pSelf, pExpr, sizeof( HB_EXPR ) );
HB_COMP_EXPR_CLEAR( pExpr );
return TRUE;
}
}
return FALSE;
}
BOOL hb_compExprReduceMAX( HB_EXPR_PTR pSelf, HB_COMP_DECL )
{
HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms;
HB_EXPR_PTR pFirst = pParms->value.asList.pExprList;
HB_EXPR_PTR pNext = pFirst->pNext;
if( pFirst->ExprType == pNext->ExprType )
{
HB_EXPR_PTR pExpr = NULL;
if( pNext->ExprType == HB_ET_NUMERIC )
{
BYTE bType = ( pFirst->value.asNum.NumType & pNext->value.asNum.NumType );
switch( bType )
{
case HB_ET_LONG:
pExpr = pFirst->value.asNum.val.l >= pNext->value.asNum.val.l ?
pFirst : pNext;
break;
case HB_ET_DOUBLE:
pExpr = pFirst->value.asNum.val.d >= pNext->value.asNum.val.d ?
pFirst : pNext;
break;
default:
if( pFirst->value.asNum.NumType == HB_ET_DOUBLE )
pExpr = pFirst->value.asNum.val.d >= ( double ) pNext->value.asNum.val.l ?
pFirst : pNext;
else
pExpr = ( double ) pFirst->value.asNum.val.l >= pNext->value.asNum.val.d ?
pFirst : pNext;
}
}
else if( pFirst->ExprType == HB_ET_DATE )
{
pExpr = pFirst->value.asNum.val.l >= pNext->value.asNum.val.l ?
pFirst : pNext;
}
else if( pFirst->ExprType == HB_ET_LOGICAL )
{
pExpr = pFirst->value.asLogical ? pFirst : pNext;
}
if( pExpr )
{
HB_EXPR_PTR * pExprPtr = &pParms->value.asList.pExprList;
while( * pExprPtr )
{
if( * pExprPtr == pExpr )
{
* pExprPtr = pExpr->pNext;
break;
}
pExprPtr = &( *pExprPtr )->pNext;
}
HB_COMP_EXPR_FREE( pParms );
HB_COMP_EXPR_FREE( pSelf->value.asFunCall.pFunName );
memcpy( pSelf, pExpr, sizeof( HB_EXPR ) );
HB_COMP_EXPR_CLEAR( pExpr );
return TRUE;
}
}
return FALSE;
}
BOOL hb_compExprReduceBitFunc( HB_EXPR_PTR pSelf, HB_LONG lResult, BOOL fBool, HB_COMP_DECL )
{
HB_EXPR_PTR pParms = pSelf->value.asFunCall.pParms;

View File

@@ -66,7 +66,7 @@ HB_FUNC( MAX )
{
HB_LONG l1 = hb_itemGetNInt( p1 );
HB_LONG l2 = hb_itemGetNInt( p2 );
hb_retnint( l1 >= l2 ? l1 : l2 );
return;
}
@@ -74,13 +74,13 @@ HB_FUNC( MAX )
{
double d1 = hb_itemGetND( p1 );
double d2 = hb_itemGetND( p2 );
int iDec1;
int iDec2;
hb_itemGetNLen( p1, NULL, &iDec1 );
hb_itemGetNLen( p2, NULL, &iDec2 );
if( d1 >= d2 )
hb_retndlen( d1, 0, iDec1 );
else
@@ -91,14 +91,14 @@ HB_FUNC( MAX )
{
BOOL b1 = hb_itemGetL( p1 );
BOOL b2 = hb_itemGetL( p2 );
hb_retl( b1 >= b2 ? b1 : b2 );
return;
}
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
{
char szDate[ 9 ];
hb_retds( hb_itemGetDL( p1 ) >= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
return;
}
@@ -118,7 +118,7 @@ HB_FUNC( MIN )
{
HB_LONG l1 = hb_itemGetNInt( p1 );
HB_LONG l2 = hb_itemGetNInt( p2 );
hb_retnint( l1 <= l2 ? l1 : l2 );
return;
}
@@ -126,13 +126,13 @@ HB_FUNC( MIN )
{
double d1 = hb_itemGetND( p1 );
double d2 = hb_itemGetND( p2 );
int iDec1;
int iDec2;
hb_itemGetNLen( p1, NULL, &iDec1 );
hb_itemGetNLen( p2, NULL, &iDec2 );
if( d1 <= d2 )
hb_retndlen( d1, 0, iDec1 );
else
@@ -143,14 +143,14 @@ HB_FUNC( MIN )
{
BOOL b1 = hb_itemGetL( p1 );
BOOL b2 = hb_itemGetL( p2 );
hb_retl( b1 <= b2 ? b1 : b2 );
return;
}
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
{
char szDate[ 9 ];
hb_retds( hb_itemGetDL( p1 ) <= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
return;
}

View File

@@ -390,6 +390,8 @@ static int volatile s_iStackCount = 0;
static int volatile s_iRunningCount = 0;
/* active HVM stacks list */
static PHB_THREADSTATE s_vmStackLst = NULL;
/* thread number */
static HB_THREAD_NO s_threadNo = 0;
# define HB_THREQUEST_STOP 1
# define HB_THREQUEST_QUIT 2
@@ -608,6 +610,8 @@ static void hb_vmStackAdd( PHB_THREADSTATE pState )
}
s_iStackCount++;
}
if( pState->th_no )
pState->th_no = ++s_threadNo;
}
static void hb_vmStackDel( PHB_THREADSTATE pState )

View File

@@ -354,45 +354,51 @@ BOOL hb_threadCondTimedWait( HB_COND_T * cond, HB_CRITICAL_T * mutex, ULONG ulMi
#endif
}
HB_THREAD_T hb_threadCreate( PHB_THREAD_STARTFUNC start_func, void * Cargo )
HB_THREAD_HANDLE hb_threadCreate( HB_THREAD_ID * th_id, PHB_THREAD_STARTFUNC start_func, void * Cargo )
{
HB_THREAD_T th_id;
HB_THREAD_HANDLE th_h;
#if !defined( HB_MT_VM )
HB_SYMBOL_UNUSED( start_func );
HB_SYMBOL_UNUSED( Cargo );
th_id = 0;
*th_id = ( HB_THREAD_ID ) 0;
th_h = ( HB_THREAD_HANDLE ) 0;
#elif defined( HB_PTHREAD_API )
if( pthread_create( &th_id, NULL, start_func, Cargo ) != 0 )
th_id = 0;
if( pthread_create( th_id, NULL, start_func, Cargo ) != 0 )
*th_id = ( HB_THREAD_ID ) 0;
th_h = *th_id;
#elif defined( HB_OS_WIN_32 )
th_id = ( HANDLE ) _beginthreadex( NULL, 0, start_func, Cargo, 0, NULL );
th_h = ( HANDLE ) _beginthreadex( NULL, 0, start_func, Cargo, 0, th_id );
if( !th_h )
*th_id = ( HB_THREAD_ID ) 0;
#elif defined( HB_OS_OS2 )
th_id = _beginthread( ( void * ) start_func, NULL, 128 * 1024, Cargo );
*th_id = _beginthread( ( void * ) start_func, NULL, 128 * 1024, Cargo );
th_h = *th_id;
#else
{ int TODO_MT; }
th_id = 0;
*th_id = ( HB_THREAD_ID ) 0;
th_h = ( HB_THREAD_HANDLE ) 0;
#endif
return th_id;
return th_h;
}
BOOL hb_threadJoin( HB_THREAD_T th_id )
BOOL hb_threadJoin( HB_THREAD_HANDLE th_h )
{
#if !defined( HB_MT_VM )
HB_SYMBOL_UNUSED( th_id );
HB_SYMBOL_UNUSED( th_h );
return FALSE;
#elif defined( HB_PTHREAD_API )
return pthread_join( th_id, NULL ) == 0;
return pthread_join( th_h, NULL ) == 0;
#elif defined( HB_OS_WIN_32 )
if( WaitForSingleObject( th_id, INFINITE ) != WAIT_FAILED )
if( WaitForSingleObject( th_h, INFINITE ) != WAIT_FAILED )
{
CloseHandle( th_id );
CloseHandle( th_h );
return TRUE;
}
return FALSE;
#elif defined( HB_OS_OS2 )
APIRET rc = DosWaitThread( &th_id, DCWW_WAIT );
APIRET rc = DosWaitThread( &th_h, DCWW_WAIT );
/* TOFIX: ERROR_INVALID_THREADID is a hack for failing DosWaitThread()
* when thread terminates before DosWaitThread() call.
* OS2 users please check and fix this code if possible.
@@ -404,17 +410,17 @@ BOOL hb_threadJoin( HB_THREAD_T th_id )
#endif
}
BOOL hb_threadDetach( HB_THREAD_T th_id )
BOOL hb_threadDetach( HB_THREAD_HANDLE th_h )
{
#if !defined( HB_MT_VM )
HB_SYMBOL_UNUSED( th_id );
HB_SYMBOL_UNUSED( th_h );
return FALSE;
#elif defined( HB_PTHREAD_API )
return pthread_detach( th_id ) == 0;
return pthread_detach( th_h ) == 0;
#elif defined( HB_OS_WIN_32 )
return CloseHandle( th_id ) != 0;
return CloseHandle( th_h ) != 0;
#elif defined( HB_OS_OS2 )
APIRET rc = DosWaitThread( &th_id, DCWW_NOWAIT );
APIRET rc = DosWaitThread( &th_h, DCWW_NOWAIT );
return rc == NO_ERROR || rc == ERROR_INVALID_THREADID;
#else
{ int TODO_MT; }
@@ -453,10 +459,10 @@ static HB_GARBAGE_FUNC( hb_threadDestructor )
hb_xfree( pThread->pSet );
pThread->pSet = NULL;
}
if( pThread->th_id != 0 )
if( pThread->th_h != 0 )
{
hb_threadDetach( pThread->th_id );
pThread->th_id = 0;
hb_threadDetach( pThread->th_h );
pThread->th_h = 0;
}
}
@@ -657,9 +663,9 @@ HB_FUNC( HB_THREADSTART )
#if defined( HB_MT_VM )
if( hb_vmThreadRegister( ( void * ) pThread ) )
#endif
pThread->th_id = hb_threadCreate( hb_threadStartVM, ( void * ) pReturn );
pThread->th_h = hb_threadCreate( &pThread->th_id, hb_threadStartVM, ( void * ) pReturn );
if( pThread->th_id == 0 )
if( !pThread->th_h )
{
#if defined( HB_MT_VM )
hb_vmThreadRelease( pThread );
@@ -692,7 +698,7 @@ HB_FUNC( HB_THREADID )
#if defined( HB_MT_VM )
PHB_THREADSTATE pThread = ( PHB_THREADSTATE ) hb_vmThreadState();
if( pThread )
hb_retnint( ( HB_PTRDIFF ) pThread->th_id );
hb_retnint( ( HB_PTRDIFF ) pThread->th_no );
else
#endif
hb_retnint( 0 );
@@ -706,12 +712,12 @@ HB_FUNC( HB_THREADJOIN )
{
BOOL fResult = FALSE;
if( pThread->th_id )
if( pThread->th_h )
{
hb_vmUnlock();
fResult = hb_threadJoin( pThread->th_id );
fResult = hb_threadJoin( pThread->th_h );
if( fResult )
pThread->th_id = 0;
pThread->th_h = 0;
hb_vmLock();
}
if( fResult )
@@ -735,9 +741,9 @@ HB_FUNC( HB_THREADDETACH )
{
BOOL fResult = FALSE;
if( pThread->th_id && hb_threadDetach( pThread->th_id ) )
if( pThread->th_h && hb_threadDetach( pThread->th_h ) )
{
pThread->th_id = 0;
pThread->th_h = 0;
fResult = TRUE;
}
hb_retl( fResult );