comp.lang.ada
 help / color / mirror / Atom feed
From: Jano <nono@celes.unizar.es>
Subject: Re: Suspicious reentrant semaphore
Date: Thu, 1 May 2003 14:33:52 +0200
Date: 2003-05-01T14:33:52+02:00	[thread overview]
Message-ID: <MPG.191b30d33a1ec1a29896ee@News.CIS.DFN.DE> (raw)
In-Reply-To: b8o01n$bh20l$1@ID-77047.news.dfncis.de

Dmitry A. Kazakov dice...
> The requeue statement does the trick in case you want to use a parameter 
> value in a barrier. You could add one more private entry and requeue to it 
> if the task is not the owner:

Dmitry: I love this suggestion specially because is the first time I'm 
going to employ requeue (never before I faced the necessity).

Here is the new version of my package. I've also slightly changed the 
release logic to obtain exceptions instead of deadlocks in case of wrong 
use:

---------------- SPEC ---------------------

with Ada.Finalization;        use Ada;
with Ada.Task_identification;

package Adagio.Monitor is

   use Ada.Task_identification;

   Use_error : Exception;
   
   protected type Semaphore is

      entry     P (Owner : Task_id);
      procedure V (Owner : Task_id);

   private

      entry Safe_P (Owner : Task_id);

      Caller : Task_id := Null_task_id;           -- Requester
      In_use : Natural := 0;                      -- Times requested

   end Semaphore;

   type Semaphore_access is access all Semaphore;

   -- Use: 
   -- S : aliased Semaphore;
   -- declare
   --   M : Object(S'access);
   -- begin
   --   Exclusive_work;
   -- end;
   type Object (S : access Semaphore) is new 
      Finalization.Limited_Controlled with null record;

   procedure Initialize (this : in out Object);
   procedure Finalize   (this : in out Object);

end Adagio.Monitor;

------------------ BODY -----------------------

package body Adagio.Monitor is

   protected body Semaphore is

      entry P (Owner : Task_id) when true is
      begin
         if Owner = Caller then
            In_use := In_use + 1;
         else
            requeue Safe_P with abort;
         end if;
      end P;

      entry Safe_P (Owner : Task_id) when In_use = 0 is
      begin
         Caller := Owner;
         In_use := 1;
      end Safe_P;

      procedure V (Owner : Task_id) is
      begin
         if Owner /= Caller then
            raise Use_error;
         else
            In_use:= In_use - 1;
            if In_use = 0 then
               Caller := Null_task_id;
            end if;
         end if;
      end V;

   end Semaphore;

   -- Get
   procedure Initialize(this: in out Object) is
   begin
      this.S.P (Current_task);
   end Initialize;

   -- Release
   procedure Finalize(this: in out Object) is
   begin
      this.S.V (Current_task);
   end Finalize;

end Adagio.Monitor;

-- 
-------------------------
Jano
402450.at.cepsz.unizar.es
-------------------------



  reply	other threads:[~2003-05-01 12:33 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-04-29 22:04 Suspicious reentrant semaphore Jano
2003-04-30  8:06 ` Dmitry A. Kazakov
2003-05-01 12:33   ` Jano [this message]
2003-05-02  7:28     ` Dmitry A. Kazakov
2003-05-02 11:24       ` Jano
2003-05-02 20:29         ` tmoran
2003-05-05 11:24       ` Michal Morawski
2003-05-05 17:42         ` Simon Wright
2003-05-05 18:03         ` Jano
2003-05-05 20:18           ` Micha� Morawski
2003-04-30 13:07 ` Ian Broster
2003-05-01 12:33   ` Jano
2003-04-30 17:39 ` Randy Brukardt
2003-04-30 23:21   ` Peter Richtmyer
2003-05-01  4:59     ` Simon Wright
2003-05-01 12:46   ` Jano
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox