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

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to