On Tue, 23 Jun 2009, Maurilio Longo wrote:
Hi,
> > 1-st I would like to check how looks simultaneous execution in xbase++.
> A single line in _out_.txt, with 'waiting 14.47.32' inside. I had to kill it;
> it was on a Core2Duo E6750 with windows xp sp3 and using xbase++ 1.90.331;
It looks like xbase++ serialize access to VM so compiled .prg code can
be executed only by one thread and all others are blocked.
When .prg function starts then it locks VM. When it executes some other
function then it unlocks VM. If executed function is also .prg function
then VM is locked again, etc. Of course it's highly possible that locking
is tuned and it's executed only when function tries to access some non
local variable.
It means that only one thread can execute compiled .prg code and all
others are suspended. Task switching can be done only in some fixed
places, i.e. when some other function is called. There is no automatic
switching. It doesn't matter how much CPU are assigned to the process/
thread. Important is only the fact that execution of compiled .prg code
is serialized. It explains many things, f.e. there is not item write
protection in xbase++. Just simply there is no real MT mode for .prg
code in xbase++ due to above serialization what effectively eliminates
problem with two threads writing to the same item. It cannot happen
for pure .prg code because only one thread can be executed in the same
time and executed thread cannot be automatically changed by OS but only
in some well defined places, i.e. when function is called. The problem
is only with .c code and maybe also with some pure .prg code when
references and/or detached locals are used inside function calls.
I haven't analyzed it yet but I think it may be possible to exploit
some problems using them. Adding protection to pure C code which will
also play well with other code may not be such easy process though
looking xbase++ C API I think that they can use common mutex to .prg
code and accessing (locking) complex items. It means that such C code
is also serialized with other .prg code and slow functions should not
be called items are locked. In such version everything is very simple
but it's not real MT support in my opinion. With the execption to
executing slow C function without lock (f.e. blocking read from pipe
or sockets) I can create such MT mode in Harbour even in DOS without
touching any OS related MT API. Just simply I'll use setjmp() and
longjmp() to create task switching and I'll switch execution context
when function is called from .prg code.
It's even interesting exercise so maybe I will try to implement it
in some spare time.
We can also introduce xbase++ like execution serialization to existing
MT HVM code but IMHO it's rather bad idea. It's serious performance and
functionality reduction.
> during execution task manager shows 7 threads for the process.
Interesting. I guess that they are defined as some type of helper
function. If possible please also check how many threads are created
by program which does not create any new thread and then how many threads
are allocated when new thread is created at .prg level. Is it 6 for each
xbase++ program and then +1 for each new thread?
> > The second thing I would like to test is write access to the same
> > item from different threads.
> It shows the two strings in random order; sometimes several A lines or C lines
> one after the other.
> I've left it running for a while, after which it exited leaving a xppfatal.log
> with an error inside MOM module; during execution it shows 8 threads for the
> process. (on a second run it kept running for a longer while: when I decided
> to stop it I had no error).
So the task switching and internal protection for C code is not enough
to make xbase++ code fully safe for write access and it can fail sometimes
though seems that newer xbase++ versions behaves much better then older ones
and the chance for crash was noticeable reduced.
> PS. As far as I can tell xbase++ can use a single core only; affinity is set
> on startup for cpu0 only. If, from task manager, I set cpu affinity to both
> cores the first sample keeps running, the second freezes as soon as I click
> [ok] inside task manager affinity window (the same for my employer apps, which
> are all compiled with xbase++).
It's possible that xbase++ makes sth like that but probably for some other
reasons, f.e.xbase++ uses some reference counters which are updated without
above VM lock protection by single INC / DEC instructions. Such code is safe
only for single CPU execution because single INC or DEC machine instruction
when data is well aligned cannot be interrupted so it's not possible to
switch execution context to other thread. Anyhow even using single CPU
does not disable automatic context switching by OS. To reach the results
like in test1 above it's necessary to block other thread execution. I guess
that it's done by mutex though in theory it can be also done by explicit
thread suspend/resume calls but it's rather much more inefficient.
Thank you very much for your tests.
best regards,
Przemek
ps. If anyone has some knowledge about xbase++ internals and can verify
my above speculations then I'll be thankful if he can share his opinion.
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour