[fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
Hi, I initially posted this in the fpc-pascal list, but I think fpc-devel is maybe more appropriate, because the pthreads include files might need amendment. I'm trying to get tiOPF to compile under FreeBSD. It works under Linux and Windows without problems. I got compiler errors using FPC 2.6.0 under FreeBSD, saying that the compiler couldn't decide which version of the sem_* methods to use. I had code like this in tiOPF: {$IFDEF MSWINDOWS} FSemaphore: THandle; {$ENDIF MSWINDOWS} {$IFDEF UNIX} FSemaphore: TSemaphore; {$ENDIF UNIX} ... procedure TtiPool.CreatePoolSemaphore; begin {$IFDEF MSWINDOWS} if FSemaphore 0 then CloseHandle(FSemaphore); FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil); {$ENDIF MSWINDOWS} {$IFDEF UNIX} FillChar(FSemaphore, sizeof(FSemaphore), 0); // pShared = 0 means, shared between the threads of a process writeln('FMaxPoolSize = ', FMaxPoolSize); if sem_init(@FSemaphore, 0, FMaxPoolSize) 0 then raise EtiOPFInternalException.Create('Failed to initialize the semaphore'); {$ENDIF UNIX} end; Note the sem_init() call takes a pointer. As you can see from the quoted code below, FreeBSD has two versions of the sem_* methods. The compiler couldn't decide which version to use: Error: Can't determine which overloaded function to call To get it to compiler under FreeBSD, I must change the sem_init() line too the following... if sem_init(FSemaphore, 0, FMaxPoolSize) 0 then ...but this breaks compiling under Linux again. 1) How do I get the tiOPF code to work under both Linux and FreeBSD using a single {$IFDEF UNIX}. I don't really want to introduce {$IFDEF LINUX} and {$IFDEF FREEBSD} in the code. 2) Why does FreeBSD have two versions of these methods and Linux only one? I had a look at the other pthr*.inc units. Linux and SunOS has a single version, BSD (which I believe is MacOSX too) and Haiku has two versions. [ pthrbsd.inc freebsd ]--- function sem_init(__sem:Psem_t; __pshared:cint;__value:dword):cint;cdecl; external; function sem_destroy(__sem:Psem_t):cint;cdecl;external ; function sem_close(__sem:Psem_t):cint;cdecl;external ; function sem_unlink(__name:Pchar):cint;cdecl;external ; function sem_wait(__sem:Psem_t):cint;cdecl;external ; function sem_trywait(__sem:Psem_t):cint;cdecl;external ; function sem_post(__sem:Psem_t):cint;cdecl;external ; function sem_getvalue(__sem:Psem_t; __sval:Pcint):cint;cdecl;external; function sem_init(var __sem: sem_t; __pshared:cint; __value:dword):cint cdecl;external; function sem_destroy(var __sem: sem_t):cint;cdecl;external; function sem_close(var __sem: sem_t):cint;cdecl;external; function sem_wait(var __sem: sem_t):cint;cdecl;external; function sem_trywait(var __sem: sem_t):cint;cdecl;external; function sem_post(var __sem: sem_t):cint;cdecl;external; function sem_getvalue(var __sem: sem_t; var __sval:cint):cint;cdecl;external; [ end ]-- ---[ pthrlinux.inc linux ]- function sem_init(__sem:Psem_t; __pshared:cint; __value:dword):cint;cdecl;external libthreads; function sem_destroy(__sem:Psem_t):cint;cdecl;external libthreads; function sem_close(__sem:Psem_t):cint;cdecl;external libthreads; function sem_unlink(__name:Pchar):cint;cdecl;external libthreads; function sem_wait(__sem:Psem_t):cint;cdecl;external libthreads; function sem_trywait(__sem:Psem_t):cint;cdecl;external libthreads; function sem_post(__sem:Psem_t):cint;cdecl;external libthreads; function sem_getvalue(__sem:Psem_t; __sval:pcint):cint;cdecl;external libthreads; function sem_timedwait(__sem: Psem_t; __abstime: Ptimespec):cint;cdecl; external libthreads; ---[ end ]--- Attached is a small test project using snippets of code that tiOPF uses. The current version of this test project will compiler under FreeBSD, but will not compiler under Linux. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ semp_test.tar.gz Description: GNU Zip compressed data ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 11:51, Graeme Geldenhuys wrote: Hi, I initially posted this in the fpc-pascal list, but I think fpc-devel is maybe more appropriate, because the pthreads include files might need amendment. I personally think that the fpc-pascal list was the more approbiate, but nevertheless: your problem comes down to this code (in principal): === code begin === program semtest; type sem_t_rec = record end; // from rtl/freebsd/ptypes.inc sem_t = ^sem_t_rec; // from rtl/freebsd/ptypes.inc psem_t = ^sem_t; // from packages/pthreads/src/pthrbsd.inc procedure sem_init(sem: psem_t); begin end; procedure sem_init(var sem: sem_t); begin end; var s: sem_t; begin sem_init(@s); end. === code end === Now the problem is the @s. This returns type Pointer and now you have two pointer types: sem_t and psem_t. Thus the compiler can not resolve this. Solution: Typed addresses. Change your call the following way: === solution begin === begin {$push} {$typedaddress on} sem_init(@s); {$pop} end. === solution end === In this case the return type of @s will be ^sem_t instead of Pointer and then the compiler will find the correct method. Now one might nevertheless ask the question why the compiler considers the var variant with an @s valid at all? Maybe this is a bug indeed... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
In our previous episode, Sven Barth said: In this case the return type of @s will be ^sem_t instead of Pointer and then the compiler will find the correct method. Now one might nevertheless ask the question why the compiler considers the var variant with an @s valid at all? Maybe this is a bug indeed... Afaik Delphi allows that too since D4. It was one of the things 1.0.x couldn't do, but 1.9+ could. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 14:16, Marco van de Voort wrote: In our previous episode, Sven Barth said: In this case the return type of @s will be ^sem_t instead of Pointer and then the compiler will find the correct method. Now one might nevertheless ask the question why the compiler considers the var variant with an @s valid at all? Maybe this is a bug indeed... Afaik Delphi allows that too since D4. It was one of the things 1.0.x couldn't do, but 1.9+ could. But if the overload with the psem_t is removed the var variant doesn't compile either: === output begin === Free Pascal Compiler version 2.6.0 [2011/12/23] for i386 Copyright (c) 1993-2011 by Florian Klaempfl and others Target OS: Linux for i386 Compiling vartest.pas vartest.pas(22,14) Error: Can't assign values to an address vartest.pas(24) Fatal: There were 1 errors compiling module, stopping Fatal: Compilation aborted Error: /mnt/data/applications/fpc/2.6.0/bin/ppc386 returned an error exitcode (normal if you did not specify a source file to be compiled) === output end === So my personal opinion is still that this is a bug... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 2013-02-03 12:28, Sven Barth wrote: I personally think that the fpc-pascal list was the more approbiate, but nevertheless: your problem comes down to this code (in principal): I thinking was that this problem seems to point towards a bug, or at least inconsistency between defined types and various platforms. But as you say, nevertheless. Thanks for replying. type sem_t_rec = record end; // from rtl/freebsd/ptypes.inc sem_t = ^sem_t_rec; // from rtl/freebsd/ptypes.inc psem_t = ^sem_t; // from packages/pthreads/src/pthrbsd.inc Indeed, the sem_t is differently defined between Linux and FreeBSD. Under Linux, sem_t is just a record defined as: // rtl/linux/ptypes.inc sem_t = record __sem_lock: _pthread_fastlock; __sem_value: cint; __sem_waiting: pointer; end; In FreeBSD sem_t is pointer. Isn't that what psem_t is for? So under FreeBSD sem_t should be defined as sem_t_rec = record end; sem_t = sem_t_rec; psem_t = ^sem_t; I would expect unix-types / posix-types supposed to be defined the same in all such related OSes (eg: *BSD, Linux, MacOSX, Haiku, *nix)? Now the problem is the @s. This returns type Pointer and now you have two pointer types: sem_t and psem_t. Thus the compiler can not resolve this. Indeed. You just seem to have explained it better than I. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
In our previous episode, Graeme Geldenhuys said: In FreeBSD sem_t is pointer. Isn't that what psem_t is for? No. That is a pointer to sem_t. It doesn't specify what sem_t should be. struct sem; typedef struct sem *sem_t; _sem_ is the record, sem_t is a pointer. So under FreeBSD sem_t should be defined as sem_t_rec = record end; sem_t = sem_t_rec; psem_t = ^sem_t; I would expect unix-types / posix-types supposed to be defined the same in all such related OSes (eg: *BSD, Linux, MacOSX, Haiku, *nix)? The reality is afaik that sem_t is abstract in POSIX. Keep in mind that POSIX is not an API, but more a set of common requirements for an api. Assuming the type should not be necessary. The VAR variants are probably leftovers from 1.0.x when headers were pascalized as much as possible. During the *nix RTL reform of what would become 2.0 I insisted to at least have the pointer variant alongside of the 1.0.x declarations (to make examples in C translate 1:1) The resulting overloading can cause problems. It can be reduced by deprecating the original pascallized versions, and removing them in some future version. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 18:54, Graeme Geldenhuys wrote: On 2013-02-03 12:28, Sven Barth wrote: I personally think that the fpc-pascal list was the more approbiate, but nevertheless: your problem comes down to this code (in principal): I thinking was that this problem seems to point towards a bug, or at least inconsistency between defined types and various platforms. But as you say, nevertheless. Thanks for replying. I personally still think there is a bug, because the compiler should (in my opinion) not consider sem_init(@sem) a valid usage of sem_init(var sem: sem_t)... type sem_t_rec = record end; // from rtl/freebsd/ptypes.inc sem_t = ^sem_t_rec; // from rtl/freebsd/ptypes.inc psem_t = ^sem_t; // from packages/pthreads/src/pthrbsd.inc Indeed, the sem_t is differently defined between Linux and FreeBSD. Under Linux, sem_t is just a record defined as: // rtl/linux/ptypes.inc sem_t = record __sem_lock: _pthread_fastlock; __sem_value: cint; __sem_waiting: pointer; end; In FreeBSD sem_t is pointer. Isn't that what psem_t is for? So under FreeBSD sem_t should be defined as sem_t_rec = record end; sem_t = sem_t_rec; psem_t = ^sem_t; I would say that someone wanted to honor the obfuscated type idea of that structs... don't ask me why it was done that way though I would expect unix-types / posix-types supposed to be defined the same in all such related OSes (eg: *BSD, Linux, MacOSX, Haiku, *nix)? I you look at the POSIX definition at http://pubs.opengroup.org/onlinepubs/007904975/basedefs/semaphore.h.html you'll see that they don't specify any specific fields so sem_t should be treated as opaque type and thus any kernel can implement it as it sees fit. Now the problem is the @s. This returns type Pointer and now you have two pointer types: sem_t and psem_t. Thus the compiler can not resolve this. Indeed. You just seem to have explained it better than I. Did at least the solution help you? AFAIK it should work for FreeBSD as well as Linux (and maybe the other *nix systems...) Regards, sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 19:08, Marco van de Voort wrote: The resulting overloading can cause problems. It can be reduced by deprecating the original pascallized versions, and removing them in some future version. Maybe exactly that should be done... (a pitty that 2.6.2 is already that far ^^) Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 2013-02-03 18:08, Marco van de Voort wrote: The resulting overloading can cause problems. It can be reduced by deprecating the original pascallized versions, and removing them in some future version. So at this current point in time, my only solution is to have code as follows in tiOPF: procedure TtiPool.CreatePoolSemaphore; ... begin {$ifdef windows} ... {$endif} {$ifdef unix} {$ifdef linux} ... {$endif} {$ifdef freebsd} ... {$endif} {$ifdef macosx} // I plan to test under MacOSX soon ... {$endif} {$endif} end; And everywhere else in the TtiPool class where sem_* methods are used. This is just yuck!!! I hate IFDEF's. :-/ Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 19:23, Graeme Geldenhuys wrote: On 2013-02-03 18:08, Marco van de Voort wrote: The resulting overloading can cause problems. It can be reduced by deprecating the original pascallized versions, and removing them in some future version. So at this current point in time, my only solution is to have code as follows in tiOPF: procedure TtiPool.CreatePoolSemaphore; ... begin {$ifdef windows} ... {$endif} {$ifdef unix} {$ifdef linux} ... {$endif} {$ifdef freebsd} ... {$endif} {$ifdef macosx} // I plan to test under MacOSX soon ... {$endif} {$endif} end; And everywhere else in the TtiPool class where sem_* methods are used. Why? The variant with the TYPEDADDRESS should work for the other *nix targets as well... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 2013-02-03 18:10, Sven Barth wrote: I personally still think there is a bug, because the compiler should (in my opinion) not consider sem_init(@sem) a valid usage of sem_init(var sem: sem_t)... +1 I you look at the POSIX definition at http://pubs.opengroup.org/onlinepubs/007904975/basedefs/semaphore.h.html you'll see that they don't specify any specific fields so sem_t should After reading Marco's reply I now understand. I didn't know this before. Did at least the solution help you? AFAIK it should work for FreeBSD as well as Linux (and maybe the other *nix systems...) [After my reply to Marco, I tried your solution] Yes, that did work - thanks. I have never seen those {$} you mentioned, but will read the FPC docs now to find out more. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 2013-02-03 18:29, Sven Barth wrote: Why? The variant with the TYPEDADDRESS should work for the other *nix targets as well... Sorry, I replied to Marco before I tried your solution. Your solution works. Thanks. Regards, - Graeme - ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD
On 03.02.2013 19:40, Graeme Geldenhuys wrote: Did at least the solution help you? AFAIK it should work for FreeBSD as well as Linux (and maybe the other *nix systems...) [After my reply to Marco, I tried your solution] Yes, that did work - thanks. I have never seen those {$} you mentioned, but will read the FPC docs now to find out more. I can suggest you to read http://www.freepascal.org/docs-html/prog/progch1.html#x5-40001 if you've not already found it. :) The 2.6.0 documentation is not completely up to date regarding the directives, but the 2.6.2 one will be (see http://bugs.freepascal.org/view.php?id=21303 ). Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel