On 15 Oct 2010, at 16:31, Andrew Brunner wrote:
On Fri, Oct 15, 2010 at 9:24 AM, Jonas Maebe <jonas.ma...@elis.ugent.be
> wrote:
You replaced a bunch of semaphore create/lock/unlock/destroy
operations with
calls to a function that does not do anything.
I did not. I REMOVED create/destroy/lock/unlock. I ADDED calls to
the ThreadManager's own functions for thread Resume and Suspend.
Yes, that's what I meant, because the ThreadManeger's SuspendThread
function does not do anything under Unix.
Did
you try executing the suspend command? What happened?
First of all, if you use tthread.create(true) (i.e., create a
suspended thread), then the "execute" method will never be called:
***
{$mode delphi}
uses
cthreads, classes, sysutils;
type
tmythread = class(tthread)
procedure execute;override;
end;
procedure tmythread.execute;
begin
writeln('executing');
end;
var
c: tmythread;
begin
writeln('creating thread suspended');
c:=tmythread.create(true);
sleep(500);
writeln('resuming thread');
c.resume;
c.waitfor;
c.free;
end.
***
Currently writes:
creating thread suspended
resuming thread
executing
With the patch, the last line is missing.
Secondly, ignoring this bug and suspending the thread inside itself:
***
{$mode delphi}
uses
cthreads, classes, sysutils;
type
tmythread = class(tthread)
procedure execute;override;
end;
procedure tmythread.execute;
begin
suspend;
writeln('executing');
end;
var
c: tmythread;
begin
writeln('creating thread suspended');
c:=tmythread.create(false);
sleep(500);
writeln('resuming thread');
c.resume;
c.waitfor;
c.free;
end.
***
Currently writes:
creating thread suspended
resuming thread
executing
With the patch:
creating thread suspended
executing
resuming thread
That barrier has nothing to do with "set values of variables before
calling
the inherited create method to their own creation" (although it's not
entirely clear to me you mean by that). If you set values that the
child
thread will read after that thread has already been created, this
memory
barrier will not help either. That barrier is again about memory
write
ordering, which could cause the newly started thread to not see all
writes
performed by the parent thread *before* creating the child thread.
Other than waiting for the values to be committed, I just don't see
it's value.
The whole value is in waiting for the values to be committed. Without
the write barrier, this could e.g. happen:
a) in parent thread
* globalvar:=1;
* create_thread();
b) in child thread:
writeln(gobalvar); // prints 0, or whatever the value of globalvar was
before the parent thread assigned "1" to it
That can even happen on x86 in its default mode, because this is a
"Stores reordered after Loads" situation (but as mentioned below, it's
unlikely to happen).
And the reason that's it's probably not required, is because
there's so much
code in between that it's unlikely that any of those writes would
still be
outstanding at that point. It's not "for the few that don't
understand how
to create a thread".
Exactly. The other code being what?
If you mean the "code in between" by "the other code": any code
executed between setting the global variable in the parent thread and
the actual starting of the child thread (which includes all of the
code in pthread_create, and in case of FPC in tthread.create and/or
BeginThread, although in case of tthread.create there is also some
extra communication between the parent thread and the child thread via
the heap).
Jonas
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal