Once upon a time, on 02/07/2013 11:57 AM to be precise, Jonas Maebe said: > > On 06 Feb 2013, at 23:16, Ewald wrote: > >> Concerning the locking mechanism, you can uses mutex(en/es/ii) or you >> can do this by a busy waiting loop with an integer (of course there are >> other possibilities). To elaborate on the latter a bit more: >> >> * TLockType = Integer; >> * Initialization: `Lock:= 0;` >> * Lock & unlock: >> >> ===> Code Begin <=== >> >> Procedure WaitLockVar(var aLock: Integer); >> Begin >> Repeat >> Until InterLockedCompareExchange(aLock, 1, 0) = 0; >> End; >> >> Procedure UnlockVar(var aLock: Integer); >> Begin >> InterlockedExchange(aLock, 0); >> End; >> >> ===> Code End <=== >> >> This last code is tested and works. > > It only works on some platforms (and even there it may change > depending on which exact processor you are using). InterlockedExchange > does not guarantee any kind of memory barrier, and hence you will get > occasional data races on platforms with weakly consistent memory > models. You have to add memory barriers. Well, I always thought that the InterLoackedCompareExchange boiles down to [**] .Lock CMPXCHG
Or something quite like that. The `.Lock` there is the important part since this does insure a memory barier. Then the only problem would be the absence of the keyword `volatile` to ensure the integer is always in the same location but I've read somewhere, long ago, that fpc doesn't perform such optimizations. So I don't see the issue really. [**] I make this assumption because the documentation says it is done in a thread safe way (reference: http://www.freepascal.org/docs-html/rtl/system/interlockedcompareexchange.html), and I don't see what other things can be made thread safe about this function except for a memory barrier. -- Ewald
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel