[fpc-devel] CThreads.pp

Jonas Maebe jonas.maebe at elis.ugent.be
Fri Nov 16 13:19:53 CET 2012


On 15 Nov 2012, at 19:55, Ewald wrote:

> I'll start off with some strange things first:
>
>    - In the source code of CThreads.pp there appears to be no field in
>    the threadmanager record called `rtlEventSync`. Yet the compiler
>    complains about the fact that this field is missing in my
>    declaration of the TThreadManager record. This declaration looks as
>    follows: `Const ZThreadManager = TThreadManager = (field: value;
>    ........);`.

Cthreads initialzes the thread manager record by explicitly assigning  
the thread manager record fields, not by declaring a typed constant.  
That means the compiler does not check for uninitialized fields. It  
seems this routine indeed still needs to be implemented for Unix  
platforms.

>    - On Mac Os X 10.6.8 the compiler complains about the fact that my
>    equivalent of the Function CBeginThread is incompatible with the  
> one
>    in the TThreadManager Record (The result types are incompatible,
>    aswell as the type of ThreadId: Pointer [Linux; this is also what  
> is
>    typed in the source file] <> TThreadId [Mac OS X]). This is very
>    strange 'cause I copied the declaration of every function over from
>    CThreads.pp. Should be the same, no?

If you also use the same units in your interface as cthreads, yes.

>    - Declaration of `pthread_key_create` differs from Mac OS X to
>    linux? Very weird because the documentation for both OS'es says
>    exactly the same, which is basically this:
>
>        `Type TCProcedure = Procedure(arg: Pointer); cdecl;
>
>        Function pthread_key_create(key: ppthread_key_t;  
> DestructorFunc:
>        TCProcedure): cint; cdecl; external name 'pthread_key_create';`

What difference do you mean exactly?
Linux: pthread_key_create : Function(__key:ppthread_key_t;  
__destr_function:__destr_function_t):longint;cdecl;
Mac OS X: function  pthread_key_create (p : ppthread_key_t;f:  
__destr_func_t):cint; cdecl;external 'c';

It's a procvar under Linux because libpthread is loaded dynamically  
there. And while it definitely would be cleaner to use cint instead of  
longint in the Linux version, in practice the type is the same.

> Then some things that seem unlogical to me:
>
>    - `Procedure IntbasiceventSetEvent` contains a Try...Finally block,
>    while there is no code inbetween that could possibly raise an
>    exception. Why is it there? (are some signals "converted" to an
>    exception? If so, why isn't this in almost every other function as
>    well?)

That was added by the person who did the very first implementation.  
There were in fact more try/finally's in the original implementation,  
but those have already been removed in the mean time. This one was  
apparently missed.

>    - Parameters `creationFlags` and `sa` in CBeginThread of  
> CThreads.pp
>    appear to be unused?

They are only used on Windows currently (they correspond to the  
corresponding arguments of the Windows CreateThread API). We should  
probably add a check for nil/0 and give an error if they are different  
on Unix.

>    - `Procedure CInitCriticalSection` contains the remark `No  
> recursive
>    mutex support :/`; which is quite weird because a recursive mutex
>    behaves *very* differently from a normal mutex. On some
>    implementations this means that you will all of the sudden get
>    deadlocks where you don't expect them. The fix for this would be to
>    remove recursive mutex support for critical sections. A patch for
>    this would be to replace the existing code with the one attached
>    [CInitCriticalSection.pas].

Removing recursive mutex support would completely break Windows/Delphi/ 
past-FPC compatibility for critical sections, so that is definitely  
not going to happen. At best, we can give an error when creating the  
critical section if no recursive mutex support is available.

>    - The types of TRTLCriticalSection and TThreadID are not defined in
>    the same unit as the thread manager, which means that creating
>    custom implementations of these (especially true for critical
>    sections) is impossible. As an example: suppose I want to use an
>    integer for busy waiting as a critical section, I would define
>    TRTLCriticalSection as an integer. Now I am stuck with pthreads'
>    mutex, which is not handy if you want to do this kinda thing with  
> an
>    integer.

They are indeed defined according to the OS thread interface. If  
necessary, I guess we could change them all to pointers, although it  
would probably break a lot of code though (since currently, code can  
use variables of those types with native OS thread functions). It's  
not true that that the current type differences mean that a custom  
implementation is impossible though, although it will require some  
typecasting in your manager. You can also add a check like this to  
your code to ensure that you don't make wrong assumptions:

{$if sizeof(tthreadid) < sizeof(longint)}
{$error tthreadid must be at least the size of a longint for this  
thread manager to function correctly}
{$endif}

> And something I haven't yet investigated thoroughly:
>
>    - On Max OS X, `sem_open` appears not to be found. This might be a
>    simply typo of mine, but maybe there's someone with the same  
> problem?

Where is it not found/how are you looking for it? Or are you perhaps  
confusing it with sem_init, which indeed does not exist on Mac OS X?


Jonas




More information about the fpc-devel mailing list