2009-03-25 02:49 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/tests/speedtst.prg
    * simplified xHarbour MT test - use mutexes as internal thread IDs
      as workarounds for race conditions in xHarbour .prg MT API.
This commit is contained in:
Przemyslaw Czerpak
2009-03-25 01:43:16 +00:00
parent 5ca4880a55
commit fd62fc0a1b
2 changed files with 25 additions and 65 deletions

View File

@@ -8,6 +8,11 @@
2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
*/
2009-03-25 02:49 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/tests/speedtst.prg
* simplified xHarbour MT test - use mutexes as internal thread IDs
as workarounds for race conditions in xHarbour .prg MT API.
2009-03-24 18:34 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/source/rtl/tbrowse.prg
! fixed Clipper compatibility in configure() action - it does not

View File

@@ -377,7 +377,7 @@ TEST t048 WITH c := repl( dtos( date() ), 5000 ) ;
TEST t049 WITH c := repl( dtos( date() ), 5000 ) ;
INFO "f2( @c[1...40000] )" ;
CODE f2( c )
CODE f2( @c )
TEST t050 WITH c := repl( dtos( date() ),5000 ), c2 ;
INFO "f2( @c[1...40000] ), c2 := c" ;
@@ -732,19 +732,6 @@ return
#ifdef __XHARBOUR__
/* do not expect that this code will work with xHarbour.
* xHarbour has many race conditions which are exploited quite fast
* on real multi CPU machines so it crashes in different places :-(
* probably this code should be forwared to xHarbour developers as
* some type of MT test
*/
/* this define is only to test if emulation function works
* without running real test which causes that xHarbour crashes
*/
//#define _DUMY_XHB_TEST_
static function hb_mutexSubscribe( mtx, nTimeOut, xSubscribed )
local lSubscribed
if valtype( nTimeOut ) == "N"
@@ -760,61 +747,29 @@ return
Notify( mtx, xValue )
return nil
/* in xHarbour there is race condition in JoinThread() which
* fails if thread end before we call it so we cannot use it :-(
* this code tries to simulate it and also add support for thread
* return value
/* In xHarbour there is race condition in JoinThread() which fails if
* thread have ended before call to JoinThread() so we cannot use it.
* Exactly the same problem exists in GetThreadId().
* As workaround we will use mutexes as thread IDs and notify/subscribe
* mechanism to simulate thread join operation and passing thread return
* value.
*/
static function hb_threadStart( ... )
local thId
thId := StartThread( @threadFirstFunc(), hb_aParams() )
/* Just like in JoinThread() the same race condition exists in
* GetThreadId() so we will use HVM thread numbers internally
thId := hb_mutexCreate()
/* For some reasons codeblocks as thread startup entry are broken
* in xHarbour so we use intermediate function instead
*/
#ifdef _DUMY_XHB_TEST_
return val( substr( hb_aParams()[1], 2 ) )
#else
return GetThreadId( thId )
#endif
StartThread( @_thFuncFirst(), thId, hb_aParams() )
return thId
static function hb_threadJoin( thId, xResult )
xResult := results( thId )
return .t.
static function threadFirstFunc( aParams )
local xResult
#ifdef _DUMY_XHB_TEST_
xResult := { "skipped test " + aParams[1], val( substr( aParams[1], 2 ) ) + 0.99 }
results( val( substr( aParams[1], 2 ) ), xResult )
#else
xResult := hb_execFromArray( aParams )
results( GetThreadId(), xResult )
#endif
static function _thFuncFirst( thID, aParams )
Notify( thId, hb_execFromArray( aParams ) )
return nil
static function results( nThread, xResult )
static s_aResults
static s_mutex
if s_aResults == nil
s_aResults := HSetAutoAdd( hash(), .t. )
s_mutex := hb_mutexCreate()
endif
if pcount() < 2
while ! nThread $ s_aResults
Subscribe( s_mutex, 1000 )
enddo
xResult := s_aResults[ nThread ]
else
s_aResults[ nThread ] := xResult
/* We cannot use NotifyAll() here because it will create
* race condition. In this program only one thread join
* results so we can use simple Notify() as workaround
*/
//NotifyAll( s_mutex )
Notify( s_mutex )
endif
return xResult
static function hb_threadJoin( thId, xResult )
xResult := Subscribe( thId )
return .t.
static function hb_threadWaitForAll()
WaitForThreads()
@@ -844,8 +799,8 @@ return
set workarea private
/* initialize mutex in hb_threadOnce() */
hb_threadOnce()
/* initialize error object to reduce possible crashes when two
* threads will try to create new error class simultaneously.
/* initialize error object to reduce to chance for possible crash
* when two threads try to create new error class simultaneously.
* xHarbour does not have any protection against such situation
*/
errorNew()
@@ -862,7 +817,7 @@ return
#endif
INIT PROCEDURE once_init()
/* initialize sync object hb_threadOnce() */
/* initialize sync object in hb_threadOnce() */
hb_threadOnce()
RETURN