[Lazarus] thread safe
Hans-Peter Diettrich
DrDiettrich1 at aol.com
Tue Jun 28 17:33:50 CEST 2011
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
More information about the Lazarus
mailing list