[fpc-pascal] Semaphore problems
Vinzent Höfler
JeLlyFish.software at gmx.net
Mon Jul 24 23:33:53 CEST 2006
Burkhard Carstens wrote:
> Am Montag, 24. Juli 2006 22:05 schrieb Vinzent Höfler:
>> Burkhard Carstens wrote:
>>> Am Montag, 24. Juli 2006 20:33 schrieb Vinzent Höfler:
>>>> Burkhard Carstens wrote:
>>>>> [..]
>>
>>> btw. this is not TEvent, we are talking about, it's rtlevent ..
>>> TEvent (in synconjs) is implemented differently, and should work
>>> like delphi/ windows TEvent, except that it is not capable of
>>> timedwait ..
>> Well, if I'm looking at it correctly that's only because its
>> implementation is based on the POSIX semaphore. It could be using the
>> phtread_mutex stuff instead. The pthread-primitives are used anyway,
>> so I don't see problems with dependencies on libpthread/libc or
>> so...
>
> My idea was to use a rtlevent additionally and only when waitfor is
> called with timeout AND event is not signalled yet.
Why additionally? Do I miss something here? If done the proper way,
everything in SyncObjs should be based on the basic RTL stuff. This
would make the SyncObjs unit system independent with clearly defined
semantics on all targets.
Of course, the original implementation (I suppose it came from Delphi?)
was very windows-centric and made use of the available
Windows-primitives directly. So maybe for Win32 it should even be kept
this way, if not for anything else, somebody may say, for performance
reasons at least.
>> Hmm, *looking closer* ... are there any differences between
>> Darwin/BSD/Linux/Solaris code at all? AFAICS, all these
>> implementations could be merged into a single one for Unix/POSIX
>> targets.
>
> Don't know, maybe. However, we use PTHREAD_MUTEX_RECURSIVE_NP, where NP
> stands for NotPortable.. don't know which platforms support it and
> which not.
Well, those flags are somhow there, but there marked "XSI" in the
OpenGroup's current specification, so probably most of our targets
implement it - but it's still an extension.
> That's why I voted for implementing most of the functionality in pascal
> and use pthread primitives only in their basic (i.e. mutex in
> non-recursive) form.
Hmm. So we'd need a mutex inside a mutex. Now I know why they call it
recursive. ;) So it'll be something like that:
function Recursive_Mutex.Lock : ...;
begin
// Lock mutex inside mutex.
self.Owner_Check_Lock.Lock;
// Owned by current thread?
if CurrentThreadId <> self.ThreadId then
begin
// Nope! Get the hell outta here.
self.Owner_Check_Lock.Unlock;
exit (NOT_OWNED);
end {if};
// Now try locking the real mutex.
if pthread_mutex_lock (self...) = 0 then
begin
self.Count := self.Count + 1;
self.Owner_Check.Unlock;
exit (SUCCESS);
end {if};
self.Owner_Check.Unlock;
exit (FAILURE);
end {Mutex.Lock};
Something like that. Don't nail me on that, it's quite late and the heat
is still killing me. ;)
Well, a simple spinlock would even be better here for performance
reasons, because first the locking time should be quite small, and
second usually this code will be called in a sequential manner from
within the same thread anyway. This would make the lock always being in
an unlocked state under all sane circumstances.
Maybe even some overflow check in case someone tries to lock the mutex
more than 2**32 times in a row? ;)
Same for unlock etc.
Vinzent.
More information about the fpc-pascal
mailing list