Hi,
I would like to know if TFPList is thread-safe or not? And if I make a component thread-safe by using critical sections etc. Is the performance penalty noticeable?
Thanks.
Xiangrong

Mailing lists / fpc-pascal / 2014-10
18 messages · 7 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Hi,
I would like to know if TFPList is thread-safe or not? And if I make a component thread-safe by using critical sections etc. Is the performance penalty noticeable?
Thanks.
Xiangrong
Xiangrong Fang wroteHi, I would like to know if TFPList is thread-safe or not? And if I make a component thread-safe by using critical sections etc. Is the performance penalty noticeable?
TFPList is not thread-safe. You need to use TThreadList if you want a thread-safe list.
Critical sections use OS calls, so there is always a performance penalty.
Michael.
I would like to know if TFPList is thread-safe or not? And if I make a component…
For a class, Thread save" is not that easily defined.
e.g.:
It can be fully thread save (like TThreadList): you can call any function/property at any time from any thread.
It could be allowed to create multiple instances in multiple threads and use each of them with it's own thread but not with others (holds for TList) It could be allowed to crate an instance with one thread and after that use functions/properties with a single other one. (e.g.: TList) it could be allowed to use all instances of the class only in a one and only thread.
It could be allowed to be used only in a predefined (e.g. the main-) thread (many classes in the LCL).
...
-Michael
TFPList is not thread-safe. You need to use TThreadList if you want a thread-safe list.…
2014-10-02 14:16 GMT+08:00 Michael Van Canneyt :
I think the only thread-critical operation I need is to add item to the list, so I will use critical section myself, not replace TFPList with TThreadList, for simplicity and performance reason...
Xiangrong
TFPList is not thread-safe. You need to use TThreadList if you want a thread-safe list.…
Michael Van Canneyt wroteCritical sections use OS calls, so there is always a performance penalty.
That is what Futex is made for.
AFAIR, in Linux, the fpc RTL calls the pthread library "mutex..." function. This library uses Futex, if the arch supports that, and uses the plain old MUTEX system call if the arch does not support FUTEX.
("FUTEX" = " Fast Userland MutEX" only does an OS call when necessary (i.e. when a thread needs to wait or when another thread needs to be woke). So in by fat most instances it just does a (atomic) userland operation.)
-Michael
2014-10-02 22:09 GMT+08:00 Michael Schnell :
I need my program to work on both Linux and Windows, can I still use FUTEX? For Critical Sections, FPC has the TCriticalSection object, is there a TMutex object?
Xiangrong
2014-10-02 22:23 GMT+08:00 Xiangrong Fang :
I found some quotes online:
For Windows, critical sections are lighter-weight than mutexes.
Mutexes can be shared between processes, but always result in a system call to the kernel which has some overhead. Critical sections can only be used within one process, but have the advantage that they only switch to kernel mode in the case of contention.
I only need lock WITHIN my own application, so, it seems that critical sections are better.
Xiangrong
2014-10-02 14:16 GMT+08:00 Michael Van Canneyt : I think the only thread-critical…
Xiangrong Fang wroteI think the only thread-critical operation I need is to add item to the list, so I will use critical section myself, not replace TFPList with TThreadList, for simplicity and performance reason...
It will make your program unstable (adding an element to an fplist can cause the entire internal array to move, so if you are in the middle of a read operation at the same time, that read operation will either read invalid data or crash). Unless you are an expert at multithreaded programming, don't try to optimise existing thread-safe structures (and definitely don't perform premature optimisations).
Jonas
2014-10-02 23:07 GMT+08:00 Jonas Maebe :
critical section, add item to the list, then leave the critical section.
I am definitely not expert in thread programming, but I am clear about the logic of my class and program. Actually, it is a TTree object I wrote, using TFPList to store sibling nodes. There are a lot of TFPList (one per tree node). I just need to make sure that there are no more than one thread operating on the same node at the same time.
Xiangrong
Xiangrong Fang wroteI don't intend to do any optimization. I just think that I need to enter a critical section, add item to the list, then leave the critical section.
Hello,
You must protect with a CriticalSection, "Add" and any other kind of access, like indexed access. As you must protect indexed access you are in the same penalty as using TThreadList.
Threading example to a crash (numbers are execution steps):
Thread 1
--------
1-Resolve TList data access to $00010000
2-calculate item 23 is at $00010023
3-Read $00010023
4-Crash or read from unalocated memory (content undefined).
Thread 2
--------
1-Enter "Add" function and resolve Tlist data to $00010000 2-Lock thread and find that it need to relocate data to $00020000. Move data 3-Unlock
4-Continue
2014-10-02 14:16 GMT+08:00 Michael Van Canneyt : I think the only thread-critical…
Xiangrong Fang wrote, not replace TFPList with TThreadList, for simplicity and performance reason...
I don't suppose it will be possible to beat TThreadList performance by any home-brew Pascal code, which is same is not insecure.
-Michael
2014-10-02 22:09 GMT+08:00 Michael Schnell : I need my program to work on both Linux and…
I did not recommend to use FUTEX yourself. Futex is a rather complicated thingy that needs ASM for a combination of atomic user land operations and system calls (that are done if necessary).
In Linux, the userland Futex stuff is done for you (if possible at all) in the ppthead library mutex_...() functions.
I am not sure that the fpc RTL in fact uses the pthread (standard C-language) library for TCrtitical section, but this would make sense, as in that library the dirty stuff is handled. (E.g. _not_ using FUTEX, but plain old MUTEX in case the arch does not provide FUTEX - there are several archs that don't provide FUTEX - AFAIK, X86, X86/64 and ARM32 do provide it).
Regarding Windows, I have not much knowledge about such low-level stuff. AFAIK, all Windows system calls are done via DLLs, and so always some Microsoft code is executed in Userland, anyway. Hence it is well possible that the Window "MUTEX" System-DLL-Call (like the pthreadlib so in Linux) automatically does a FUTEX-alike thingy.
For Critical Sections, FPC has the TCriticalSection object, is there a TMutex object?
AFAI understand, "CriticalSection" is the Delphi/fpc name for "POSIX-Mutex".
Of course you can do you own low-level implementation of a MUTEX/FUTEX Sync-Object. Doing that directly in ASM might be slightly faster than calling the C-phtreadlib. But this definitively is hard stuff. (Unfortunately Linux does not - and supposedly will not very soon support the rather new "vdso" concept - a kind of user-land system calls
- for FUTEX/MUTEX).
-Michael
2014-10-02 22:23 GMT+08:00 Xiangrong Fang : I found some quotes online: For Windows,…
So it seems that Windows in fact does a kind of FUTEX for inter-Thread synchronizing (as does pthredlib, that as it's name says just provides POSIX-operation within Threads, not between applications.)
Hence, provided TCrtiticalSections uses the Windows system DLL in Windows and the pthreadlib so in Linux, the resulting performance should be very similar.
-Michael
I did not recommend to use FUTEX yourself. Futex is a rather complicated thingy that…
In our previous episode, Michael Schnell said:
Critical sections are bound to the owning process under Windows, while Windows mutexes can span processes (and thus are more expensive).
So critical section is equal to posix mutex with PTHREAD_PROCESS_PRIVATE attribute.
Marco van de Voort wroteSo critical section is equal to posix mutex with PTHREAD_PROCESS_PRIVATE attribute.
Thanks for the clearness !
(The OP of course just wants just this - synchronization between threads of a single application.)
-Michael
In our previous episode, Michael Schnell said:
On *nix for critical section, cthreads creates a mutex of the recursive type(_PTHREAD_MUTEX_RECURSIVE) but doesn't set that attribute, but it seems(*) that the above attribute(PTHREAD_PROCESS_PRIVATE) is default.
(*) http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutexattr_getpshared.htmlI don't suppose it will be possible to beat TThreadList performance by any home-brew…
But I looked at the source code of TThreadList,
procedure TThreadList.Add(Item: Pointer);
begin
LockList;
try
if (Duplicates=dupAccept) or
// make sure it's not already in the list
(FList.IndexOf(Item)=-1) then
FList.Add(Item)
else if (Duplicates=dupError) then
FList.Error(SDuplicateItem,PtrUInt(Item));
finally
UnlockList;
end;
end;where
function TThreadList.LockList: TList;
begin
Result:=FList;
System.EnterCriticalSection(FLock);
end;There is no special simply calls
System.EnterCriticalSection(FLock),
so performance should be JUST THE SAME as wrapping a pair of critical section enter/leave around the code ourselves.
Dennis
Yep.
System.EnterCriticalSection is a procedure variable that is set according to the OS and arch the project is compiled for.
In Linux without UseCThreads it is just an empty function. (OK here creating threads is not allowed)
In Linux with UseCThreads it is just an empty function it is a call to pthread_mutex_lock, which is in the pthreadlib so file and calls FUTEX or MUTEX, such as appropriate. (So don't try to "optimize" !!! ) In Windows I suppose it does a call to the Windows system DLL that supposedly does a FUTEX workalike. (So don't try to "optimize" !!! )
Yep. (So don't try to "optimize" !!! )
-Michael