Maurilio, Luis, Please post a REDUCED, yet SELF CONTAINED, sample that shows the problem.
Ron -------------------------------------------------- From: "Luis Krause Mantilla" <lkrau...@shaw.ca> Sent: Thursday, January 08, 2009 9:27 AM To: "Maurilio Longo" <maurilio.lo...@libero.it> Cc: "Xharbour-Developers List" <xharbour-developers@lists.sourceforge.net>; "Ron Pinkas" <r...@xharbour.com> Subject: Re: [xHarbour-developers] MT build dies at startup > Ron: > > This same problem Maurilio describes occurs with the most current > builds of xharbour builder and for this reason we can't test the > Outlook add-in with any recent versions of xbuilder because > Outlooks bombs upon closing it. > > Regards, > > Maurilio Longo wrote: >> I've received a message from Przemyslaw that I attach here, I think we >> should >> seriously fix these problems, right now xharbour is not useable anymore, >> not >> only in MT mode but even a plain ST code with a destructor (which does >> not >> uses statics nor creates now objects inside destructor). >> >> Maurilio. >> >> >> Message from Przemyslaw follows >> --------8<----------------------------- >> >> It's causes by: >> STATIC lInErr >> inside rtl/terror.prg >> >> below I'm forwarding the last message I sent to Phil with a patch >> which resolves the problem by simple removing lInErr. >> Please note that there is s_iLaunchCount for protection against recursive >> error calls inside source/vm/errorapi.c which in MT version is part of >> HVM >> stack. >> >> The problem with destructors your reported is probably caused by >> executing destructors also for statics variables. Because class >> definition is stored inside such variables then it means that now >> you cannot create any new object inside destructor even if you want >> to remove it immediately. It also means that you should not expect >> any valid values in static variables you will want to access from >> destructors so you should probably not use them in destructors at all. >> >> best regards, >> Przemek >> >> >> ----- Forwarded message from Przemyslaw Czerpak <dru...@acn.waw.pl> ----- >> >> From: Przemyslaw Czerpak <dru...@acn.waw.pl> >> Subject: Re: [xHarbour-developers] ChangeLog 2008-12-23 01:00 UTC+0300 >> PhilKrylov <phil a t newstar.rinet.ru> >> To: Phil Krylov <p...@newstar.rinet.ru> >> Date: Wed, 24 Dec 2008 03:25:48 +0100 >> Lines: 131 >> >> On Wed, 24 Dec 2008, Przemyslaw Czerpak wrote: >> >> Hi Phil, >> >> Finally I located the problem with reference counters and why >> it was crashing in T004. Just simply in some syncing after CVS >> update I had to add by mistake HB_ATOMIC_INC()/HB_ATOMIC_DEC() >> macros definition to the section which is used for ST mode. >> If you moved it then readonly access to complex variables >> begins to work without crashes. Looking for the problem I also >> found that hb_itemUnShareString() was copied from Harbour as >> is without adopting it to xHarbour. I have serious doubts if >> Miguel well knows what he is doing porting Harbour code only >> partially. Someone should verify such modifications. >> I'm attaching patch which resolves this problems and speedtst.prg >> begins to work with xHarbour. But it was rather trivial things. >> Now you should look for much more complicated ones. F.e. race >> conditions when threads are started/finished which causes that >> programs creating simultaneously many short life threads crashes, >> memvar variables which causes unreported memory leaks so in practice >> cannot be use in MT programs which have to be executed for long time >> creating many threads (each new thread allocates new dynamic symbols >> for each used memvar which is never released), add MT protection >> for classy code, remove all global static variables like >> hb_vm_bQuitRequest, s_iBaseLine, hb_vm_iTry, ... >> check the .prg code which also uses many static variables >> (probably you will have to add support for THREAD STATIC if >> you will want to make some things like GETLIST working in MT >> mode), make SETs thread local (or any code which have to use >> them cannot be ported to MT), updated GT code and enable GT >> locking (f.e. see gtapi.c in Harbour and xHarbour), clean >> basic thread API to eliminate race conditions which xHarbour >> thread functions have (see some notes in speedtst.prg), fix >> some compiler constructions like multivalue macros (f.e.: >> a[&("1,2")], qout(&("3,4")), a:={&("5,6,7"})] ) or TRY/CATCH >> which are not MT safe, update debugger for MT mode, reduce >> number of internal locks which kill scalability - you probably >> noticed in speedtst results that on real multiCPU machine is >> more efficient to execute simultaneously 2 * <numCPU> instances >> of single thread xHarbour program then <numCPU> threads in MT one. >> Here it will be necessary to strongly change some subsystems. >> F.e. whole macro compiler is protected by MUTEX so only one thread >> can access it. To resolve it it's necessary to rewrite compiler, >> macrocompiler and lexer code to be MT and reentrant safe. >> And probably many other things I do not remember know. If you >> are interested then I can try to collect modifications I had >> to made in Harbour when I was working on MT mode. I still should >> have a list I created over year ago. >> They should help you to locate places which should be updated. >> HTH >> >> Marry Christmas and Happy New Year, >> Przemek >> >> >> * xharbour/config/rules.cf >> * give PRG_USR higher priority then HB_FLAGS >> >> * xharbour/include/thread.h >> ! fixed declaration of HB_ATOMIC_INC()/HB_ATOMIC_DEC() macros >> for 32bit x86 *nixes - by mistake it was added to ST section >> >> * xharbour/source/rtl/terror.prg >> ! removed lInErr static variable - it breaks using errorNew() in >> MT programs >> >> * xharbour/source/vm/itemapi.c >> ! fixed copied as is from Harbour hb_itemUnShareString() >> Harbour uses different HVM internals and such code cannot >> be copied without adopting to xHarbour >> >> * xharbour/tests/speedtst.prg >> ! fixed possible race condition in initialization >> + added SET WORKAREA PRIVATE >> >> Index: config/rules.cf >> =================================================================== >> RCS file: /cvsroot/xharbour/xharbour/config/rules.cf,v >> retrieving revision 1.13 >> diff -u -r1.13 rules.cf >> --- config/rules.cf 16 Mar 2008 19:15:57 -0000 1.13 >> +++ config/rules.cf 24 Dec 2008 02:19:44 -0000 >> @@ -85,7 +85,7 @@ >> else >> # Rule to generate a C file from a PRG file. >> %.c : $(GRANDP)%.prg >> - $(HB) $? $(PRG_USR) $(HB_FLAGS) >> + $(HB) $? $(HB_FLAGS) $(PRG_USR) >> endif >> >> ifeq ($(SHLVL),) # COMMAND.COM >> Index: include/thread.h >> =================================================================== >> RCS file: /cvsroot/xharbour/xharbour/include/thread.h,v >> retrieving revision 1.126 >> diff -u -r1.126 thread.h >> --- include/thread.h 23 Dec 2008 18:06:33 -0000 1.126 >> +++ include/thread.h 24 Dec 2008 02:19:44 -0000 >> @@ -396,8 +396,37 @@ >> >> #endif >> >> - #define HB_ATOMIC_INC( x ) ( ++(x) ) >> - #define HB_ATOMIC_DEC( x ) ( --(x) ) >> + #if HB_COUNTER_SIZE == 4 && defined( __GNUC__ ) && 1 && \ >> + ( defined( i386 ) || defined( __i386__ ) || defined( >> __x86_64__ ) ) >> + >> + static __inline__ void hb_atomic_inc32( volatile int * p ) >> + { >> + __asm__ __volatile__( >> + "lock; incl %0\n" >> + :"=m" (*p) :"m" (*p) >> + ); >> + } >> + >> + static __inline__ int hb_atomic_dec32( volatile int * p ) >> + { >> + unsigned char c; >> + __asm__ __volatile__( >> + "lock; decl %0\n" >> + "sete %1\n" >> + :"=m" (*p), "=qm" (c) :"m" (*p) : "memory" >> + ); >> + return c == 0; >> + } >> + >> + #define HB_ATOMIC_INC( x ) ( hb_atomic_inc32( ( volatile int >> * ) >> &(x) ) ) >> + #define HB_ATOMIC_DEC( x ) ( hb_atomic_dec32( ( volatile int >> * ) >> &(x) ) ) >> + >> + #else >> + >> + #define HB_ATOMIC_INC( x ) ( ++(x) ) >> + #define HB_ATOMIC_DEC( x ) ( --(x) ) >> + >> + #endif >> >> #define HB_MUTEX_T HB_CRITICAL_T >> #define HB_MUTEX_INIT( x ) HB_CRITICAL_INIT( x ) >> @@ -875,37 +904,8 @@ >> >> #else >> >> - #if HB_COUNTER_SIZE == 4 && defined( __GNUC__ ) && \ >> - ( defined( i386 ) || defined( __i386__ ) || defined( >> __x86_64__ ) ) >> - >> - static __inline__ void hb_atomic_inc32( volatile int * p ) >> - { >> - __asm__ __volatile__( >> - "lock; incl %0\n" >> - :"=m" (*p) :"m" (*p) >> - ); >> - } >> - >> - static __inline__ int hb_atomic_dec32( volatile int * p ) >> - { >> - unsigned char c; >> - __asm__ __volatile__( >> - "lock; decl %0\n" >> - "sete %1\n" >> - :"=m" (*p), "=qm" (c) :"m" (*p) : "memory" >> - ); >> - return c == 0; >> - } >> - >> - #define HB_ATOMIC_INC( x ) ( hb_atomic_inc32( ( volatile int >> * ) >> &(x) ) ) >> - #define HB_ATOMIC_DEC( x ) ( hb_atomic_dec32( ( volatile int >> * ) >> &(x) ) ) >> - >> - #else >> - >> - #define HB_ATOMIC_INC( x ) ( ++(x) ) >> - #define HB_ATOMIC_DEC( x ) ( --(x) ) >> - >> - #endif >> + #define HB_ATOMIC_INC( x ) ( ++(x) ) >> + #define HB_ATOMIC_DEC( x ) ( --(x) ) >> >> #define HB_CRITICAL_LOCK( x ) >> #define HB_CRITICAL_TRYLOCK( x ) >> Index: source/rtl/terror.prg >> =================================================================== >> RCS file: /cvsroot/xharbour/xharbour/source/rtl/terror.prg,v >> retrieving revision 1.19 >> diff -u -r1.19 terror.prg >> --- source/rtl/terror.prg 27 Jun 2008 06:21:49 -0000 1.19 >> +++ source/rtl/terror.prg 24 Dec 2008 02:19:44 -0000 >> @@ -61,19 +61,12 @@ >> >> FUNCTION ErrorNew( SubSystem, GenCode, SubCode, Operation, Description, >> Args, >> ModuleName, ProcName, ProcLine ) >> >> - STATIC lInErr := .F., s_oClass >> + STATIC s_oClass >> LOCAL oErr >> LOCAL nLevel, aaStack >> >> //TraceLog( SubSystem, GenCode, SubCode, Operation, Description, >> Args, >> ModuleName, ProcName, ProcLine ) >> >> - // Avoid RECURSIVE Errors. >> - IF lInErr >> - RETURN NIL >> - ELSE >> - lInErr := .T. >> - ENDIF >> - >> IF s_oClass == NIL >> s_oClass := HBClass():New( "ERROR" ) >> >> @@ -160,8 +153,6 @@ >> oErr:VMThreadId := ThreadGetCurrentInternal() >> #endif >> >> - lInErr := .F. >> - >> RETURN oErr >> >> FUNCTION __eInstVar53( oVar, cMethod, xValue, cType, nSubCode, bValid ) >> Index: source/vm/itemapi.c >> =================================================================== >> RCS file: /cvsroot/xharbour/xharbour/source/vm/itemapi.c,v >> retrieving revision 1.155 >> diff -u -r1.155 itemapi.c >> --- source/vm/itemapi.c 3 Dec 2008 11:09:45 -0000 1.155 >> +++ source/vm/itemapi.c 24 Dec 2008 02:19:44 -0000 >> @@ -1521,14 +1521,19 @@ >> HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemUnShareString(%p)", pItem)); >> >> if( pItem->item.asString.allocated == 0 || >> - hb_xRefCount( pItem->item.asString.value ) > 1 ) >> + *( pItem->item.asString.pulHolders ) > 1 ) >> { >> ULONG ulLen = pItem->item.asString.length + 1; >> char *szText = ( char* ) hb_xgrab( ulLen ); >> >> hb_xmemcpy( szText, pItem->item.asString.value, ulLen ); >> if( pItem->item.asString.allocated ) >> - hb_xRefDec( pItem->item.asString.value ); >> + { >> + if( HB_ATOMIC_DEC( *( pItem->item.asString.pulHolders ) ) == >> 0 ) >> + { >> + hb_xfree( pItem->item.asString.value ); >> + } >> + } >> pItem->item.asString.value = szText; >> pItem->item.asString.allocated = ulLen; >> } >> Index: tests/speedtst.prg >> =================================================================== >> RCS file: /cvsroot/xharbour/xharbour/tests/speedtst.prg,v >> retrieving revision 1.8 >> diff -u -r1.8 speedtst.prg >> --- tests/speedtst.prg 23 Dec 2008 18:06:33 -0000 1.8 >> +++ tests/speedtst.prg 24 Dec 2008 02:19:45 -0000 >> @@ -11,7 +11,6 @@ >> * >> */ >> >> - >> #define N_TESTS 54 >> #define N_LOOPS 1000000 >> #define ARR_LEN 16 >> @@ -241,7 +240,13 @@ >> >> /* initialize mutex in hb_trheadDoOnce() */ >> init proc once_init() >> + set workarea private >> hb_threadOnce() >> + /* initialize error object to reduce possible crashes when two >> + * threads will try to create new error class simultaneously >> + * xHarbour does not have any protection against such situation >> + */ >> + errorNew() >> return >> >> function hb_threadOnce( xOnceControl, bAction ) >> @@ -253,11 +258,11 @@ >> if xOnceControl == NIL >> hb_mutexLock( s_mutex ) >> if xOnceControl == NIL >> - xOnceControl := .t. >> - lFirstCall := .t. >> if bAction != NIL >> eval( bAction ) >> endif >> + xOnceControl := .t. >> + lFirstCall := .t. >> endif >> hb_mutexUnlock( s_mutex ) >> endif >> @@ -275,15 +280,15 @@ >> TEST t003 WITH L_D:=date() CODE x := L_D >> >> TEST t004 INIT _( static s_once, S_C ) ; >> - INIT iif( hb_threadOnce( @s_once ), S_C := dtos(date()), ) ; >> + INIT hb_threadOnce( @s_once, {|| S_C := dtos( date() ) } ) ; >> CODE x := S_C >> >> TEST t005 INIT _( static s_once, S_N ) ; >> - INIT iif( hb_threadOnce( @s_once ), S_N := 112345.67, ) ; >> + INIT hb_threadOnce( @s_once, {|| S_N := 112345.67 } ) ; >> CODE x := S_N >> >> TEST t006 INIT _( static s_once, S_D ) ; >> - INIT iif( hb_threadOnce( @s_once ), S_D := date(), ) ; >> + INIT hb_threadOnce( @s_once, {|| S_D := date() } ) ; >> CODE x := S_D >> >> TEST t007 INIT _( memvar M_C ) INIT _( private M_C := dtos( date() ) ) ; >> @@ -298,19 +303,19 @@ >> TEST t010 INIT _( memvar P_C ) ; >> INIT _( static s_once ) ; >> INIT _( public P_C ) ; >> - INIT iif( hb_threadOnce( @s_once ), P_C := dtos( date() ), ) ; >> + INIT hb_threadOnce( @s_once, {|| P_C := dtos( date() ) } ) ; >> CODE x := P_C >> >> TEST t011 INIT _( memvar P_N ) ; >> INIT _( static s_once ) ; >> INIT _( public P_N ) ; >> - INIT iif( hb_threadOnce( @s_once ), P_N := 112345.67, ) ; >> + INIT hb_threadOnce( @s_once, {|| P_N := 112345.67 } ) ; >> CODE x := P_N >> >> TEST t012 INIT _( memvar P_D ) ; >> INIT _( static s_once ) ; >> INIT _( public P_D ) ; >> - INIT iif( hb_threadOnce( @s_once ), P_D := date(), ) ; >> + INIT hb_threadOnce( @s_once, {|| P_D := date() } ) ; >> CODE x := P_D >> >> TEST t013 INIT _( field F_C ) INIT use_dbsh() EXIT close_db() ; >> >> >> ----- End forwarded message ----- >> >> > > -- > Luis Krause Mantilla > lkrausem at shaw dot ca > luis_krause at hotmail dot com > "May the Source be with GNU" > > > > ------------------------------------------------------------------------------ > Check out the new SourceForge.net Marketplace. > It is the best place to buy or sell services for > just about anything Open Source. > http://p.sf.net/sfu/Xq1LFB > _______________________________________________ > xHarbour-developers mailing list > xHarbour-developers@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/xharbour-developers > ------------------------------------------------------------------------------ Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB _______________________________________________ xHarbour-developers mailing list xHarbour-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/xharbour-developers