Re: [Lazarus] thread safe

2011-06-30 Thread Lukasz Sokol
On 29/06/2011 16:11, Michael Schnell wrote:
 On 06/28/2011 08:14 PM, Hans-Peter Diettrich wrote:


 I just found a very nice description of some aspects of thread safety in
 http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_09_08
 titled Thread-Safety.
 Great.
 
 Niche background information on Posix.
 
 But it does not help regarding the issue of defining a thread-safety paradigm 
 for classes.
 

How is the 'thread safety for classses' different from 
thread safety for any other code ?

L.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Hans-Peter Diettrich

Lukasz Sokol schrieb:

On 29/06/2011 16:11, Michael Schnell wrote:

On 06/28/2011 08:14 PM, Hans-Peter Diettrich wrote:


I just found a very nice description of some aspects of thread safety in
http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_09_08
titled Thread-Safety.

Great.

Niche background information on Posix.

But it does not help regarding the issue of defining a thread-safety paradigm 
for classes.



How is the 'thread safety for classses' different from 
thread safety for any other code ?


Thread-safety has many facettes. An item may be safe in one aspect, e.g. 
not using global variables, but unsafe in other aspects.


Objects (classes) add further topics to the list of items, that make up 
thread-safety in general.


During the various discussions I got the impression, that thread-safety 
only can be a headline or keyword, that leads to a detailed description 
of thread-related properties or behaviour of the described item.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Lukasz Sokol
On 30/06/2011 11:14, Hans-Peter Diettrich wrote:
 Lukasz Sokol schrieb:
[...]
 
 How is the 'thread safety for classses' different from thread
 safety for any other code ?
 
 Thread-safety has many facettes. An item may be safe in one aspect,
 e.g. not using global variables, but unsafe in other aspects.

If it is unsafe in other aspects then it is unsafe, right?
(modulo what you actually need, but AFAIR there is not much too pickchoose 
from,
because they are related and some of them imply others ?)

 
 Objects (classes) add further topics to the list of items, that make
 up thread-safety in general.

After compilation, it's just code, isn't it? 
Classes may have the 'hidden' variables but they're not 'hidden' to the
OS/CPU ?

 
 During the various discussions I got the impression, that
 thread-safety only can be a headline or keyword, that leads to a
 detailed description of thread-related properties or behaviour of the
 described item.
 
AFAIR, code (whatever way you write it) can either BE safe or NOT, no
half measyres here - any one of the 'properties' vel 'aspects' not 
complied with, and you can't name your code thread-safe.

It may be a headline or keyword, but it should list ALL the things one
need to be aware of when writing multi-threaded code?

That's my view.

 DoDi
 



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Michael Schnell

On 06/30/2011 10:09 AM, Lukasz Sokol wrote:

On 29/06/2011 16:11, Michael Schnell wrote:
How is the 'thread safety for classses' different from
thread safety for any other code ?

This already has been discussed in this thread previously.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Michael Schnell

On 06/30/2011 01:53 PM, Lukasz Sokol wrote:


After compilation, it's just code, isn't it?
Yep but the programmer that writes the code using an existing object and 
reading it's docs does not see the code after compilation. He is 
inclined to consider the functions of multiple instances of a class to 
be unrelated code which might or might not be appropriate, depending on 
the classes internals. (Or anther programmer thinks the code is related, 
which might in fact be too restrictive.)


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Michael Schnell

On 06/30/2011 01:53 PM, Lukasz Sokol wrote:


AFAIR, code (whatever way you write it) can either BE safe or NOT, no
half measyres here - any one of the 'properties' vel 'aspects' not
complied with, and you can't name your code thread-safe.
A function easily can be thread safe _only_ if a parameter of same is 
different for each thread:


var
 a array [0...10] of Integer;
Function x(i);
begin
  a[i] := a[i] + 1;
end;

A very likely case with the hidden self parameter of class instances.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-30 Thread Hans-Peter Diettrich

Lukasz Sokol schrieb:


Objects (classes) add further topics to the list of items, that make
up thread-safety in general.


After compilation, it's just code, isn't it? 
Classes may have the 'hidden' variables but they're not 'hidden' to the

OS/CPU ?


Objects include information, that may be subject to race conditions, 
deadlocks and other unwanted things. A thread-safe definition for 
procedures covers nothing of what applies to thread-safe objects.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-29 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 2:32 PM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:
 Andrew Brunner schrieb:

 In a bidirectionally linked list up to 4 pointers have to be updated
 together, whenever an element is inserted or removed. This leaves much
 room
 for race conditions, that cannot be cured by protecting every single
 pointer. Instead the entire chain must be protected, by a MUTEX or other
 synchronization means. And then it's only a *convention*, which object or
 memory block shall be protected by a MUTEX, no memory barrier prevents
 access without obtaining the MUTEX first. Kind of a memory barrier can be
 established by putting the list object (head) into a TThreadList,
 *provided
 that* no code will retain references to list elements after releasing the
 list object.

 I had a similar issue once.

 Above is my comment on your example ;-)

The above comment has nothing to do with my example.  My example was
the one with 2 lines of code being executed by two different cores
under the same thread protected within a criticalsection.

My experience though, was shared where I happened to have a memory
barrier in place, and experienced a problem with order or stale values
that was solved by using InterlockedExchange calls.

 Why do you see a need for Interlocked updates, when only one thread can
 access the list at the same time?

Primarily because I want to enforce core cache updates to the values.

 IMO Interlocked updates are fine for self-contained values, where the use of
 critical sections would be overkill. But when multiple variables have to be
 updated without interruption (synchronously, atomically), the entire data
 object should be protected against concurrent access.

 I see it as a matter of coding discipline, and how to make disobedience as
 impossible as possible ;-)


Obedience is not germane to the topic of this particular issue of core
cache and interlockedexhange.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-29 Thread Michael Schnell

On 06/28/2011 08:34 PM, Hans-Peter Diettrich wrote:



Another aspect seems to be the synchronization of *all* data, in *all* 
caches. Is this correct, or do I expect too much?
Not necessary (e.g.) on detecting that a cache line resides in multiple 
caches doing an immediate write back and invalidating for all other 
caches a cache line that is written to in one cache would forces a 
synchronization without too much overhead. AFAIK certain processors 
provide a dedicated fast inter-cache bus for such operations.


I suppose how exactly this is done depends on the CPU manufacturer.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-29 Thread Michael Schnell

On 06/28/2011 08:14 PM, Hans-Peter Diettrich wrote:



I just found a very nice description of some aspects of thread safety in
http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_09_08 


titled Thread-Safety.

Great.

Niche background information on Posix.

But it does not help regarding the issue of defining a thread-safety 
paradigm for classes.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-29 Thread José Mejuto
Hello Lazarus-List,

Wednesday, June 29, 2011, 5:09:22 PM, you wrote:

 *** This one must work
 Thread/core/processor 2
 ---
 while true do begin
Critical.Enter;
if ab then Raise Exception.Create('KBOOM!');
Critical.Leave;
 end;

 If the second one will not work in a n-code processor, or SMP, please
 tell me why not. Of course the performance will be quite poor.
MS Did you experience that it does not work ? IMHO that would be really ban
MS news.

No, exactly the opposite, I do not see how it could fail about memory
order access, cache coherence, ...

-- 
Best regards,
 José


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Mattias Gaertner
On Tue, 28 Jun 2011 04:18:55 +0200
Reimar Grabowski reimg...@web.de wrote:

 On Mon, 27 Jun 2011 18:41:46 -0500
 Andrew Brunner andrew.t.brun...@gmail.com wrote:
 
  This is relatively new theory which required low-level CPU code to
  perform such locks.  This was never needed until the introduction of
  multi-core systems.
 
 Excuse my ignorance but what is different on multi-core systems compared to 
 multi-processor systems which are around for quite some time?

They used a more conservative cache system. A write automatically
invalidated the cache of the other cpus.


Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/27/2011 08:03 PM, Andrew Brunner wrote:


entercricitalsection();
loop
   a:=b+c;
end loop;
leavecriticalsection();

thread 2

can read a and b and c at any state.  If you want an accurate view of
a,b,c you need to employ interlocked statements :-)

Hmm.
In this example, b and c are not modified so in fact any view is 
accurate at a certain point of time. Moreover doing the critical section 
outside of a lop does not make much sense.



A more obvious example would be

Thread 1:

loop
  entercricitalsection();
  a:=a+1;
  b:=b+a;
  leavecriticalsection();
end loop;


Here another thread just fetching a and b could get inconsistent (not 
representing a the same loop) value of a and b.


IMHO if the other thread would do

  entercricitalsection();
  a1:=a;
  a2:=b+a;
  leavecriticalsection();

  write a1 and a2


it will show consistant values.

Here, it is not possible to force consistent values by interlocked 
instructions, as there is no interlocked instruction that does a:=a+1 
and b:=b+a in a single hardware lock. So using the critical section in 
both threads is necessary to force consistency.



An example that can be done with interlocked instructions (and thus 
prevents the huge overhead introduced by a critical section) is


Thread 1:

loop
  a:=a+1;
end loop;

Thread 2:

loop
  a:=a-1;
end loop;

-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 12:31 AM, Andrew Brunner wrote:


2.) Execution Order.
As a critical section is a function call, it prevents instructions are 
re-ordered from being inside of the protected code sequence to being 
outside. And what happens inside the protected code sequence is not 
prone to mutual access anyway.


Please do not odder any analogies but construct a decent example sowing 
how you think something can go wrong and why.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 01:41 AM, Andrew Brunner wrote:

2011/6/27 Malcom Haakinsane...@gmail.com:

In fact in cases
this this the use of CriticalSections would be sensible and

Thread 1:
...
This is relatively new theory which required low-level CPU code to
perform such locks.  This was never needed until the introduction of
multi-core systems.  Of which I did extensive tests on AMD via
FPC/Lazarus.
We are discussing here if a critical would offer data integrity with 
threads or not (without additionally using low level CPU code). Your 
example does not say anything about this.


Of course we all know that in certain cases there are better performing 
option than critical sections (using low level code). But this is not to 
be discussed right now.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 10:48 AM, Michael Schnell wrote:

...
I forgot to mention that the variables a and b need to be defined as 
volatile (mentioning this C-keyword) and thus need to be global/static 
which makes Pascal to handle them as volatile (not cashing them in CPU 
registers). I don't know if/how it in Pascal is possible to define 
stack-variables to be handled as volatile.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Henry Vermaak

On 28/06/11 11:13, Henry Vermaak wrote:

On 27/06/11 23:31, Andrew Brunner wrote:

AMD vs Intel. Kernels Linux vs Windows. The only way to make sure


How does the kernel matter?

Other than the cpu, compilers can also reorder instructions. You can use
__asm__ __volatile__(: : :memory) in c to stop gcc from screwing
around with the order, for example. This is of course if a hardware
memory barrier isn't necessary.


you can get code in proper order with regard to memory assignments (
specifically variables) is to use Interlocked methods. This is why
they were designed.


No. You have to use memory barriers for this. Atomic operations are only
useful for single data elements.


To add to this, on x86 the memory barrier is probably implemented with 
an atomic instruction.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 12:13 PM, Henry Vermaak wrote:


Other than the cpu, compilers can also reorder instructions.
AFAIK modern CPUs can do on the fly instruction reordering and Register 
renaming, but (other than speed) this should be transparent ant not 
detectable when looking at what the CPU actually does.


-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Hans-Peter Diettrich

Marco van de Voort schrieb:

On Mon, Jun 27, 2011 at 03:05:36PM +0100, Hans-Peter Diettrich wrote:

OOP is just a convenient abstraction, it's for people needed only :)

OOP is for designers, not for hackers ;-)

When some thread-safe code must never bring a program (automaton, 
system...) into an inconsistent state, objects are fine to break down 
the entire program into self-contained sub-systems. This allows to 
dramatically reduce the degree of freedom of the entire (flattened) 
problem. Whatever can be done entirely inside an object, deserves no 
further consideration of everything outside the object.


Are you talking about monitors? How else will you force an object with only
one thread in it?

Or are you meaning thread+TLS+state exclusively used in the thread as
object?


I'm not talking specifically about threads here, instead of OOP and 
program design in general. An interactive program is much harder to 
control than a batch-style program with almost sequential control flow. 
When you try to create a state/transition diagram (automaton, state 
machine), with allowed actions and transitions for every possible state, 
then this will be almost impossible for an interactive program (too many 
possible states). When that huge automaton is broken down into 
sub-automatons (objects), with their own internal states and 
transitions, then the overall application will have to respect only a 
fraction of the total possible states. Every object will settle down in 
a limited set of allowed states, and the logic of the main program must 
not deal with the many *intermediate* states, that may occur inside an 
object.


Imagine a file object, that may implement included files, an undo list 
and whatever you like. Such an object includes many sub-objects 
(lists...) and variables (file positions, undo pointers...), which can 
be in very many different states (values). But those states, that are of 
interest to the controlling program, can be restricted to simple 
informations like IsOpen:boolean, and all further validity checks and 
transitions can be encapsulated in the publicly accessible methods 
(actions).


This model can be extended for threads, where a single test for e.g. 
obj.Locked will reveal whether access to *all* of the object's members 
is currently allowed. When such objects know about related objects, that 
will be accessed during some operation (method call), the number of 
these objects will be much lower than the number of variables, that had 
to be locked *individually* before the operation can start. That reduced 
number of dependencies will simplify the implementation of strategies 
for deadlock prevention and resolution.




I've been following this subthread for a couple of posts yet, and the whole
picture leaves an vague feeling.


ACK. Using threads requires more than only TThread objects, which are 
useless without a reliable thread synchronization model, *and* an 
according implementation of this model in application specific code.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:

On Mon, Jun 27, 2011 at 2:51 PM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

Absolutely incorrect.

Why?



Two reasons.

1.) Visibility.  A critical section does not particularly protect
visibility as with 2 threads accessing a piece of memory.


This is exactly what I wanted to say. A critical section does *not* 
enforce a MB (by visibility).



2.) Execution Order.  A critical section does not protect or ensure
that code will be executed in any particular order.


Right. When execution order (race conditions) is of interest, it must be 
established by other means. Here is where deadlocks enter the scene.


I think that you didn't understand what I wanted to say. Hard to tell, 
due to the snipped details you are referring to :-(


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:


This is relatively new theory which required low-level CPU code to
perform such locks.


This is not new. String operations (CMPS...) can be interrupted since a 
long time, and it took some more time until even the single-core CPUs 
could resume such an interrupted instruction correctly.


You're right that CMPXCHG and similar instructions have been missing in 
older instruction sets, but these would have been useful also in 
single-core CPUs with interrupt capabilities. Really new is the need for 
cache synchronization, when multiple processors or cores use their own 
caches, including on-chip (instruction...) caches. But wasn't this 
already of concern in memory-mapped I/O (graphics cards)? Cache look 
aside?


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Mark Morgan Lloyd

Henry Vermaak wrote:

On 27/06/11 23:31, Andrew Brunner wrote:


2.) Execution Order.  A critical section does not protect or ensure
that code will be executed in any particular order.  This is where


How do you know this?  Unfortunately I can't read the code for the 
Windows critical sections and the documentation doesn't explicitly state 
anything, but at least pthread mutex guarantees a memory barrier.  So if 
you're using the fpc rtl critical sections on unix (which uses 
pthread_mutex), your statement is false.


You'll have to read the generated assembler for Windows critical 
sections.  My hunch would be that they use memory barriers, too.


On processors that support them, which I think excludes x86.

My understanding is that in the general case membars are there to 
enforce sanity when a processor can reorder memory accesses. As such 
they don't guarantee anything either way when multiple threads are 
considered on an SMP/multicore system, they're just part of the overall 
picture.


--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 12:44 PM, Hans-Peter Diettrich wrote:


This is exactly what I wanted to say. A critical section does *not* 
enforce a MB (by visibility).
All references I read today say that pthread_mutex (on which supposedly 
TCriticalSection is based) and the appropriate Windows stuff does 
contain an MB. But there might be issues with other OSes and Archs.


If they would not do so, the complete plain old threaded application 
paradigm would be invalid, and tons of applications would need to be 
trashed.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
2011/6/27 Malcom Haak insane...@gmail.com:

 OF WHAT? bad code? It would only look different if you are looking at
 different parts of memory.. or you hadn't finished writing.

Are you serious?

 Also what the hell are you on about? You could use CriticalSections in your
 example and it would work fine. The fact you have one Thread doing nothing
 for ever is a tad silly and to me shows you have no idea what you are
 doing.. but that could be just because of the exceedingly limited scope of
 the example.

You haven't a clue.


 Core X computes a=b+c
 Core X+Y computes a2

 Why would you spilt this into different threads??
 If it is the same thread it does not matter if it moves CPU...
 Your example is lacking in sanity.

This code is written and compiled to execute in thread 1 as per example.

Line T : Core X computes a=b+c
Line T+1 : Core X+Y computes a2

T+1 most likely will be completed before line T is computed!

And it is not poor practice to have threads communicating
reading/writing variables.  Your lack of understanding multi-threaded
systems is evident.

 This is relatively new theory which required low-level CPU code to
 perform such locks.  This was never needed until the introduction of
 multi-core systems.  Of which I did extensive tests on AMD via
 FPC/Lazarus.

 Yeah your just sounding silly here. As per Reimar Grabowski's comment, whats
 the difference between multi-core and Multi-processor?
 I'll tell you... accessibility to people who don't know what they are on
 about.

No.  I speak with experience.  Whether or not you are able to
learn/comprehend what I am illustrating - that is a different matter.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 12:35 PM, Hans-Peter Diettrich wrote:
 *and* an according implementation of this model in application 
specific code.


Yep but the application program should not (need to) be aware of what 
architecture (Processor-Type, SMP,...) it is running on nor know about 
the underlying OS or system libraries (MUETX/FUTEX, ...). For the user 
program, protecting the data structures by TCriticalSection() (if 
necessary according to the description e.g. of the LCL objects it uses) 
should suffice.


If this is not like that, I consider it a bug. Which might not be 
helpful if there is no decent way to cure it. In this case: what 
workaround can be used ?


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 7:40 AM, Michael Schnell mschn...@lumino.de wrote:
 All references I read today say that pthread_mutex (on which supposedly
 TCriticalSection is based) and the appropriate Windows stuff does contain an
 MB. But there might be issues with other OSes and Archs.


Yes, any object that requires atomic features will employ a memory barrier.
That is to say the MB is employed in order for the spincount to be
accurate across all cores.

 If they would not do so, the complete plain old threaded application
 paradigm would be invalid, and tons of applications would need to be
 trashed.

 -Michael

Probably right here.  My engine had worked fine on a tripple core AMD.
 It wasn't until I upgraded to the 6 core system did I have to start
looking into what was causing random problems with pointer
assignments.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Henry Vermaak

On 28/06/11 11:43, Michael Schnell wrote:

On 06/28/2011 12:24 PM, Henry Vermaak wrote:


To add to this, on x86 the memory barrier is probably implemented with
an atomic instruction.



Like MUTEX/FUTEX (and critical section) on the system level all this
needs to be done using atomic (and with SMP bus locking / cache
invalidating) instructions (with no-SMP, disabling the interrupt would
be another system-level option).


Different architectures have specific memory barrier instructions which 
must be used.  For example, arm has DMB, DSB, ISB.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 02:47 PM, Andrew Brunner wrote:
Yes, any object that requires atomic features will employ a memory 
barrier.

That is to say the MB is employed in order for the spincount to be
accurate across all cores.
As for a user program the only way to handle atomic operations is to 
protect them by a MUTEX (TCriticalSection in FPC) and same does include 
the memory barrier we hopefully are safe.

My engine had worked fine on a tripple core AMD.
  It wasn't until I upgraded to the 6 core system did I have to start
looking into what was causing random problems with pointer
assignments.
Of course it might be possible that it just was good luck that it worked 
on the 3-Core (because the bad timing condition did not ever occur). But 
there also might be some bug somewhere.


As said before besides all this complicated stuff the critical variable 
needs to be handled as volatile by the compiler (not caching it in a 
register while opening or closing the critical section). I have no Idea 
how this can be enforced in FPC.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:00 AM, Michael Schnell mschn...@lumino.de wrote:

 As said before besides all this complicated stuff the critical variable
 needs to be handled as volatile by the compiler (not caching it in a
 register while opening or closing the critical section). I have no Idea how
 this can be enforced in FPC.

You are wrong.  There is no complicated stuff.  Just use interlocked
assignments for high performance computing :-)

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:00 PM, Andrew Brunner wrote:

There is no complicated stuff. Just use interlocked
assignments for high performance computing :-)
This is low level stuff and not what user programs are supposed to do. 
User land programs only know Posix as their system interface.


If the performance of Posix is not good enough you can use low level 
interfaces to do very dedicated non portable high performance programs.


But when only using Posix the program should work correctly on all 
systems that provide Posix (including a million core SMP). Otherwise 
somewhere there is a bug.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 8:27 AM, Michael Schnell mschn...@lumino.de wrote:
 On 06/28/2011 03:00 PM, Andrew Brunner wrote:

 There is no complicated stuff. Just use interlocked
 assignments for high performance computing :-)

 This is low level stuff and not what user programs are supposed to do.
 User land programs only know Posix as their system interface.

LOL  All the Interlocked / Compare and Swap statements are included in
the system unit and are readily available and tested (at least on
AMD).

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 03:30 PM, Andrew Brunner wrote:


LOL  All the Interlocked / Compare and Swap statements are included in
the system unit and are readily available and tested (at least on
AMD).

I don't know an IDE called AMD ;-) .

I already did some research and found that on ARM there seem to be 
issues with those.


On X64 there are hardware instructions for these operations, so I 
believe they will work as expected (atomic but not memory ordering).


But if you need to do atomic operations that are moire complex than what 
a single x86 instruction provides, you still need to use MUTEX 
(CriticalSection). And same is bound to work on all systems (including 
SMP) according to the Posix specs.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Hans-Peter Diettrich

Henry Vermaak schrieb:


You'll have to read the generated assembler for Windows critical 
sections.  My hunch would be that they use memory barriers, too.



When a critical section object is owned, the only other threads affected 
are the threads that are waiting for ownership in a call to 
EnterCriticalSection. Threads that are not waiting are free to continue 
running.



I don't see anything like memory barriers here.

DoDi



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Hans-Peter Diettrich

Michael Schnell schrieb:

On 06/27/2011 07:52 PM, Hans-Peter Diettrich wrote:


You forget the strength of protection.

Maybe I seem to see what you mean.

You think, a critical section will not prevent that the data that is 
accessed by both threads is duplicated in a register or in the Data 
cache of the two (or more) CPUs that are trying to access the resource 
(variable).


Big Q: *which* resource?

A critical section (process-local MUTEX) is not related to a specific 
(memory) resource, except itself, consequently it can not protect any 
*other* resource. It also does not block any other thread, not waiting 
for entering the critical section, so that all resources are accessible 
by all threads, except the critical section (or mutex...) itself.



Thus a concurrent access might erroneously offer a not 
updated state to the other CPU.


Right. All threads keep running, except those waiting for a critical 
section in use, so that concurrent access can occur in all threads.



Regarding Data Cache, AFAIK, the hardware prevents this. If one CPU 
writes a value, an invalidate signal for the addresses in that cache 
line is sent to all caches, and so all other CPUs will reread the data 
from the main memory, which in turn will force a preliminary write from 
cache to main memory for the cache line of the first CPU.


An invalidated cache line does not cause a reload from RAM. A reload 
only occurs when the next read will result in an cache miss.



Thus Locked instructions (that force this mechanism, guaranteeing 
proper read-modify-write access even if multiple instructions access the 
same data are issued at the same time overlapping execution ) only are 
necessary outside a critical section protecting the data in question.


That's wrong, since a critical section does not protect any range of 
memory addresses.


A locking instruction most probably will invalidate the address in all 
caches, before reading from or writing to the specified address. Since 
the RAM is locked during the instruction, all other cores or processors 
have to wait until the end of the instruction cycle, before they can 
access the same address.



My conclusion is, that the said problem with linked lists results from 
the pointers not being defined as volatile.


No. In a bidirectionally linked list up to 4 pointers have to be updated 
together, whenever an element is inserted or removed. This leaves much 
room for race conditions, that cannot be cured by protecting every 
single pointer. Instead the entire chain must be protected, by a MUTEX 
or other synchronization means. And then it's only a *convention*, which 
object or memory block shall be protected by a MUTEX, no memory barrier 
prevents access without obtaining the MUTEX first. Kind of a memory 
barrier can be established by putting the list object (head) into a 
TThreadList, *provided that* no code will retain references to list 
elements after releasing the list object.


And I really don't know 
how this could be cured in Pascal other than doing ASM. (I was not aware 
of this problem and I feel it should be discussed in the FPC mailing list.)


It's not a matter of the language, when a thread does *not* aquire a 
lock before accessing the related resource. It's simply a design flaw, 
when some piece of code does not obey the established rules.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:47 AM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

 I don't see anything like memory barriers here.

Compare and swap mechanisms aren't quite like memory barriers but they
to get the CPU to send a fresh copy of a variable to all cores'
cache...

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 05:33 PM, Hans-Peter Diettrich wrote:



A critical section (process-local MUTEX) is not related to a specific 
(memory) resource, except itself, consequently it can not protect any 
*other* resource. It also does not block any other thread, not waiting 
for entering the critical section, so that all resources are 
accessible by all threads, except the critical section (or mutex...) 
itself.

I understand that you are supposed to do

 CriticalSection.Enter;
   do something with the variables that are protected
 CriticalSection.leave;

What did you think how to use them ? Of course a MUTEX can do other 
things, too, but here we are discussing normal CriticalSection use.

-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Henry Vermaak

On 28/06/11 15:47, Hans-Peter Diettrich wrote:

Henry Vermaak schrieb:



You'll have to read the generated assembler for Windows critical
sections. My hunch would be that they use memory barriers, too.


 
When a critical section object is owned, the only other threads affected
are the threads that are waiting for ownership in a call to
EnterCriticalSection. Threads that are not waiting are free to continue
running.


I don't see anything like memory barriers here.


Quoting from 
http://msdn.microsoft.com/en-us/library/ms686355%28v=VS.85%29.aspx


The following synchronization functions use the appropriate barriers to 
ensure memory ordering:


Functions that enter or leave critical sections
Functions that signal synchronization objects
Wait functions
Interlocked functions

Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Michael Schnell

On 06/28/2011 05:33 PM, Hans-Peter Diettrich wrote:


No. In a bidirectionally linked list up to 4 pointers have to be 
updated together, whenever an element is inserted or removed. This 
leaves much room for race conditions, that cannot be cured by 
protecting every single pointer. Instead the entire chain must be 
protected, by a MUTEX or other synchronization means. And then it's 
only a *convention*, which object or memory block shall be protected 
by a MUTEX, no memory barrier prevents access without obtaining the 
MUTEX first. Kind of a memory barrier can be established by putting 
the list object (head) into a TThreadList, *provided that* no code 
will retain references to list elements after releasing the list object.


I fully agree. With the RTL/LCL, the MUTEX is encapsulated in the 
TCtriticalSection Object (one MUTEX per instance. And of course, here, a 
single instance is necessary to be used for all accesses to the 
pointers). And as the Mutex already contains the Full Fence memory 
barrier and (as discussed over in the fpc list) the function calls to 
Enter and Leave prevents the compiler from caching any of the 
intermediate pointer values in registers at a wrong point in time, I 
don't see why CriticalSection would not be the correct way to go and 
work as expected. (OTOH using atomic interlocked ASM  instructions does 
not help as all pointers need to be updated in a single atomic operation).


But the original claim was that the implementation with Critical 
sections failed on a multi core engine and interlocked instructions helped.


This is why I suggested that there is some kind of bug.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 10:33 AM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

 Big Q: *which* resource?

 A critical section (process-local MUTEX) is not related to a specific
 (memory) resource, except itself, consequently it can not protect any
 *other* resource. It also does not block any other thread, not waiting for
 entering the critical section, so that all resources are accessible by all
 threads, except the critical section (or mutex...) itself.

100% correct.  That's what I've been saying.  I think some think that
its some magical solution that protects everything under the sun.

 Thus a concurrent access might erroneously offer a not updated state to
 the other CPU.

 Right. All threads keep running, except those waiting for a critical section
 in use, so that concurrent access can occur in all threads.

Simple semantics.

 Regarding Data Cache, AFAIK, the hardware prevents this. If one CPU writes
 a value, an invalidate signal for the addresses in that cache line is sent
 to all caches, and so all other CPUs will reread the data from the main
 memory, which in turn will force a preliminary write from cache to main
 memory for the cache line of the first CPU.

 An invalidated cache line does not cause a reload from RAM. A reload only
 occurs when the next read will result in an cache miss.

OK folks.  Can we please focus around this comment ??? This is what
makes a piece of memory volatile with respect to threading/cores.  CAS
/ Interlocked mechanisms are the solution to this issue.  But are
there others?

 Thus Locked instructions (that force this mechanism, guaranteeing proper
 read-modify-write access even if multiple instructions access the same data
 are issued at the same time overlapping execution ) only are necessary
 outside a critical section protecting the data in question.

 That's wrong, since a critical section does not protect any range of memory
 addresses.

Ok another focus here.  Lets make the distinction between Thread Locks
and Interlocked/Compare and Swaps here.  Anyone else got anything to
add here?

 A locking instruction most probably will invalidate the address in all
 caches, before reading from or writing to the specified address. Since the
 RAM is locked during the instruction, all other cores or processors have to
 wait until the end of the instruction cycle, before they can access the same
 address.

This is good info.  This is exactly what I observed on my AMD 1075Ts

 My conclusion is, that the said problem with linked lists results from the
 pointers not being defined as volatile.

 No. In a bidirectionally linked list up to 4 pointers have to be updated
 together, whenever an element is inserted or removed. This leaves much room
 for race conditions, that cannot be cured by protecting every single
 pointer. Instead the entire chain must be protected, by a MUTEX or other
 synchronization means. And then it's only a *convention*, which object or
 memory block shall be protected by a MUTEX, no memory barrier prevents
 access without obtaining the MUTEX first. Kind of a memory barrier can be
 established by putting the list object (head) into a TThreadList, *provided
 that* no code will retain references to list elements after releasing the
 list object.

I had a similar issue once.  And it was solved with bringing the list
under my manager/worker system so that there was only one thread
accessing the linkedlist, and I used InterlockedExchange for
First,Last,Next,Previous.

 And I really don't know how this could be cured in Pascal other than doing
 ASM. (I was not aware of this problem and I feel it should be discussed in
 the FPC mailing list.)

 It's not a matter of the language, when a thread does *not* aquire a lock
 before accessing the related resource. It's simply a design flaw, when some
 piece of code does not obey the established rules.

I don't see how this is an issue of obedience.  It's more of a phenomenon.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-28 Thread Andrew Brunner
On Tue, Jun 28, 2011 at 9:59 AM, Michael Schnell mschn...@lumino.de wrote:

 But the original claim was that the implementation with Critical sections
 failed on a multi core engine and interlocked instructions helped.

 This is why I suggested that there is some kind of bug.

LOL  I don't recall you ever asking specifics on my implementation.
You have indeed made gross assumptions regardless of design.

The Engine doesn't have cores.  It's an application written in
Lazarus and proudly compiled with FPC and worked flawlessly on
Windows/Ubuntu32/64 untill I upgraded from a 3 core to a 6 core.
During stress tests - I watched graphically under each core, using AWN
widgets (1 display per core) code execution went from core to core
instead of staying locked.

While my linked list was headed by a critical section, that head was
there only by design for general use and as vestigial for my
particular instance.  Keep in mind, there was no re-entrancy with this
particular link-list instance.
I had headed it with critical sections there for two reasons.

1) it was vestige from a non-adapted - general purpose link list - and
were always allowed access b/c the same thread was accessing.
2) if I ever wanted to re-use the component, I would still need that
thread barrier to block re-entrance.

So to bring this to a conclusion, the Critical section did not ensure
code order of execution when run on the multi-core system.  And by
using InterlockedExhchange we can be assured that variables are valid
to other cores when the event of a core switch occurred - which
resolved the stale values problem I was experiencing.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/23/2011 12:37 AM, Malcom Haak wrote:
Correct me if I'm wrong, But can't you technically make any code 
'thread-safe'  by using Critical Sections before doing work.

Of course you are correct. But this is not a decent way to go.
 1) the calls of CriticalSection themselves can slow down the code, as 
they need library and (unless the Library and the Arch decently 
implements FUTEX) System API calls. And even with FUTEX, hardware-locked 
instructions need to be use that might count for hundreds of normal 
instructions with modern processors due to necessary cache syncing.
 2) if the CriticalSection in fact requires waiting the increase in 
latency is huge. So the calls should be placed only there where they are 
really necessary and the code should be optimized to run as little 
within CriticalSections as possible.


In some code I have seen before a critical section was entered before 
calling TList.Add
Now provided that you don't need a specific order, does this not then 
make it thread safe?

Yes, but in General it's not a decent way to go.

That is why I state that TList (supposedly) already is per-instance 
thread safe and does not need further ado if no concurrent thread 
accesses the same instance.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/23/2011 07:50 AM, Hans-Peter Diettrich wrote:
I may be wrong here, because I used threads only on realtime systems, 
never in Delphi or Lazarus...
Threads can help to greatly improve the soft realtime behavior of a 
Delphi/Lazarus program. We do this a lit.


BTW, I just got my copy of RAD Studio XE, where e.g. thread.suspend is 
deprecated, and other means for thread synchronization are added. But 
these have to be implemented in FPC first, before SpinLock or other 
procedures or methods can be used.


IMHO TThread.Suspend and friends is a very queer way of doing thread 
synchronizing. The Delphi developers seem to have been drunk when 
inventing this (in vain trying to create something idiot-friendly). I 
never used this stuff.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Marco van de Voort
On Thu, Jun 23, 2011 at 06:50:14AM +0100, Hans-Peter Diettrich wrote:
 
 BTW, I just got my copy of RAD Studio XE, where e.g. thread.suspend is 
 deprecated, 

So is FPC 2.4.4.

 and other means for thread synchronization are added.

 Afaik they only added start as a replacements for deprecated .resume.


 But 
 these have to be implemented in FPC first, before SpinLock or other 
 procedures or methods can be used.

These are afaik unrelated to the above change, and related to the addition
of monitors.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread michael . vancanneyt



On Mon, 27 Jun 2011, Michael Schnell wrote:


On 06/23/2011 07:50 AM, Hans-Peter Diettrich wrote:
I may be wrong here, because I used threads only on realtime systems, never 
in Delphi or Lazarus...
Threads can help to greatly improve the soft realtime behavior of a 
Delphi/Lazarus program. We do this a lit.


BTW, I just got my copy of RAD Studio XE, where e.g. thread.suspend is 
deprecated, and other means for thread synchronization are added. But these 
have to be implemented in FPC first, before SpinLock or other procedures or 
methods can be used.


IMHO TThread.Suspend and friends is a very queer way of doing thread 
synchronizing. The Delphi developers seem to have been drunk when inventing 
this (in vain trying to create something idiot-friendly). I never used this 
stuff.


These calls are simply wrappers around the Microsoft threading API. 
So it's the MS engineers who were drunk, I suppose.


Michael.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/23/2011 02:02 PM, Andrew Brunner wrote:


With multi-core systems simply adding a mutex/lock is not enough.
A MUTEX or FUTEX (or CriticalSection) is supposed to work as expected on 
multi-Core systems as well. User code is not supposed to need to bother 
about running on a multi-core system. If MUTEX/FUTEX does not work 
correctly this is a bug of the OS / SystemLibrary.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 11:29 AM, michael.vancann...@wisa.be wrote:


So it's the MS engineers who were drunk, I suppose.

I don't doubt this :-) :-) :-) .

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 22/06/2011 23:37, Malcom Haak wrote:
Correct me if I'm wrong, But can't you technically make any code 
'thread-safe'  by using Critical Sections before doing work. 


I don't think so.

If the function, for example stores some important data in a thread 
local variable, but flags (thread global) the availability of the data, 
then no Critical section will fix it.


Admittedly this is a constructed case, and sounds like an extremely poor 
implementation... But it shows that thread-safety is more than just a 
Critical Section. After execution of a thread-save function the overall 
state of your app (and the entire system) must still be valid (and it 
must be so, for each thread).


Martin


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe [ot]

2011-06-27 Thread Lukasz Sokol
On 27/06/2011 10:31, Michael Schnell wrote:
 On 06/27/2011 11:29 AM, michael.vancann...@wisa.be wrote:

 So it's the MS engineers who were drunk, I suppose.
 I don't doubt this :-) :-) :-) .
 
 -Michael
Must have been something to do with the Ballmer Peak
http://xkcd.com/323/ :)

L.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 11:37 AM, Martin wrote:


If the function, for example stores some important data in a thread 
local variable, but flags (thread global) the availability of the 
data, then no Critical section will fix it.



Yep !

As stated in my former messages in this thread, IMHO, the official 
definition of thread-safe-ness does not make much sense with objects, 
but a more complex definition covering several cases of use is necessary.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 27/06/2011 11:19, Michael Schnell wrote:

On 06/27/2011 11:37 AM, Martin wrote:


If the function, for example stores some important data in a thread 
local variable, but flags (thread global) the availability of the 
data, then no Critical section will fix it.



Yep !

As stated in my former messages in this thread, IMHO, the official 
definition of thread-safe-ness does not make much sense with objects, 
but a more complex definition covering several cases of use is necessary.


Why? Where does the definition conflict with the above?
  A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time


Save invocation includes that the function returns a correct 
result(output) for any input.


Where input:
- is not limited to the parameters passed in the parameter list, not 
even to limited to parameters passed implicitly (such as the object 
instance)
- input includes the entire state of the system (that can be global 
vars, available and unavailable resources of any kind, and much more)

The same applies to result, or output.

This part of Save invocation is not limited to thread safeness. It 
applies to any piece of code.
For example, a piece of code involving memory allocation, must examine 
the result of the actual AllocMem call for errors. Otherwhise it is 
not save to be executed, as it may fail with an undefined result, if no 
mem is available.


So as far as I can see, my example, (as well as objects) are very well 
covered by the definition.


Martin


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 27/06/2011 11:58, Martin wrote:

On 27/06/2011 11:19, Michael Schnell wrote:

On 06/27/2011 11:37 AM, Martin wrote:


If the function, for example stores some important data in a thread 
local variable, but flags (thread global) the availability of the 
data, then no Critical section will fix it.



Yep !

As stated in my former messages in this thread, IMHO, the official 
definition of thread-safe-ness does not make much sense with objects, 
but a more complex definition covering several cases of use is 
necessary.


Why? Where does the definition conflict with the above?
  A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time


Save invocation includes that the function returns a correct 
result(output) for any input.

Make that any defined/allowed input

Obviously if you pass in a pointer to random memory as object instance 
no function will be ave to call.





Where input:
- is not limited to the parameters passed in the parameter list, not 
even to limited to parameters passed implicitly (such as the object 
instance)
- input includes the entire state of the system (that can be global 
vars, available and unavailable resources of any kind, and much more)

The same applies to result, or output.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Lukasz Sokol
On 27/06/2011 11:19, Michael Schnell wrote:
 On 06/27/2011 11:37 AM, Martin wrote:
 
 If the function, for example stores some important data in a thread
 local variable, but flags (thread global) the availability of the
 data, then no Critical section will fix it.
 
 Yep !
 
 As stated in my former messages in this thread, IMHO, the official
 definition of thread-safe-ness does not make much sense with objects,
 but a more complex definition covering several cases of use is
 necessary.
 
 -Michael

The computer/OS/system has no clue of anything you may call 'an object'...
when compiled, it is just 'code'.

OOP is just a convenient abstraction, it's for people needed only :)

L.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 12:51 PM, Martin wrote:


Why? Where does the definition conflict with the above?
  A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time

It does not *conflict* it is just not useful.

The problem is not safe invocation the problem is *a* piece of code.

An object is invocated with a hidden self pointer. So for the user 
this self is not an input as normal parameters are.


By definition, an object is a combination of a data store and a pool of 
functions.


Thus (when looking at your definition above) you either can define that 
(A) the the code is *different* for multiple instances of the object 
(even though it only exists once in memory and in the source code), or 
you can define or you can define that (B) it's *the same piece of code* 
for all instances.


From the point of view of the user both does make sense (if you get him 
to be aware of that at all).


Obviously as an example, the (non-thread-safe) TList.add (supposedly) 
can happily be used with multiple threads if each thread uses it's own 
instance and thus different code (regarding definition (A), while 
TThreadList is thread safe (regarding both definitions) and the same 
instance can be used by multiple threads.


The reason is, that TList just uses (stack and) class variables (and 
decently protected global variables), While with TThreadList 
additionally the class variables are decently protected.


OTOH, e.g. TForm is not thread save at all: you can't do multiple 
instances and use each of them from it's dedicated thread, because 
implicitly TForm uses unprotected global variables.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 27/06/2011 12:23, Michael Schnell wrote:

On 06/27/2011 12:51 PM, Martin wrote:


Why? Where does the definition conflict with the above?
  A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time

It does not *conflict* it is just not useful.

The problem is not safe invocation the problem is *a* piece of code.

An object is invocated with a hidden self pointer. So for the user 
this self is not an input as normal parameters are.


Unfortunately you left out the real important part of my last msg.

If you choose to ignore the full meaning of safely invoked  (even 
WITHOUT threads), then I agree the definition is not useful. But then 
which definition is useful if you ignore parts of it?


Ask yourself: WITHOUT threads, when can a piece of code be safely invoked?
Answer: It can be safely invoked, if it will return a correct result for 
any input, within the range of input for which it is defined.


See my example about memory alloc in my other mail. It shows, that a 
piece of code (and it's ability to be safely invoked ) does not solely 
depend on the parameters passed, but also on (selected parts of) the 
state of the application or system.






By definition, an object is a combination of a data store and a pool 
of functions.

The data part can be seen as input, for the above definition
That this input is made available in a specific way does not matter.

But yes, It's your choice.

You can have an indefinite amount of definitions for each possible 
special case .
Or you can have one definition, using the most abstract common part of 
them all.


For the above it is enough to see an object as a piece of code (or 
several pieces of code), for (each of) which the data is a part of the 
input. It does not matter by which means this input is made available. 
It does not matter that the programmer does not need to explicitly 
specify this input.
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe (concurrently versus subsequently)

2011-06-27 Thread Martin

On 10/06/2011 12:26, Henry Vermaak wrote:

On 10/06/11 02:09, Hans-Peter Diettrich wrote:


What is thread safe?


The definition is very clear here:

http://en.wikipedia.org/wiki/Thread_safety


A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time


Just to point out first, I am aware of the discussion this has already 
sparked, and in the light of any argument of that discussion, in my 
opinion this definition is correct.


Yet I came to think of a case, for which I wonder, and would like to 
hear opinions, if indeed the above statement is complete.

My query is about the part: at the same time

Now a piece of code could for example mix up thread local and thread 
global data:
- cache access to thread local data in a thread global way. Subsequent 
calls from another thread may fail.
- create an initialize some data, and store it thread-local, while 
flagging it's existence thread global. Subsequent calls from another 
thread may fail.
Even if such code was using some sort of locking (mutex, 
criticalsection, ...) it would fail. It would not need to be executed 
from several threads at the same time, it fails if executed by several 
threads subsequently.


However so far of course each of those would also fail, if called at 
the same time. So all my examples are indeed covered by the original 
definition.


The question is, is it prooven, or can it be prooven, that no code can 
be constructed, that would not fail if called at the same time, but 
that would fail if called subsequently
That would be code, for which *during* its execution  the application 
would be in a state valid to enter the code in another thread, but 
*after* it's execution, this validity would no longer be given.


If such code can be constructed, then would the above statement have to 
be extended to subsequent calls of the piece of code ?


Martin
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell
There is no question that we all agree about the technical background of 
all this.


The discussion I started was just about what (new) definitions makes 
sense to be provided in the docs to the user of an Object language to 
allow him to decide which object (e.g. TList vs. TThreadList) he needs 
to use where in his threaded application and what is allowed (e.g. 
accessing multiple TList instances from multiple threads with each 
thread only accessing one of them, or accessing any TThreadList instance 
from any thread) and what is  forbidden (e.g accessing a single TList 
instance from multiple threads or accessing a TForm instance from any 
thread but the MainThread.)


-Michael



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 27/06/2011 13:57, Michael Schnell wrote:

There is no question that we all agree about the technical background
of all this.

The discussion I started was just about what (new) definitions makes
sense to be provided in the docs to the user of an Object language to
allow him to decide which object (e.g. TList vs. TThreadList) he needs
to use where in his threaded application and what is allowed (e.g.
accessing multiple TList instances from multiple threads with each
thread only accessing one of them, or accessing any TThreadList
instance from any thread) and what is  forbidden (e.g accessing a
single TList instance from multiple threads or accessing a TForm
instance from any thread but the MainThread.)


Well, that is something, I can agree with.

*IF* a definition is supplied (with FPC/Lazarus), and in the light that 
the users come with all levels of experience, then it would be nice, if 
(in addition) an explanation would be given, rather than just a short 
abstract form.


In this case your wording may be misleading  just about what (new) 
definitions . There would be no new definition, only an explanation, of 
the existing definition.




--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe (concurrently versus subsequently)

2011-06-27 Thread Mattias Gaertner
 
 


 Martin laza...@mfriebe.de hat am 27. Juni 2011 um 14:47 geschrieben:


  On 10/06/2011 12:26, Henry Vermaak wrote:
   On 10/06/11 02:09, Hans-Peter Diettrich wrote:
  
   
What is thread safe?
   

   The definition is very clear here:
  
  http://en.wikipedia.org/wiki/Thread_safety
  

  A piece of code is thread-safe if it can be safely invoked by multiple
 threads at the same time
 
  Just to point out first, I am aware of the discussion this has already
 sparked, and in the light of any argument of that discussion, in my opinion
 this definition is correct.
 
  Yet I came to think of a case, for which I wonder, and would like to hear
 opinions, if indeed the above statement is complete.
  My query is about the part: at the same time
 
Think about safely invoked as no need for extra precautions to call it multi
threaded, like e.g. critical sections or check which thread is running. 
Obviously thread-safe does not extend the safety nor does it fix any kind of
flaw that is already there when called single threaded. 
And thread safe does not mean that calling a function multi threaded will give
the same results as called single threaded. Although typically it does. 
 
And look up the definition of function. A function is defined by the input,
output and task. Failing means for some input the wrong output is returned.
Input/Output are not only parameters. 
 
 


 
  Now a piece of code could for example mix up thread local and thread global
 data:
  - cache access to thread local data in a thread global way. Subsequent calls
 from another thread may fail.
  - create an initialize some data, and store it thread-local, while flagging
 it's existence thread global. Subsequent calls from another thread may fail.
 
The fail depends on how you define the task of the function.
I guess with fail you mean the function can fail its tasks when called multi
threaded. Then it is by definition not thread safe.
 
 


  Even if such code was using some sort of locking (mutex, criticalsection,
 ...) it would fail. It would not need to be executed from several threads at
 the same time, it fails if executed by several threads subsequently.
 
  However so far of course each of those would also fail, if called at the
 same time. So all my examples are indeed covered by the original definition.
 
  The question is, is it prooven, or can it be prooven, that no code can be
 constructed, that would not fail if called at the same time, but that would
 fail if called subsequently
 
At the same time includes subsequently, for the simple reason that critical
sections are allowed, which simply turns a parallel (at the same time) into a
sequential one. 
 
 


  That would be code, for which *during* its execution  the application would
 be in a state valid to enter the code in another thread, but *after* it's
 execution, this validity would no longer be given.
 
  If such code can be constructed, then would the above statement have to be
 extended to subsequent calls of the piece of code ?


 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Andrew Brunner
On Mon, Jun 27, 2011 at 7:57 AM, Michael Schnell mschn...@lumino.de wrote:
 There is no question that we all agree about the technical background of all
 this.

Actually,

There was no mention of memory barriers other than the content in my
post.  So if you want to understand what that is here is a link...

http://en.wikipedia.org/wiki/Memory_barrier

Simply protecting a loop with a futex is not sufficient.  Assigning
variables in a multi-threaded environment is not sufficient.

Interlocked/Exchange/ExchangeAdd/Increment features must be used
whenever dealing with variables (with at least one exception)  In my
experience arrays of boolean are atomic.

I ran tests on a HexCore AMD system which had unexplained anomalies
with pointers in an bidirectional linked list.  I replaced all the
pointer assignments with InterlockedExchange and the system worked
flawlessly.  Some of the assignments were taking place in a
criticalsection (btw).

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Mattias Gaertner
 
 

 Michael Schnell mschn...@lumino.de hat am 27. Juni 2011 um 14:57 geschrieben:

  There is no question that we all agree about the technical background of
  all this.
 
  The discussion I started was just about what (new) definitions makes
  sense to be provided in the docs to the user of an Object language to
  allow him to decide which object (e.g. TList vs. TThreadList) he needs
  to use where in his threaded application and what is allowed (e.g.
  accessing multiple TList instances from multiple threads with each
  thread only accessing one of them, or accessing any TThreadList instance
  from any thread) and what is  forbidden (e.g accessing a single TList
  instance from multiple threads or accessing a TForm instance from any
  thread but the MainThread.)
 The documentation can simply say about TList:
 Thread safe: no
 Used non thread safe global variables: none

 About TAVLTree:
 Thread safe: no
 Used non thread safe global variables: NodeMemManager, unless overriden by
SetNodeManager

 No need for new terms. And everyone knows what to do to use the class in a
specific thread.

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Hans-Peter Diettrich

Martin schrieb:

As stated in my former messages in this thread, IMHO, the official 
definition of thread-safe-ness does not make much sense with objects, 
but a more complex definition covering several cases of use is necessary.


Why? Where does the definition conflict with the above?
  A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time


That's the definition of reentrant subroutines only.

Save invocation includes that the function returns a correct 
result(output) for any input.


Where input:
- is not limited to the parameters passed in the parameter list, not 
even to limited to parameters passed implicitly (such as the object 
instance)
- input includes the entire state of the system (that can be global 
vars, available and unavailable resources of any kind, and much more)

The same applies to result, or output.


This would mean that a thread-safe procedure has to lock *all* input 
that it - or one of its called procedures - wants to read or update, 
before starting at all. The best scenario for an unrecoverable deadlock :-(


This part of Save invocation is not limited to thread safeness. It 
applies to any piece of code.


Your attempt to re-interpret above definition is of no use :-(

DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Hans-Peter Diettrich

Lukasz Sokol schrieb:


The computer/OS/system has no clue of anything you may call 'an object'...
when compiled, it is just 'code'.


Right.


OOP is just a convenient abstraction, it's for people needed only :)


OOP is for designers, not for hackers ;-)

When some thread-safe code must never bring a program (automaton, 
system...) into an inconsistent state, objects are fine to break down 
the entire program into self-contained sub-systems. This allows to 
dramatically reduce the degree of freedom of the entire (flattened) 
problem. Whatever can be done entirely inside an object, deserves no 
further consideration of everything outside the object.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 03:31 PM, Andrew Brunner wrote:

Simply protecting a loop with a futex is not sufficient.  Assigning
variables in a multi-threaded environment is not sufficient.
While I don't think we should this discuss in this context, I suggest 
that in the docs for the user of the object library (that was the 
starting point of the discussion), any type of thread-safety should 
include threads running on multiple processors.

Interlocked/Exchange/ExchangeAdd/Increment features must be used
whenever dealing with variables (with at least one exception)  In my
experience arrays of boolean are atomic.
Yep. But this is only relevant if you don't protect them by a critical 
section, as this excludes concurrent exchange before the critical 
instructions are executed. Of course (when possible) using the 
interlocked instruction results in a lot less overhead than simply using 
a critical section.

I ran tests on a HexCore AMD system which had unexplained anomalies
with pointers in an bidirectional linked list.  I replaced all the
pointer assignments with InterlockedExchange and the system worked
flawlessly.
This is clear. You also would have been able to avoid the problem by 
using critical sections around *all *the appropriate instructions, but 
supposedly this would have slowed done the application greatly.

  Some of the assignments were taking place in a
criticalsection (btw).

I believe that the some were not enough.

-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 03:34 PM, Mattias Gaertner wrote:



The documentation can simply say about TList:
Thread safe: no
Used non thread safe global variables: none

Poor user !
If he just reads Thread safe: no, he supposedly will believe he needs to 
use TThreadList in all threads and do very inefficient code.
How is he supposed to know that accessing a TList instance with just a 
single thread while accessing another instance only with another thread 
is safe ?


A new term (decently explained on a central location) that can be used 
in a Feature grid would be much more readable.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe (concurrently versus subsequently)

2011-06-27 Thread Martin

On 27/06/2011 14:23, Mattias Gaertner wrote:





What is thread safe?


The definition is very clear here:

http://en.wikipedia.org/wiki/Thread_safety


A piece of code is *thread-safe* if it can be safely invoked by 
multiple threads at the same time


Just to point out first, I am aware of the discussion this has 
already sparked, and in the light of any argument of that discussion, 
in my opinion this definition is correct.


Yet I came to think of a case, for which I wonder, and would like to 
hear opinions, if indeed the above statement is complete.
My query is about the part: at the same time 


Think about safely invoked as no need for extra precautions to call 
it multi threaded, like e.g. critical sections or check which thread 
is running.


Obviously thread-safe does not extend the safety nor does it fix any 
kind of flaw that is already there when called single threaded.


And thread safe does not mean that calling a function multi threaded 
will give the same results as called single threaded. Although 
typically it does.


And look up the definition of function. A function is defined by the 
input, output and task. Failing means for some input the wrong output 
is returned. Input/Output are not only parameters.




Yes, but if I am correct, input for example can not (always) be 
limited to the list of param (not even including hidden param, like self)
eg, a constructor, includes the task of allocating memory. If that fails 
a defined behaviour should be expected (return nil, throw exception, 
...). That implies, that available memory in this case is part of the 
input.


Sure, similar flaws (with invalid data) can be constructed outside 
threads. But the ability to store data in either a variable local to one 
thread, or global to all threads does not exists without threads.


Yes the aim of the definition, is solely to extend the concept of being 
called safely to being called safely from several threads.
But the above definition *limits* this requirement to called at the 
same time





Now a piece of code could for example mix up thread local and thread 
global data:
- cache access to thread local data in a thread global way. 
Subsequent calls from another thread may fail.
- create an initialize some data, and store it thread-local, while 
flagging it's existence thread global. Subsequent calls from another 
thread may fail. 


The fail depends on how you define the task of the function.

I guess with fail you mean the function can fail its tasks when 
called multi threaded. Then it is by definition not thread safe.




As I said, those examples, are not actually correct (for what I am 
questioning) They only point into a direction.


fail = not the result that is expected according to the definition of 
the function (that could be: not return at all, crash, or return an 
incorrect value as result...)


The example is merely to indicate, that thread related problems can 
occur, even if calls are not at the same time.


Yes similar issues can be constructed without threads. But without 
threads you do not have a differentiation between data accessible to 
just one thread, and data accessible to all threads. So problems arising 
from this, are thread related.


Even if such code was using some sort of locking (mutex, 
criticalsection, ...) it would fail. It would not need to be executed 
from several threads at the same time, it fails if executed by 
several threads subsequently.


However so far of course each of those would also fail, if called at 
the same time. So all my examples are indeed covered by the original 
definition.


The question is, is it prooven, or can it be prooven, that no code 
can be constructed, that would not fail if called at the same time, 
but that would fail if called subsequently 


At the same time includes subsequently, for the simple reason that 
critical sections are allowed, which simply turns a parallel (at the 
same time) into a sequential one.




There is a difference between called/invoked at the same time, and 
executed at the same time.


The original defintion says invoked they are still invoked at the same 
time, even though *if* a critical section is used, the part inside it 
(and only this part, not the whole piece of code, which includes the 
critical section) is executed deferred.


at the same time does not necessarily mean a critical section has to 
exist, there are other means that allow for more parallel execution:
 2 read only calls, may not need to block each other at all. Yet a 
read-only  call may fail due to something thread related, that happened 
long before (in an other thread, and only because it happened in an 
other thread).


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe (concurrently versus subsequently)

2011-06-27 Thread Mattias Gaertner
 
 


 Martin laza...@mfriebe.de hat am 27. Juni 2011 um 16:01 geschrieben:
 [...]
 
  Think about safely invoked as no need for extra precautions to call it
  multi threaded, like e.g. critical sections or check which thread is
  running. 
  Obviously thread-safe does not extend the safety nor does it fix any kind
  of flaw that is already there when called single threaded. 
  And thread safe does not mean that calling a function multi threaded will
  give the same results as called single threaded. Although typically it
  does. 
   
  And look up the definition of function. A function is defined by the
  input, output and task. Failing means for some input the wrong output is
  returned. Input/Output are not only parameters.
  

  Yes, but if I am correct, input for example can not (always) be limited to
 the list of param (not even including hidden param, like self)
  eg, a constructor, includes the task of allocating memory. If that fails a
 defined behaviour should be expected (return nil, throw exception, ...). That
 implies, that available memory in this case is part of the input.
In fact a function's input can even be a file on disk. 
The memory manager is thread safe, so there is not much difference between
single threaded and multi threaded here. 
 
 


 
  Sure, similar flaws (with invalid data) can be constructed outside threads.
 But the ability to store data in either a variable local to one thread, or
 global to all threads does not exists without threads.
Well, this depends on pov. So this is more a philosophical question. 
 


 
  Yes the aim of the definition, is solely to extend the concept of being
 called safely to being called safely from several threads.
  But the above definition *limits* this requirement to called at the same
 time
English lacks the exactness of mathematical expressions.  
You are right, that the definition is not exact and the wikipedia page contains
a few remarks about that.
The nice thing about this definition is that everyone I knew instantly
understands the idea and was able to apply it to most cases without much
thinking, including methods and classes. Everyone - until I read this thread.
Apparently some people have problems with it. Well, life is learning. 
 
 


 
  
  The fail depends on how you define the task of the function.
  I guess with fail you mean the function can fail its tasks when called
  multi threaded. Then it is by definition not thread safe.
  

 
  As I said, those examples, are not actually correct (for what I am
 questioning) They only point into a direction.
 
  fail = not the result that is expected according to the definition of the
 function (that could be: not return at all, crash, or return an incorrect
 value as result...)
 
Then the function is not thread safe. 
 


 
  The example is merely to indicate, that thread related problems can occur,
 even if calls are not at the same time.
True.  
And I would like to discuss this, but I'm not sure if this topic is Lazarus
related. 

 


  [...]
  
  At the same time includes subsequently, for the simple reason that
  critical sections are allowed, which simply turns a parallel (at the same
  time) into a sequential one.
  

  There is a difference between called/invoked at the same time, and executed
 at the same time.
For thread safe it is the same. 
 
 


 
  The original defintion says invoked they are still invoked at the same
 time, even though *if* a critical section is used, the part inside it (and
 only this part, not the whole piece of code, which includes the critical
 section) is executed deferred.
 
  at the same time does not necessarily mean a critical section has to exist,
 there are other means that allow for more parallel execution:
   2 read only calls, may not need to block each other at all. Yet a read-only 
 call may fail due to something thread related, that happened long before (in
 an other thread, and only because it happened in an other thread).
 
 
Yes. But then again it is a question of how you define the task of the code.
Maybe you want this behavior, maybe you don't care. 
 
 
Mattias
 --
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 04:17 PM, Andrew Brunner wrote:

See the link at wikipedia.

I don't think Wikipedia can explain implementation details of the LCL/RTL..

But if TCriticalSection uses a MUTEX (which in fact is a FUTEX as (on 
Linux) it uses pthreadlib mutex function from LibC, which automatically 
uses FUTEX if available in the underlying arch, otherwise fallback to 
MUTEX) (and I believe it is implemented this way) same blocks all at the 
start of the section independently from the core they run on, and thus 
no concurrent access can happen.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Hans-Peter Diettrich

Martin schrieb:

See my example about memory alloc in my other mail. It shows, that a 
piece of code (and it's ability to be safely invoked ) does not solely 
depend on the parameters passed, but also on (selected parts of) the 
state of the application or system.


What when some code does not return anything, *and* cannot work at all 
due to some problem (out-of-memory, file deleted, object destroyed...)?


When e.g. a file search cannot proceed due to missing access rights? It 
cannot return an boolean value (succ/fail), because it's simply unknown 
whether the file exists.


When in case of an unexpected error the called procedure throws an 
exception? Can this procedure *ever* be safely invoked, when it may 
return to some other place in code (exception handler)?


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:


I ran tests on a HexCore AMD system which had unexplained anomalies
with pointers in an bidirectional linked list.  I replaced all the
pointer assignments with InterlockedExchange and the system worked
flawlessly.  Some of the assignments were taking place in a
criticalsection (btw).


Here I feel a need for clarification of CriticalSection in general.

Can multiple critical sections be used in a program, to protect 
*specific* resources? Is it wise to do so?


How can critical sections prevent concurrent access to a resource, when 
*not* entered as required?



Your observation suggests to me that there existed some other code, 
accessing the list *without* entering the (related) critical section. 
This would mean that *no* code can be thread-safe by itself, instead it 
requires *also* that all other code respects resource protection 
(aquire/release locks).


AFAIR TThreadList is thread-safe, because it requires to obtain (and 
lock) an object, before it becomes accessible at all. This definitely 
prevents all other code from accessing the protected object - provided 
there exist no other references to such an object outside the list. But 
this is no guarantee that the object itself will be protected against 
concurrent access to *further* resources.



My conclusion: thread-safety can be achieved only for items (procedures, 
objects) which do not use non-local data at all. Otherwise thread-safety 
can be achieved only by sequentializing *all* critical operations in an 
process - but then we effectively are back to single-threaded code, with 
only a bit more of noise in switching the active thread in random 
sequence :-(


When consequently thread-safe code is entirely up to the proper use of 
synchronization means, what's the use of sticking an thread-safe 
attribute to anything but an entire program?


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Andrew Brunner
You're totally underestimating the need for a memory barrier :

Multithreaded programming and memory visibility

See also: Memory model (computing)
Multithreaded programs usually use synchronization primitives provided
by a high-level programming environment, such as Java and .NET
Framework, or an application programming interface (API) such as POSIX
Threads or Windows API. Primitives such as mutexes and semaphores are
provided to synchronize access to resources from parallel threads of
execution. These primitives are usually implemented with the memory
barriers required to provide the expected memory visibility semantics.
In such environments explicit use of memory barriers is not generally
necessary. 

Focus on the These primitives are usually implemented with the memory
barriers required to provide the expected memory visibility semantics.


These primitives include TCrticialSection.  It's not enough to ensure
that someone from another thread is reading a variable at will.  And
it would safe to assume that CPU management systems can switch code
execution on any core at any time.

On Mon, Jun 27, 2011 at 9:47 AM, Michael Schnell mschn...@lumino.de wrote:
 On 06/27/2011 04:17 PM, Andrew Brunner wrote:

 See the link at wikipedia.

 I don't think Wikipedia can explain implementation details of the LCL/RTL..

 But if TCriticalSection uses a MUTEX (which in fact is a FUTEX as (on Linux)
 it uses pthreadlib mutex function from LibC, which automatically uses FUTEX
 if available in the underlying arch, otherwise fallback to MUTEX) (and I
 believe it is implemented this way) same blocks all at the start of the
 section independently from the core they run on, and thus no concurrent
 access can happen.


Semantically Ok.  Poor code performance though..  If you had 1
CriticalSection per instance of a variable you possibly could make
this argument... But it's just easier and FAAASTER to use interlocked
statements ;-)  Locking a thread is poor practice.  Just design it
well and you won't have to worry about locking much.  And wherever
possible use interlocked features - they were designed for this issue
alone.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 04:15 PM, Mattias Gaertner wrote:


A new term would need explanation too.
Yep. In a central location, so the feature lists for the objects is not 
polluted.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Martin

On 27/06/2011 15:58, Hans-Peter Diettrich wrote:

Martin schrieb:

See my example about memory alloc in my other mail. It shows, that a 
piece of code (and it's ability to be safely invoked ) does not 
solely depend on the parameters passed, but also on (selected parts 
of) the state of the application or system.


What when some code does not return anything, *and* cannot work at all 
due to some problem (out-of-memory, file deleted, object destroyed...)?


When e.g. a file search cannot proceed due to missing access rights? 
It cannot return an boolean value (succ/fail), because it's simply 
unknown whether the file exists.


When in case of an unexpected error the called procedure throws an 
exception? Can this procedure *ever* be safely invoked, when it may 
return to some other place in code (exception handler)?


Yes, why not. IF this is the defined behaviour. Exceptions can be 
caught. To safely call such a function one would need to define an 
exception handler. But it can be safely called.


That a function can be safely called does not mean that there is no way 
to call it unsafely.


A function expecting a pointer to some specific data, may be able to 
check if the pointer is nil, but it can not necessarily check if the 
pointer is otherwise valid.
Hence input range for which the function is defined, is a pointer that 
is nil, or pointing to the correct type of data. Within this range of 
input the function may be called and will be safe, with other input the 
result of calling the function is not defined, hence it is not safe.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Michael Schnell

On 06/27/2011 04:58 PM, Andrew Brunner wrote:

You're totally underestimating the need for a memory barrier :
While I do know that memory barriers are the way to go to avoid the 
expensive use of Mutex and friends, I am positive that an MB is not 
necessary if all accesses to something are protected by a Mutex, as same 
is designed to block any thread independently from the CPU it is running 
on. so no other thread can even try to access that memory location. (we 
are not discussing how to construct a Mutex/FUTEX internally).

Focus on the These primitives are usually implemented with the memory
barriers ...

Yep, usually as critical sections are much more expensive.

-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Mattias Gaertner
 
 

 Hans-Peter Diettrich drdiettri...@aol.com hat am 27. Juni 2011 um 16:58
geschrieben:

  Martin schrieb:
 
   See my example about memory alloc in my other mail. It shows, that a
   piece of code (and it's ability to be safely invoked ) does not solely
   depend on the parameters passed, but also on (selected parts of) the
   state of the application or system.
 
  What when some code does not return anything, *and* cannot work at all
  due to some problem (out-of-memory, file deleted, object destroyed...)?
 
  When e.g. a file search cannot proceed due to missing access rights? It
  cannot return an boolean value (succ/fail), because it's simply unknown
  whether the file exists.
 
  When in case of an unexpected error the called procedure throws an
  exception? Can this procedure *ever* be safely invoked, when it may
  return to some other place in code (exception handler)? 
Yes, if raising an IO exception is a valid output. 

 
Mattias
 --
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Lukasz Sokol
On 27/06/2011 15:05, Hans-Peter Diettrich wrote:
 Lukasz Sokol schrieb:
 
 The computer/OS/system has no clue of anything you may call 'an
 object'... when compiled, it is just 'code'.
 
 Right.
 
 OOP is just a convenient abstraction, it's for people needed only
 :)
 
 OOP is for designers, not for hackers ;-)
 
 When some thread-safe code must never bring a program (automaton,
 system...) into an inconsistent state, objects are fine to break down
 the entire program into self-contained sub-systems. This allows to
 dramatically reduce the degree of freedom of the entire (flattened)
 problem. Whatever can be done entirely inside an object, deserves no
 further consideration of everything outside the object.

What I meant (and I think) it is, is that whatever thread-safe *is*, 
is completely orthogonal i.e. not dependent on your programming 
paradigm, it is completely about the resulting code.
Therefore, *result* code can either be thread safe, or it can not be, 
there is no shades of gray here, whatever complex paradigms you apply 
to your language :)

(somebody correct me if I'm not correct ;)
L.

 
 DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Andrew Brunner
On Mon, Jun 27, 2011 at 12:52 PM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:
 You forget the strength of protection. A MB will disallow immediately any
 concurrent access to the memory area - no way around. Protection by other
 means only can work in *perfect* cooperation, a very weak model.

Absolutely incorrect.

entercricitalsection();
loop
  a:=b+c;
end loop;
leavecriticalsection();

thread 2

can read a and b and c at any state.  If you want an accurate view of
a,b,c you need to employ interlocked statements :-)

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Hans-Peter Diettrich

Andrew Brunner schrieb:

On Mon, Jun 27, 2011 at 12:52 PM, Hans-Peter Diettrich
drdiettri...@aol.com wrote:

You forget the strength of protection. A MB will disallow immediately any
concurrent access to the memory area - no way around. Protection by other
means only can work in *perfect* cooperation, a very weak model.


Absolutely incorrect.


Why?


entercricitalsection();


Where do you see a memory barriere here?

DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Marco van de Voort
On Mon, Jun 27, 2011 at 03:05:36PM +0100, Hans-Peter Diettrich wrote:
  OOP is just a convenient abstraction, it's for people needed only :)
 
 OOP is for designers, not for hackers ;-)
 
 When some thread-safe code must never bring a program (automaton, 
 system...) into an inconsistent state, objects are fine to break down 
 the entire program into self-contained sub-systems. This allows to 
 dramatically reduce the degree of freedom of the entire (flattened) 
 problem. Whatever can be done entirely inside an object, deserves no 
 further consideration of everything outside the object.

Are you talking about monitors? How else will you force an object with only
one thread in it?

Or are you meaning thread+TLS+state exclusively used in the thread as
object?

I've been following this subthread for a couple of posts yet, and the whole
picture leaves an vague feeling.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Reimar Grabowski
On Mon, 27 Jun 2011 18:41:46 -0500
Andrew Brunner andrew.t.brun...@gmail.com wrote:

 This is relatively new theory which required low-level CPU code to
 perform such locks.  This was never needed until the introduction of
 multi-core systems.

Excuse my ignorance but what is different on multi-core systems compared to 
multi-processor systems which are around for quite some time?

R.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-27 Thread Malcom Haak
On Tue, Jun 28, 2011 at 9:41 AM, Andrew Brunner
andrew.t.brun...@gmail.comwrote:

 2011/6/27 Malcom Haak insane...@gmail.com:
  Tell me then why any of what you have said is relevant. In fact in cases
  this this the use of CriticalSections would be sensible and would not
 cause
  'tons of wait' as you have all your worker threads off doing things 99%
 of
  the time.

 Firstly, I was referring to my example



 Thread 1:
 a=b+c
 a2=a+c2
 SignalEvent(E1)

 This will run in 1 thread.. if you use local variables this is fine. if you
were using global variables you are an idiot.


 Thread 2:
  repeat
  WaitForEvent(E1,120);
We can read anything now
  until terminated or complete


This the prime example.  On a 6 core system a looks like one value to
 one core than it does to another core.  It's that simple.  No getting
 around this issue.

 OF WHAT? bad code? It would only look different if you are looking at
different parts of memory.. or you hadn't finished writing.


 While spinlocks can block a entrance - it cannot guarantee memory
 order / code execution order.  Therefore it is good practice to adopt
 interlocked assignments to guarantee memory is what it is.

 Also what the hell are you on about? You could use CriticalSections in your
example and it would work fine. The fact you have one Thread doing nothing
for ever is a tad silly and to me shows you have no idea what you are
doing.. but that could be just because of the exceedingly limited scope of
the example.



 Core X computes a=b+c
 Core X+Y computes a2

 Why would you spilt this into different threads??
If it is the same thread it does not matter if it moves CPU...
Your example is lacking in sanity.


 This is relatively new theory which required low-level CPU code to
 perform such locks.  This was never needed until the introduction of
 multi-core systems.  Of which I did extensive tests on AMD via
 FPC/Lazarus.

 Yeah your just sounding silly here. As per Reimar Grabowski's comment,
whats the difference between multi-core and Multi-processor?
I'll tell you... accessibility to people who don't know what they are on
about.

 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-23 Thread Andrew Brunner
2011/6/22 Malcom Haak insane...@gmail.com:
 Correct me if I'm wrong, But can't you technically make any code
 'thread-safe'  by using Critical Sections before doing work.
 In some code I have seen before a critical section was entered before
 calling TList.Add
 Now provided that you don't need a specific order, does this not then make
 it thread safe?


Partially.  Read barriers may not be necessary.  It depends on the
implementation.  By having barriers placed at strategic locations in
the code, you can make an implementation thread safe.

Add, Delete, and Clear would be some.  List iterations would be
difficult if not unsafe outside a lock but if accessed under a manager
thread you can schedule and operation and it will wait done until
conditions are safe to perform.

Getting an item from the list rather than locking the entire list and
having an inUse boolean set to true for that item, would allow for any
deletion to be blocked until another time (by a manager thread).

With multi-core systems simply adding a mutex/lock is not enough.  A
manager is needed to be in place to safely provision, delegate, and
use items.  IMO, this forces efficiency in a system design.  The basic
logic for a manager thread is that the manager thread is accepting
commands, and scheduled execution happens automatically.

Further, you could create a command system for each list so when you
add/remove an item from the list you are merely scheduling that item
for deletion. I would avoid polling for large lists.  The command
should have a completion routine like Item.onComplete(Item) where the
item is passed for use in the application.

This way there would be absolutely no waiting for data in code and the
system in general at rest until needed.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-22 Thread Hans-Peter Diettrich

Malcom Haak schrieb:
Correct me if I'm wrong, But can't you technically make any code 
'thread-safe'  by using Critical Sections before doing work. 
In some code I have seen before a critical section was entered before 
calling TList.Add


IMO this won't help, because any other thread that does *not* use the 
critical section still can trash the list.


It might help when TList.Add would use a critical section internally, 
but then *all* lists are blocked at once, unless a critical section is 
connected to *every* single TList instance - what may run into 
out-of-resources. Otherwise a global TList.Add lock may lock up an 
entire application, when an OnAdd handler tries to use another 
(temporary...) TList.


IMO. I may be wrong here, because I used threads only on realtime 
systems, never in Delphi or Lazarus...



BTW, I just got my copy of RAD Studio XE, where e.g. thread.suspend is 
deprecated, and other means for thread synchronization are added. But 
these have to be implemented in FPC first, before SpinLock or other 
procedures or methods can be used.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Mattias Gaertner
On Tue, 14 Jun 2011 11:53:14 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 06/10/2011 06:09 PM, Mattias Gaertner wrote:
 
  Sigh. It already does. See my TThreadList.Add example.
 This example shows that it does not make sense.
 
 (Supposedly) TThreadList.Add is separate-instance-thread safe (each thread 
 can create an instance and use the Add procedure without risking a 
 conflict).
 
 TThreadList.Add is not cross-instance-thread safe (multiple threads using 
 the same instance's Add procedure will result in erroneous behavior).

Why do you think so?

 
 Simply stating that TThreadList.Add is not thread save (which of course is 
 perfectly correct) would prevent using a TThreadList as a data store e.g. in 
 a thread class that itself is instantiated multiple times. There using 
 TThreadList would be overkill.


Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Henry Vermaak

On 14/06/11 10:53, Michael Schnell wrote:

On 06/10/2011 06:09 PM, Mattias Gaertner wrote:


Sigh. It already does. See my TThreadList.Add example.

This example shows that it does not make sense.

(Supposedly) TThreadList.Add is separate-instance-thread safe (each
thread can create an instance and use the Add procedure without
risking a conflict).


Everything is separate-instance-thread safe.  How can something be 
unsafe if only one thread is accessing it?



TThreadList.Add is not cross-instance-thread safe (multiple threads
using the same instance's Add procedure will result in erroneous
behavior).


No, it won't.  All the operations lock the list, so you can use the same 
instance from multiple threads.  Just read the source before you make 
misguided comments like this.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Michael Schnell

On 06/14/2011 12:02 PM, Mattias Gaertner wrote:

Why do you think so?
Sorry I have been typing much faster than thinking here (again). I had 
meant to be talking about TTlist. :-[ :-[ :-[


So once again:



(Supposedly) TList.Add is separate-instance-thread safe (each thread 
can create an instance and use the Add procedure without risking a 
conflict).


TList.Add is not cross-instance-thread safe (multiple threads using 
the same instance's Add procedure will result in erroneous behavior).


Simply stating that TList.Add is not thread save (which of course is 
perfectly correct) would prevent using a TList instance as a data store 
e.g. in a thread class that itself is instantiated multiple times. There 
using TThreadList would be overkill.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Michael Schnell


Everything is separate-instance-thread safe.  How can something be 
unsafe if only one thread is accessing it?
As soon as you use global variables. E.G. Application uses global 
variables, as well internally, as implicitly by doing calls to an 
external Widget set. That is why the LCL is known to be not thread safe.





TThreadList.Add is not cross-instance-thread safe (multiple threads
using the same instance's Add procedure will result in erroneous
behavior).


No, it won't. 

Right you are. I meant to write TList. Sorry.

-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Mattias Gaertner
On Tue, 14 Jun 2011 13:26:07 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 06/14/2011 12:02 PM, Mattias Gaertner wrote:
  Why do you think so?
 Sorry I have been typing much faster than thinking here (again). I had 
 meant to be talking about TTlist. :-[ :-[ :-[

Your mails contain so many confusions - TThread.Add, completely
thread safe, separate-instance-thread safe, TList with TThreadList and now 
TTlist. You are a very confused troll.
This thread started about thread safe LCL functions.
If you want that FCL functions/methods be documented whether they are
thread safe or not you can ask on the fpc lists or create a feature
request.


[...]
 Simply stating that TList.Add is not thread save (which of course is 
 perfectly correct) would prevent using a TList instance as a data store 
 e.g. in a thread class that itself is instantiated multiple times. There 
 using TThreadList would be overkill.


Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Michael Schnell
The fact that I am a paranoiac does not mean that they are not after me 
;-) :-P :-D .


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-14 Thread Michael Schnell

On 06/14/2011 04:57 PM, Hans-Peter Diettrich wrote:


How would you expect a thread-safe version to work? A TList doesn't 
serialize requests, this would have to be added separately.


It does not need to, as  separate-instance-thread safe means that each 
thread handles only it's own instance.


Add only needs to use stack variables and instance variables. Both are 
dedicated to the thread and thus don't need a protection (OK it if needs 
to allocate memory the heap allocation procedure does need protection 
mechanism, but this is provided by the infrastructure anyway. )


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-12 Thread Marco van de Voort
On Sat, Jun 11, 2011 at 02:41:03AM +0100, Hans-Peter Diettrich wrote:
 threads at the same time.
 
 Which piece of code can *not* be safely invoked?
 
 Instead I'd define thread safety as the *absence* of possible data or
 state inconsistencies in concurrent execution [of threads].

The FileExistsUTF8() definition even adheres to that. The possible
inconsistency is in a different layer, the OS layer outside the runtime and
language's reach.

In short, then you must simply open the file for exclusive access and abort
on failure to open, instead of checking for existance.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe (was: How to PostMessage to object?)

2011-06-10 Thread Mattias Gaertner
On Fri, 10 Jun 2011 03:09:07 +0200
Hans-Peter Diettrich drdiettri...@aol.com wrote:

 Mattias Gaertner schrieb:
 
  Only if the documentation explicitly says a method is thread safe it is. 
  Maybe this needs to be made more clear. Any ideas, where?
 
 What is thread safe?

http://lmgtfy.com/?q=thread+safel=1

A piece of code is thread safe if it can be safely invoked by
multiple threads at the same time.


[...]
 After all: how/where can I find thread-related Lazarus/FPC 
 documentation? My wiki search was not really successful :-(

What words did you search?
I got results on Thread, Threads and Multithreading.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Michael Schnell

On 06/10/2011 03:09 AM, Hans-Peter Diettrich wrote:

What is thread safe?


IMHO, quite often, this needs further explanation in the docs.

e.g. if the code in question defines a class the diversification is 
generated by the potential use of class variables and global variables:



 - Are you allowed to create in in another thread but the main thread 
(e.g. forbidden for GUI-aware objects) ?


 - Can you create the class in one thread and call it's functions and 
properties from another one (e.g. forbidden for GUI-aware objects) ?


 - Are the functions and properties of a single project reentry-safe 
(is it allowed to use the same function of the same instance with 
multiple threads).


 - Is it allowed to use multiple instances of the object with multiple 
threads (each thread uses an instance; is it allowed to use the same 
function of a different instance with multiple threads).


 - Does an instance internally create threads and are events thrown in 
the context of such a thread instead in the context of the thread that 
created the object ?


 - ...

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Henry Vermaak

On 10/06/11 02:09, Hans-Peter Diettrich wrote:


What is thread safe?


The definition is very clear here:

http://en.wikipedia.org/wiki/Thread_safety


In how far is just FileExistsUTF8 thread safe? Even if the file
existed at function return, it can have been killed by somebody else
immediately after, even from outside the application.


This example is here:

http://en.wikipedia.org/wiki/Thread_safety#Concurrent_programing

It has nothing to do with thread safety.

Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Mattias Gaertner
On Fri, 10 Jun 2011 12:49:59 +0200
Hans-Peter Diettrich drdiettri...@aol.com wrote:

 Mattias Gaertner schrieb:
 
  Only if the documentation explicitly says a method is thread safe it is. 
  Maybe this needs to be made more clear. Any ideas, where?
  What is thread safe?
  
  http://lmgtfy.com/?q=thread+safel=1
  
  A piece of code is thread safe if it can be safely invoked by
  multiple threads at the same time.
 
 As already explained, I'm not comfortable with that definition.

Welcome to earth. How do you define it on your planet?

 
 Which aspect would cover access to shared objects by different pieces 
 of code?

What did you not understand on the link I gave?

 
  [...]
  After all: how/where can I find thread-related Lazarus/FPC 
  documentation? My wiki search was not really successful :-(
  
  What words did you search?
  I got results on Thread, Threads and Multithreading.
 
 Yes, hundreds of results per search - this is not really helpful :-(

I'm always amazed how spoiled Lazarus users are. I think this
is a compliment for Lazarus. :)

 
 It would help, to some degree, if a language could be specified, so that 
 the results are not crowded with any number of translated pages.

+1

Although I must admit I would not use that feature, because I often
want to know where a word is used.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Michael Schnell

On 06/10/2011 01:26 PM, Henry Vermaak wrote:

On 10/06/11 02:09, Hans-Peter Diettrich wrote:


What is thread safe?


The definition is very clear here:

http://en.wikipedia.org/wiki/Thread_safety


clear does not imply useful :) .

With piece of code they obviously mean a single function (or part of 
it), with the implication that no other functions are called during this 
test by any of those threads.


E.g. Regarding Objects this is not enough.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Mattias Gaertner
On Fri, 10 Jun 2011 13:52:35 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 06/10/2011 01:26 PM, Henry Vermaak wrote:
  On 10/06/11 02:09, Hans-Peter Diettrich wrote:
 
  What is thread safe?
 
  The definition is very clear here:
 
  http://en.wikipedia.org/wiki/Thread_safety
 
 clear does not imply useful :) .
 
 With piece of code they obviously mean a single function (or part of 
 it), with the implication that no other functions are called during this 
 test by any of those threads.

?
Of course a threads safe function can call other thread safe
functions.

 
 E.g. Regarding Objects this is not enough.

Prove?

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Michael Schnell

On 06/10/2011 02:18 PM, Mattias Gaertner wrote:

E.g. Regarding Objects this is not enough.

Prove?


Theory: with multiple instances, the same piece of code behaves 
differently, according to to the states that are stored internally in an 
instance.


It's not practical to just ignore this as a specification: you now would 
need to say that Objects never are thread safe and by this make any 
object language totally unsuited for threaded application.


It's a lot more helpful to do a more sophisticated definition of 
thread-safety for objects.



Example:

Imagine you create an instance of an object for each thread.

So the same piece of code (a function  procedure or property of the 
object) can behave differently regarding which instance is used (here 
which thread is calling it).


e.g. the function accesses just class variables (and local variables). 
Now it is thread safe if in fact each thread uses it's instance; but 
it's not thread safe, if a thread uses another thread's instance.


If it uses global variables it is not thread safe at all.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Mattias Gaertner
On Fri, 10 Jun 2011 14:36:36 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 06/10/2011 02:18 PM, Mattias Gaertner wrote:
  E.g. Regarding Objects this is not enough.
  Prove?
 
 Theory: with multiple instances, the same piece of code behaves 
 differently, according to to the states that are stored internally in an 
 instance.

Not only theory. It's common practical thing. For example
TThreadList.Add is thread safe and each call changes the object.

 
 It's not practical to just ignore this as a specification: you now would 
 need to say that Objects never are thread safe and by this make any 
 object language totally unsuited for threaded application.

I can't follow you here.


 It's a lot more helpful to do a more sophisticated definition of 
 thread-safety for objects.
 
 
 Example:
 
 Imagine you create an instance of an object for each thread.
 
 So the same piece of code (a function  procedure or property of the 
 object) can behave differently regarding which instance is used (here 
 which thread is calling it).
 
 e.g. the function accesses just class variables (and local variables). 
 Now it is thread safe if in fact each thread uses it's instance; but 
 it's not thread safe, if a thread uses another thread's instance.

I got the feeling you are not familiar with mathematical definitions.
If the definition says it can be safely invoked by multiple threads at
the same time then it means it can be invoked by any thread in any order at 
any time and the code still performs its task.

For example:
TThreadList.Add is thread safe because the task is to add an element
to the list.
If you define the task that after calling the element
is in the list, then it would not be thread safe.


 If it uses global variables it is not thread safe at all.

No. For example the heap manager uses global variables and it is
thread safe.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Michael Schnell

On 06/10/2011 03:32 PM, Mattias Gaertner wrote:


If the definition says it can be safely invoked by multiple threads at
the same time then it means it can be invoked by any thread in any order at 
any time and the code still performs its task.

But what is it.

The wiki says: piece of code. With Objects this would need to be 
piece of code of a particular instance, as the same piece of code of 
another instance c an behave totally different, as the states that are 
stored in the instance can behave totally different.


Of course (only with less practical value) this is also true in a 
not-object languages:


The piece of code can be a function that is called with a parameter. 
It can be thread safe if each thread calls it with a different parameter 
value (say a number denoting the thread) and not thread safe if some 
threads call it with the same parameter.


e.g.:

void a(n) {
  array[n] ++;
}


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] thread safe

2011-06-10 Thread Mattias Gaertner
On Fri, 10 Jun 2011 15:45:35 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 06/10/2011 03:32 PM, Mattias Gaertner wrote:
 
  If the definition says it can be safely invoked by multiple threads at
  the same time then it means it can be invoked by any thread in any order 
  at any time and the code still performs its task.
 But what is it.
 
 The wiki says: piece of code.

correct

 With Objects this would need to be 
 piece of code of a particular instance,

No.

 as the same piece of code of 
 another instance c an behave totally different, as the states that are 
 stored in the instance can behave totally different.

Doesn't matter as long the code does its task.

 
[...]

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


  1   2   >