[fpc-devel] how to get same pthreads code to compile between Linux and FreeBSD

2013-02-03 Thread Graeme Geldenhuys
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

2013-02-03 Thread Sven Barth

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

2013-02-03 Thread Marco van de Voort
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

2013-02-03 Thread Sven Barth

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

2013-02-03 Thread Graeme Geldenhuys
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

2013-02-03 Thread Marco van de Voort
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

2013-02-03 Thread Sven Barth

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

2013-02-03 Thread Sven Barth

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

2013-02-03 Thread Graeme Geldenhuys
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

2013-02-03 Thread Sven Barth

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

2013-02-03 Thread Graeme Geldenhuys
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

2013-02-03 Thread Graeme Geldenhuys
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

2013-02-03 Thread Sven Barth

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