[fpc-devel] CThreads.pp

Ewald bloody.middlefinger at yellowcouch.org
Fri Nov 16 19:15:13 CET 2012


Once upon a time, on 11/16/2012 01:19 PM to be precise, Jonas Maebe said:
> 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.
Right, I see. I've reported a bug on this matter.



>>    - 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.
Well, the compiler gives this error:
`Incompatible types: got
    "<address of function(Pointer,QWord,TThreadFunc,Pointer,LongWord,var
*Pointer*):^*untyped*;Register>" expected
    "<procedure variable type of
function(Pointer,QWord,TThreadFunc,Pointer,LongWord,var
*TThreadID*):^*TThreadRec*;Register>"
`

Rather weird, no? Have I missed something? Or is this due to the fact
that I declare my threadmanager record using a typed constant?

Note: Th compiler also complains about several other
functions/procedures involving the tpe TThreadID. Same error as the one
above.



>>    - 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';
Well, I discovered that some code was contained in an $ifdef block,
while it shouldn't. So there is indeed no difference between the two
calls. Sorry for that.



>> 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.
I see. I've also reported a bug on this one.



>>    - 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.
Yep, as I said, I'm not into windows programming lately. So it basically
has no meaning at all on non-windows OS'es?


> 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.
Right, I didn't know this. The best solution would be, as you said, to
give an error in case 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).
Indeed it would perhaps break to much code to do any good, especially
true for TThreadID. Then again there are `eassier` types, for example
TRTLCriticalSection, which never gets used as a parameter in a system
call... Or am I wrong in saying that?

> 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.
Yep, that's what I did to give it a try, and of course it works, but it
is, let's admit it, a rather hackish way and a waste of good memory.
Also it doesn't really give you code that compiler everywhere. So in my
opinion it can be called `Impossible`.

> 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}
This is very interesting to generate `safer` code (i.e. only perform the
typecast when there is enough memory), but it still doesn't give one a
clean solution.




>> 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?
>
No, it's definetly sem_open, the litteral error is:
    `Error: Identifier not found "sem_open"`

My uses list contains the exact same units as in CThreads.pp, in the
same order, so I don't see why the symbol isn't found. Also, the entire
load of $idfdef's are also copied into my source code.

Undeffing `has_sem_open` makes the code compile.

Same goes for `SEM_FAILED`, but this is related to the very same issue I
believe.

-- 
Ewald

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20121116/01991612/attachment.html>


More information about the fpc-devel mailing list