On Fri, 19 Sep 2008, Pritpal Bedi wrote: Hi Pritpal,
> Here is the message transcript on xHarbour NG: [...] xHarbour never had have working MT model. There is nothing what even can be called MT model in this language. Just few hacks to create and executes threads but serious problems in core code was never resolved. In many cases not even touched. Evan such basic functionality like safe readonly access to complex variables was implemented few months ago by Walter and only for MS-Win. If you look carefully at xHarbour MT code you will find that from thread startup there are bad race conditions. Lexer, compiler and macro compiler are full of static variables and are not MT safe. here at least there is protection: mutex to block access to macro compiler so only one thread can access it. It means that xHarbour MT programs which extensively use macrocompiler are reduced to single CPU speed and they cannot benefit from multiprocessor machines. There is not protection for class definition which is kept in single memory block and when new class is added this block is resized. Because classes are added dynamically when calls function is called 1-st time then such situation can happen in any moment. It means that executing code which uses object messages is not MT safe be. It can work for some programs but it may also badly crashes - timed dependent race condtion. Instead of redesigning memvars code for MT mode the memvars table was moved to HVM stack as is from MT code. It forces other things. xHarbour has to use thread local memvars and there is no option for memvars sharing. But even this was hacked because code for dynamic symbol table was also used from ST mode without necessary modification. Instead hacks where intorduced. In xHarbour MT mode all memvars are accessed by _name_ not symbols. When thread access asign memvar then to the mamavr name is added prefix: ":TH:" + <thread_id> + ":" and such name is scann in dynamic symbol table. It's performance killer and memory leak because symbol registered in dynamic symbol tables cannot be removed. Beacuse thread uses cyclic IDs repeated from 1 to 32000 (BTW also without protection against non unique values but xHarbour has many such small bugs in MT code) then in long working MT programs using memvars each used PRIVATE and PUBLIC variable will be registered 32000 times in dynamic symbol table. Of course it will not happen because xHarbour will crash. Just simply the maximum number of dynamic symbols will be reached earlier. In sumarry you cannot use memvars in real MT xHarbour programs at all. But it's not all. In the same table as memvars which was made thread local are also kept detached local variables which can be accessed by codeblocks. Such codeblocks can be storred in different places which will be accessible after thread termination. F.e. in one of the worst cases they maybe added to one of class definition. When threads terminates its memvars pool is released by codeblocks which detached local can be still accessible by other threads and so when you try to evaluate them or _even_ delete you will have GPF or other unexpected behavior because freed memory is accessed. It means that they are corrupted forever and xHarbour will GPF on HVM exit when will try to free all alocated items. Result: you cannot use codeblocks with locals in xHarbour MT programs or at least in very limited way _only_ in thread which created them and you have to be sure that all their instances will be removed before threads which created them terminates. In practice all sets in xHarbour are global to application. It means that there is not even way to use safely many things in xHarbour by different threads without bad interactions. F.e. it's not possible that one thread will operate on WA 1 with SET DELETED ON and second one on WA 2 with SET DELETED OFF. It's not MT safe to use CODEPAGEs in WA because for indexing RDDs switching active codepage which is also global program setting not thread dependent, etc. You can imagine all other bad interactions. It means that you cannot use many things safely in xHarbour MT programs. F.e. even operating on different RDDs is not fully MT safe and you have to be very carefull to not change any of global settings. The worka rea in xHarbour are not separated at all. It means that each thread can access the same workare without _ANY_ protections. To not GPF user have to create exclusive access to WA yourself. It means that it have to be protect by user mutex, F.e.: static s_wa1mutex [...] s_wa1mutex := HB_MUTEXCREATE() // INIT [...] HB_MUTEXLOCK( s_wa1mutex ) // LOCK WA [do sth with WA] HB_MUTEXUNLOCK( s_wa1mutex ) // UNLOCK WA [...] It means that in xHarbour WA accessed is reduced to sth what in xbase++ is called zero zone what is also supported by Harbout. Just simply instead of using mutex LOCK/UNLOCK you are using hb_dbDetach() and hb_dbRequest(). F.e. the same code in Harbour may look like: [...] hb_dbDetach( "MYTABLE" ) // INIT [...] hb_waRequest( "MYTABLE" ) // LOCK WA [do sth with WA] hb_waDetach( "MYTABLE" ) // UNLOCK WA [...] The difference is only in protection. In Harbour and xBase user cannot corrupt WA by mistake due to missing warkarea lock because locks are obligatory. In xHarbour they are not obligatory and user any user mistake will corrupt internal RDD structures causing unpredictable results, f.e. data lost or curruption. Farther in xHarbour aliases are global to application so it's not possible to create two independent threads which will use aliases with the same name. You have to change your code to eliminate such situatyions - of course if it's possible. As you can emaigne sometimes it means that you have to rewrite in practice whole code which uses aliases. There are also many other things broken or not implemented in xHarbour MT mode at all. If you are interesting then you can look at xHarbour code. Some easy visible you will finde immediately f.e. s_iBaseLine is static variable in hvm.c global for all threads - it means that line numbering (PROCLINE()) does not work correctly in MT programs. hb_vm_iTry is also static variable used in TRY/CATCH statement. Any functionality related to this variable does not work correctly in MT programs. Such things can be easy fixed but if you will dig deeper then you will find some other much more serious problems. Some of them I described above. Bu not all f.e. in xHarbour destructors uses hack in GC which uses s_bCollecting program global variable. It's not MT safe so xHarbour MT programs cannot use destructors or they may crash in unexpected places or block HVM/GC deadlocking the whole application. In summary if xHarbour developers will want to have really working MT model then they will have to remove most of existing code and implement it from scratch. But 1-st they will have to define how it should work and what are their goals at beginning and cleanup ST HVM resolving long waiting problems and bugs. Otherwise during implementation they will find problems which cannot be easy resolved without changing already written code and they will end with something like they have now. Enough, it's not my job to analyze xHarbour problems on on this list. best regards, Przemek _______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour