From ca21165e4bfabcf688c5d7ddd9b878d5bd0e0216 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Sun, 14 Sep 2008 20:16:03 +0000 Subject: [PATCH] 2008-09-14 22:15 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbsetup.h * accept both settings: HB_FM_STATISTICS and HB_FM_STATISTICS_OFF without errors * harbour/bin/postinst.sh * added small trick to make HBFM lib compilation not dependent on default HB_FM_STATISTIC settings * harbour/include/hbvm.h * harbour/source/vm/hvm.c + added C function hb_vmIsMt() * harbour/source/vm/cmdarg.c * report MT HVM status when program is executed with //INFO parameter * harbour/source/vm/fm.c ! fixed memory statistic MT protection in hb_xrealloc() operation * harbour/config/w32/owatcom.cf * use echo instead of echo. for non empty output. * harbour/include/hbextern.ch * harbour/source/vm/thread.c + added .prg function hb_threadTerminateAll() - it sends QUIT request to each HVM thread and waits for their termination. Can be executed only by main HVM thread. --- harbour/ChangeLog | 29 +++++++++++++++++++ harbour/bin/postinst.sh | 2 +- harbour/config/w32/owatcom.cf | 14 ++++----- harbour/include/hbextern.ch | 1 + harbour/include/hbsetup.h | 4 ++- harbour/include/hbvm.h | 4 ++- harbour/source/vm/cmdarg.c | 2 +- harbour/source/vm/fm.c | 4 +-- harbour/source/vm/hvm.c | 53 ++++++++++++++++++++--------------- harbour/source/vm/thread.c | 7 +++++ 10 files changed, 84 insertions(+), 36 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c2fd39c657..6d44a188c9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,35 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-09-14 22:15 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbsetup.h + * accept both settings: HB_FM_STATISTICS and HB_FM_STATISTICS_OFF + without errors + + * harbour/bin/postinst.sh + * added small trick to make HBFM lib compilation not dependent on + default HB_FM_STATISTIC settings + + * harbour/include/hbvm.h + * harbour/source/vm/hvm.c + + added C function hb_vmIsMt() + + * harbour/source/vm/cmdarg.c + * report MT HVM status when program is executed with //INFO + parameter + + * harbour/source/vm/fm.c + ! fixed memory statistic MT protection in hb_xrealloc() operation + + * harbour/config/w32/owatcom.cf + * use echo instead of echo. for non empty output. + + * harbour/include/hbextern.ch + * harbour/source/vm/thread.c + + added .prg function hb_threadTerminateAll() - it sends QUIT request + to each HVM thread and waits for their termination. Can be executed + only by main HVM thread. + 2008-09-14 16:30 UTC+0200 Lorenzo Fiorini (lorenzo.fiorini/at/gmail.com) * contrib/hbvpdf/hbvpdf.prg * contrib/hbvpdf/hbvpdf.ch diff --git a/harbour/bin/postinst.sh b/harbour/bin/postinst.sh index 0a37a94c9a..4c9b3b9a37 100755 --- a/harbour/bin/postinst.sh +++ b/harbour/bin/postinst.sh @@ -83,7 +83,7 @@ then fi # build hbfm lib with memory statistic (cd ${hb_root}/source/vm - C_USR=${C_USR//-DHB_FM_STATISTICS_OFF/} + C_USR="${C_USR//-DHB_FM_STATISTICS_OFF/} -DHB_FM_STATISTICS" rm -f fm.o ${MAKE} -r fm.o ${AR} ${AR_OPT} ${HB_LIB_INSTALL}/libhbfm.a fm.o diff --git a/harbour/config/w32/owatcom.cf b/harbour/config/w32/owatcom.cf index b9116960b6..e40e2d6c1f 100644 --- a/harbour/config/w32/owatcom.cf +++ b/harbour/config/w32/owatcom.cf @@ -37,24 +37,24 @@ CPPFLAGS = # Note: The empty line directly before 'endef' HAVE TO exist! # It causes that the 'echo' command is separated by LF define link_file -echo. FILE $(file) >> __link__.tmp +echo FILE $(file) >> __link__.tmp endef #Note: The empty line directly before 'endef' HAVE TO exist! define link_lib -echo. LIB $(lib) >> __link__.tmp +echo LIB $(lib) >> __link__.tmp endef define link_exe_file -echo. $(LDFLAGS) NAME $@ > __link__.tmp +echo $(LDFLAGS) NAME $@ > __link__.tmp $(foreach file, $(^F), $(link_file)) $(foreach lib, $(LINKLIBS), $(link_lib)) $(foreach lib, $(RDDLIBS), $(link_lib)) $(foreach lib, $(GTLIBS), $(link_lib)) -echo. @%watcom%/binnt/wlink.lnk >> __link__.tmp -echo. LIB kernel32.lib, user32.lib, wsock32.lib, winspool.lib, oleaut32.lib, uuid.lib, comctl32.lib, mapi32.lib >> __link__.tmp +echo @%watcom%/binnt/wlink.lnk >> __link__.tmp +echo LIB kernel32.lib, user32.lib, wsock32.lib, winspool.lib, oleaut32.lib, uuid.lib, comctl32.lib, mapi32.lib >> __link__.tmp -$(LD) @__link__.tmp endef @@ -90,12 +90,12 @@ LD_RULE = $(link_exe_file) #Note: The empty line below HAVE TO exist! define lib_object -echo. -+$(file) >> __lib__.tmp +echo -+$(file) >> __lib__.tmp endef define create_library -echo. $(LIB_DIR)/$@ > __lib__.tmp +echo $(LIB_DIR)/$@ > __lib__.tmp $(foreach file, $(^F), $(lib_object)) $(AR) $(ARFLAGS) @__lib__.tmp endef diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index 8dba4398ec..988738be13 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -932,6 +932,7 @@ EXTERNAL HB_THREADJOIN EXTERNAL HB_THREADDETACH EXTERNAL HB_THREADQUITREQUEST EXTERNAL HB_THREADWAITFORALL +EXTERNAL HB_THREADTERMINATEALL EXTERNAL HB_MUTEXCREATE EXTERNAL HB_MUTEXLOCK diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index a822222226..8557af79f0 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -98,7 +98,9 @@ * * By default this is turned on. Define HB_FM_STATISTICS_OFF to turn it off. */ -#ifndef HB_FM_STATISTICS_OFF +#if defined( HB_FM_STATISTICS_OFF ) + #undef HB_FM_STATISTICS +#elif !defined( HB_FM_STATISTICS ) #define HB_FM_STATISTICS #endif diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index f5fbedcefa..11fedbdd0c 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -152,6 +152,7 @@ extern HB_EXPORT void hb_vmPushState( void ); /* push current VM state on st extern HB_EXPORT void hb_vmPopState( void ); /* pop current VM state from stack */ extern HB_EXPORT void hb_vmPushItemRef( PHB_ITEM pItem ); /* push item reference */ +extern HB_EXPORT BOOL hb_vmIsMt( void ); /* return TRUE if HVM is compiled with thread support */ extern HB_EXPORT void hb_vmLock( void ); /* lock VM blocking GC execution by other threads */ extern HB_EXPORT void hb_vmUnlock( void ); /* unlock VM, allow GC execution */ #ifdef _HB_API_INTERNAL_ @@ -160,8 +161,9 @@ extern HB_EXPORT void hb_vmResumeThreads( void ); /* unblock execution of th #endif extern HB_EXPORT void hb_vmThreadInit( void * ); /* allocate local thread HVM stack */ extern HB_EXPORT void hb_vmThreadQuit( void ); /* destroy local thread HVM stack */ -extern HB_EXPORT void hb_vmThreadQuitRequest( void * ); /* send stop request to given thread */ +extern HB_EXPORT void hb_vmThreadQuitRequest( void * ); /* send QUIT request to given thread */ extern HB_EXPORT void hb_vmWaitForThreads( void ); /* wait for all threads to terminate can be called only by main HVM thread */ +extern HB_EXPORT void hb_vmTerminateThreads( void ); /* send QUIT request to all threads except current one and wait for their termination, should be called only by main HVM thread */ /* various flags for supported features */ #define HB_VMFLAG_HARBOUR 1 /* enable Harbour extension */ diff --git a/harbour/source/vm/cmdarg.c b/harbour/source/vm/cmdarg.c index 1d49b1dd82..9ee551dc7c 100644 --- a/harbour/source/vm/cmdarg.c +++ b/harbour/source/vm/cmdarg.c @@ -360,7 +360,7 @@ ULONG hb_cmdargProcessVM( int *pCancelKey, int *pCancelKeyEx ) { char buffer[ 128 ]; /* snprintf( buffer, sizeof( buffer ), "DS avail=%luKB OS avail=%luKB EMM avail=%luKB", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ) ); */ - snprintf( buffer, sizeof( buffer ), "DS avail=%luKB OS avail=%luKB EMM avail=%luKB MemStat:%s", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ), hb_xquery( HB_MEM_USEDMAX ) ? "On" : "Off" ); + snprintf( buffer, sizeof( buffer ), "DS avail=%luKB OS avail=%luKB EMM avail=%luKB MemStat:%s MT:%s", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ), hb_xquery( HB_MEM_USEDMAX ) ? "On" : "Off", hb_vmIsMt() ? "On" : "Off" ); hb_conOutErr( buffer, 0 ); hb_conOutErr( hb_conNewLine(), 0 ); } diff --git a/harbour/source/vm/fm.c b/harbour/source/vm/fm.c index 84521efa45..0a1f9c47d3 100644 --- a/harbour/source/vm/fm.c +++ b/harbour/source/vm/fm.c @@ -435,6 +435,8 @@ HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ) /* reallocates m HB_FM_CLRSIG( pMem, ulMemSize ); + HB_FM_LOCK + #ifdef HB_PARANOID_MEM_CHECK pMem = malloc( HB_ALLOC_SIZE( ulSize ) ); if( pMem ) @@ -453,8 +455,6 @@ HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ) /* reallocates m pMem = realloc( pMemBlock, HB_ALLOC_SIZE( ulSize ) ); #endif - HB_FM_LOCK - s_lMemoryConsumed += ( ulSize - ulMemSize ); if( s_lMemoryMaxConsumed < s_lMemoryConsumed ) s_lMemoryMaxConsumed = s_lMemoryConsumed; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 3bfc579173..b0884ed802 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -360,6 +360,7 @@ static void hb_vmDoInitClip( void ) #if !defined( HB_MT_VM ) +BOOL hb_vmIsMt( void ) { return FALSE; } void hb_vmLock( void ) {} void hb_vmUnlock( void ) {} BOOL hb_vmSuspendThreads( BOOL fWait ) { HB_SYMBOL_UNUSED( fWait ); return TRUE; } @@ -391,6 +392,8 @@ static PHB_VM_STACKLST s_vmStackLst = NULL; # define HB_VM_LOCK hb_threadEnterCriticalSection( &s_vmMtx ); # define HB_VM_UNLOCK hb_threadLeaveCriticalSection( &s_vmMtx ); +BOOL hb_vmIsMt( void ) { return TRUE; } + static void hb_vmRequestTest( void ) { HB_VM_LOCK @@ -509,6 +512,32 @@ void hb_vmResumeThreads( void ) HB_VM_UNLOCK } +/* send QUIT request to all threads except current one + * and wait for their termination, + * should be called only by main HVM thread + */ +void hb_vmTerminateThreads( void ) +{ + HB_VM_LOCK + + if( s_main_thread == hb_stackId() ) + { + hb_vmThreadRequest |= HB_THREQUEST_QUIT; + --s_iRunningCount; + + hb_threadCondBroadcast( &s_vmCond ); + + while( s_iStackCount > 1 ) + hb_threadCondWait( &s_vmCond, &s_vmMtx ); + + ++s_iRunningCount; + /* hb_vmThreadRequest &= ~HB_THREQUEST_QUIT; */ + hb_vmThreadRequest = 0; + + HB_VM_UNLOCK + } +} + /* wait for all threads to terminate * should be called only by main HVM thread */ @@ -531,28 +560,6 @@ void hb_vmWaitForThreads( void ) } } -/* terminate all threads except current one, - * should be called only by main HVM thread - */ -static void hb_vmTerminateThreads( void ) -{ - HB_VM_LOCK - - hb_vmThreadRequest |= HB_THREQUEST_QUIT; - --s_iRunningCount; - - hb_threadCondBroadcast( &s_vmCond ); - - while( s_iStackCount > 1 ) - hb_threadCondWait( &s_vmCond, &s_vmMtx ); - - ++s_iRunningCount; - /* hb_vmThreadRequest &= ~HB_THREQUEST_QUIT; */ - hb_vmThreadRequest = 0; - - HB_VM_UNLOCK -} - static void hb_vmStackAdd( PHB_THREADSTATE pState ) { PHB_VM_STACKLST pStack; @@ -711,7 +718,7 @@ HB_EXPORT void hb_vmThreadQuit( void ) hb_vmStackDel(); /* remove stack from linked HVM stacks list */ } -/* send stop request to given thread */ +/* send QUIT request to given thread */ HB_EXPORT void hb_vmThreadQuitRequest( void * Cargo ) { PHB_THREADSTATE pState; diff --git a/harbour/source/vm/thread.c b/harbour/source/vm/thread.c index 2cd5287200..d178dd0757 100644 --- a/harbour/source/vm/thread.c +++ b/harbour/source/vm/thread.c @@ -607,6 +607,13 @@ HB_FUNC( HB_THREADWAITFORALL ) #endif } +HB_FUNC( HB_THREADTERMINATEALL ) +{ +#if defined( HB_MT_VM ) + hb_vmTerminateThreads(); +#endif +} + /* II. MUTEXES */ typedef struct _HB_MUTEX