Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-04

semaphores?

10 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Seth Grover

Is there not a cross-platform semaphore API in Free Pascal? I planned on using the callbacks in TThreadManager as described in the docs (http://www.freepascal.org/docs-html/rtl/system/tthreadmanager.html), but to my dismay they aren't initialized for win32. Bug 11206, which has been marked as "won't fix", indicates that TThreadManager should not be used by user programs.

So is there a "right" way to do it, or do I have to revert to using IFDEFs and the low-level system-dependent calls?

-SG

This email is fiction. Any resemblance to actual events or persons living or dead is purely coincidental. Seth Grover sethdgrover[at]gmail[dot]com

Reply by email

Graeme Geldenhuys
to Seth Grover
Seth Grover wrote
Is there not a cross-platform semaphore API in Free Pascal? I planned

About 4 years ago there wasn't, so I had to use IFDEF's in my code. I haven't looked in newer versions of FPC if there is a cross-platform API available. I would be interested in this as well.

This is what I had to do...

[...snip...]
    {$IFDEF MSWINDOWS}
    FSemaphore : THandle;
    {$ENDIF MSWINDOWS}
    {$IFDEF LINUX}
    FSemaphore : TSemaphore;
    {$ENDIF LINUX}
[...snip...]
procedure TtiPool.CreatePoolSemaphore;
begin
  {$IFDEF MSWINDOWS}
  if FSemaphore  0 then
    CloseHandle(FSemaphore);
  FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil);
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  sem_destroy(FSemaphore);
  if sem_init(FSemaphore, 0, FMaxPoolSize)  0 then
    raise Exception.Create('Failed to create the semaphore');
  {$ENDIF LINUX}
end;

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 6 lines
On Mon, Apr 13, 2009 at 11:49 PM, Seth Grover wrote: > Is there not a cross-platform semaphore API in Free Pascal? I planned About 4 years ago there wasn't, so I had to use IFDEF's in my code. I haven't looked in newer versions of FPC if there is a cross-platform API available. I would be interested in this as well.

Well:

  TThreadManager = Record
   // skip some stuff
    SemaphoreInit          : TSempahoreInitHandler;
    SemaphoreDestroy       : TSemaphoreDestroyHandler;
    SemaphorePost          : TSemaphorePostHandler;
    SemaphoreWait          : TSemaphoreWaitHandler;
  end;

Use GetThreadManager() to retrieve the thread manager, and then simply use the various functions.

This should work cross-platform, but it seems that the Windows implementation is empty. Maybe we can use your functions to implement the windows part.

Michael.

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote
Use GetThreadManager() to retrieve the thread manager, and then simply use the various functions.

Umm, I didn't know that... I made a note for future reference. :-)

This should work cross-platform, but it seems that the Windows implementation is empty. Maybe we can use your functions to implement the windows part.

The code I quoted is from tiOPF's tiPool.pas unit. I think the following is the relevant parts...

================================
procedure TtiPool.UnlockPoolSemaphore;
begin
  {$IFDEF MSWINDOWS}
  ReleaseSemaphore(FSemaphore, 1, nil);
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  if sem_post(FSemaphore)  0 then
    raise Exception.Create('Failed to unlock the semaphore');
  {$ENDIF LINUX}
end;
procedure TtiPool.CreatePoolSemaphore;
begin
  {$IFDEF MSWINDOWS}
  if FSemaphore  0 then
    CloseHandle(FSemaphore);
  FSemaphore := CreateSemaphore(nil, FMaxPoolSize, FMaxPoolSize, nil);
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  sem_destroy(FSemaphore);
  if sem_init(FSemaphore, 0, FMaxPoolSize)  0 then
    raise Exception.Create('Failed to create the semaphore');
  {$ENDIF LINUX}
end;
procedure TtiPool.DestroyPoolSemaphore;
{$IFDEF LINUX}
var
  error: integer;
{$ENDIF LINUX}
begin
  {$IFDEF MSWINDOWS}
  CloseHandle(FSemaphore);
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  error := sem_destroy(FSemaphore);
  if error  0 then
    raise Exception.Create('Failed to destroy the semaphore');
  {$ENDIF LINUX}
end;
function TtiPool.LockPoolSemaphore: boolean;
begin
  // Wait for a semaphore
  {$IFDEF MSWINDOWS}
  result:= WaitForSingleObject(FSemaphore, FWaitTime * 1000)  WAIT_TIMEOUT;
  {$ENDIF MSWINDOWS}
  {$IFDEF LINUX}
  { TODO: The timeout option is not available in POSIX semaphores. This can be
    achieved by issuing a non-blocking sem_trywait() within a loop, which
    counts the timeout value: int sem_trywait(sem_t * sem).
    i := fpgeterrno; }
  result:= sem_trywait(FSemaphore) = 0;
  {$ENDIF LINUX}
end;

============================

The tiPool.pas unit is probably the unit with the most IFDEF's in them, in the whole tiOPF project. ;-)

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Michael Van Canneyt
to Jonas Maebe
Jonas Maebe wrote 9 lines
On 14 Apr 2009, at 13:42, Michael Van Canneyt wrote: >Use GetThreadManager() to retrieve the thread manager, and then >simply use the various functions. No, the thread manager is only for internal use by the RTL, and may lack implementations for functions not required by the RTL for a particular platform. See http://bugs.freepascal.org/view.php?id=11206

That was definitely not the original intention of the thread manager.

The idea was to have low-level thread related functions available without classes, including semaphores.

Michael.

Reply by email

Jonas Maebe
to Michael Van Canneyt
Michael Van Canneyt wrote 18 lines
On Mon, 20 Apr 2009, Jonas Maebe wrote: > On 14 Apr 2009, at 13:42, Michael Van Canneyt wrote: > >> Use GetThreadManager() to retrieve the thread manager, and then >> simply use the various functions. > > No, the thread manager is only for internal use by the RTL, and may > lack > implementations for functions not required by the RTL for a > particular > platform. See http://bugs.freepascal.org/view.php?id=11206 That was definitely not the original intention of the thread manager. The idea was to have low-level thread related functions available without classes, including semaphores.

I don't think the thread manager is an appropriate model for this, as it may have to be changed depending on internal requirements of the RTL (for example, a big shortcoming currently is that the thread manager generally lacks error reporting functionality, other than triggering run time errors). An abstraction layer on top of the thread manager seems more appropriate for the purpose of offering a portable procedural threading interface.

It's similar to how you don't directly use the memory manager, but instead have to use getmem/freemem/...

Jonas

Reply by email

Michael Van Canneyt
to Jonas Maebe
Jonas Maebe wrote 25 lines
On 20 Apr 2009, at 10:30, Michael Van Canneyt wrote: >On Mon, 20 Apr 2009, Jonas Maebe wrote: > > >On 14 Apr 2009, at 13:42, Michael Van Canneyt wrote: > > > > >Use GetThreadManager() to retrieve the thread manager, and then > > >simply use the various functions. > > > >No, the thread manager is only for internal use by the RTL, and may lack > >implementations for functions not required by the RTL for a particular > >platform. See http://bugs.freepascal.org/view.php?id=11206 > >That was definitely not the original intention of the thread manager. > >The idea was to have low-level thread related functions available without >classes, including semaphores. I don't think the thread manager is an appropriate model for this, as it may have to be changed depending on internal requirements of the RTL (for example, a big shortcoming currently is that the thread manager generally lacks error reporting functionality, other than triggering run time errors). An abstraction layer on top of the thread manager seems more appropriate for the purpose of offering a portable procedural threading interface.

That was exactly the intention. Prior to giving my answer, I checked and discovered that the semaphor low-level functions do not exist, so I recommended to use the thread manager record. While checking, I also saw that there is no implementation for windows.

It's similar to how you don't directly use the memory manager, but instead have to use getmem/freemem/...

Agreed 100%, but I was trying to present a workaround.

Michael.

Reply by email

Marco van de Voort
to Michael Van Canneyt: That was definitely not the original intention of the thread manager. The idea was to…

In our previous episode, Michael Van Canneyt said:

Show quoted text 8 lines
> No, the thread manager is only for internal use by the RTL, and may lack > implementations for functions not required by the RTL for a particular > platform. See http://bugs.freepascal.org/view.php?id=11206 That was definitely not the original intention of the thread manager. The idea was to have low-level thread related functions available without classes, including semaphores.

I cannot remember that either. I can remember something about beginthread/endthread being kept because of backwards compat, but not because of a great all-procedural api.

Reply by email

Jonas Maebe
to Marco van de Voort
Marco van de Voort wrote 16 lines
In our previous episode, Michael Van Canneyt said: >> No, the thread manager is only for internal use by the RTL, and >> may lack >> implementations for functions not required by the RTL for a >> particular >> platform. See http://bugs.freepascal.org/view.php?id=11206 > > That was definitely not the original intention of the thread manager. > > The idea was to have low-level thread related functions available > without > classes, including semaphores. I cannot remember that either. I can remember something about beginthread/endthread being kept because of backwards compat, but not because of a great all-procedural api.

beginthread/endthread are part of a general procedural api for thread programming (they also exist in Kylix, afaik). It just was never really fleshed out. I was only talking about recommending the use of the thread manager directly (even as a workaround).

Jonas

Reply by email