comp.lang.ada
 help / color / mirror / Atom feed
From: "Nick Roberts" <nickroberts@adaos.worldonline.co.uk>
Subject: Re: How to avoid unreferenced objects (mutexes etc)
Date: Tue, 15 Jan 2002 18:59:16 -0000
Date: 2002-01-15T18:59:16+00:00	[thread overview]
Message-ID: <a21u43$u3f33$2@ID-25716.news.dfncis.de> (raw)
In-Reply-To: 3c429d1c.2624281@News.CIS.DFN.DE

"Dmitry A. Kazakov" <dmitry@elros.cbb-automation.de> wrote in message
news:3c429d1c.2624281@News.CIS.DFN.DE...

> ...
> Maybe I should describe the problem. There is a communication channel
> implemented as a tagged type. The base type provides low-level I/O
> operations. It has read and write tasks serving as monitors. The
> problem is with the derived types [potentially an arbitrary number of
> them]. They extend the base type and  provide layered high-level
> operations.

I'm not too keen on this approach, because this way the higher levels do not
'hide away' the lower-level interface. Normally, it would be better for a
distinctly higher-level interface to be based on a different type (not a
derived one).

> Some of them must lock the channel [either read or write
> one]. A "natural" solution would be to extend monitors, but alas tasks
> are not tagged.

But the tagged type could contain a component of a task type.

> An untagged solution requires an increasing number of
> wrapping subroutines [thus run-time penalty].

I really don't understand why there should be a greater time penalty for
this solution. I think possibly this is a misunderstanding that lies at the
heart of your problems.

> A genericity-based
> solution produces a combinatoric explosion of packages used as the
> parameters for other packages etc. They must be instantiated at the
> library level. In other words it is a mess.

I don't really see generics being directly relevant to the problem here.

> So I chose the lesser evil = mutexes with all that nasy problems of
> error recovery, you have pointed. I really do not like it.

Please find below an outline skeleton of what a simple communications
hierarchy might look like in Ada. It is merely a guess at what you need, and
it even then is merely a suggestion of how to do it.

=====
-- Abstract level: hardware devices in general

with Ada.Finalization;
package Devices is
   type Abstract_Device is abstract Limited_Controlled with private;
   procedure Reset (Device: access Abstract_Device) is abstract;
   ...
private
   ...
end Devices;

=====
-- Abstract level: communications devices

package Devices.Communications is
   type Byte_Array is ...;
   type Communication_Device is abstract new Abstract_Device with private;
   procedure Read (Transceiver: access Communication_Device;
                   Data: out Byte_Array;
                   Last: out Natural) is abstract;
   procedure Write (Transceiver: access Communication_Device;
                    Data: in Byte_Array) is abstract;
   ...
private
   ...
end Devices.Communications;

=====
-- Low concrete level: my particular communications hardware

with Devices.Communications;
with My_Stuff.Hardware;
package My_Stuff.My_Comms is
   type My_Comms_Device_X is
      new Devices.Communications.Comuunications_Device with private;
   ...
private
   task type Reception_Monitor is
      entry Read (Data: ...);
      entry Reset (Port: in My_Stuff.Hardware.Port_Number);
      entry Stop;
   end;
   task type Transmission_Monitor is
      entry Write (Data: ...);
      entry Reset (Port: in My_Stuff.Hardware.Port_Number);
      entry Stop;
   end;
   ... etc
   type Communications_Device is abstract new Abstract_Device with
      record
         R_Mon: Reception_Monitor;
         T_Mon: Transmission_Monitor;
         ...
      end record;
   procedure Reset (...);
   procedure Read (...);
   procedure Write (...);
   procedure Initialize (...);
   procedure Finalize (...);
   ...
end My_Stuff.My_Comms;

=====
-- Higher level: a communications facility for application programs

with My_Stuff.My_Comms;
with Ada.Streams.Stream_IO;
package Utility.Intercom is
   type Socket_Type is limited private;
   procedure Open (Socket: in out Socket_Type;
                   Name:   in     String;
                   Form:   in     String := "");
   procedure Reset (Socket: in out Socket_Type);
   procedure Close (Socket: in out Socket_Type);
   function Input_Stream  (Socket: in Socket_Type)
               return Ada.Streams.Stream_IO.Stream_Access;
   function Output_Stream (Socket: in Socket_Type)
               return Ada.Streams.Stream_IO.Stream_Access;
private
   ...
end Utility.Intercom;

=====

Note the embedding of two tasks, R_Mon and T_Mon, acting as input and output
monitor respectively, as components within a tagged type.

These tasks would be programmed to buffer the byte stream passing through
them, so as to help 'smooth out the bumps' that you inevitably get as
differences in the rate at which other tasks will produce or consume data.

On a single-processor system, they will act like passive synchronisation
mechanisms (but that's okay); on a multi-processor system they could
actually help to increase the efficiency (speed) of the overall system,
possibly quite dramatically, because they can be busily receiving and
buffering data (R_Mon) and sending buffered data (T_Mon) while other tasks
are busy doing other things.

Also notice how I use successive derivations from a tagged type to evolve
from an abstract level to a concrete one (where the theme is promises made
and promises kept), but I use different types to evolve from a low level to
a higher one (where the theme is the progressive hiding away of nasty
nitty-gritty details).

Hope this helps in some way.

--
Best wishes,
Nick Roberts






  parent reply	other threads:[~2002-01-15 18:59 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-01-11 13:48 How to avoid unreferenced objects (mutexes etc) Dmitry A. Kazakov
2002-01-11 13:52 ` Lutz Donnerhacke
2002-01-11 14:47 ` Robert A Duff
2002-01-11 18:02 ` Jeffrey Carter
2002-01-11 19:40 ` Robert Dewar
2002-01-12 10:18   ` Martin Dowie
2002-01-14  8:54   ` Dmitry A. Kazakov
2002-01-12  1:11 ` Nick Roberts
2002-01-12 22:04   ` Matthew Heaney
2002-01-13  5:45     ` Nick Roberts
2002-01-13  8:21       ` tmoran
2002-01-13 16:12         ` Nick Roberts
2002-01-13 15:08       ` Simon Wright
2002-01-15 17:53         ` Nick Roberts
2002-01-13 16:51       ` Jeffrey Carter
2002-01-14 23:32       ` Matthew Heaney
2002-01-15  8:53         ` Dmitry A. Kazakov
2002-01-14  8:31     ` Jean-Pierre Rosen
2002-01-14  9:42   ` Dmitry A. Kazakov
2002-01-15 15:41     ` Matthew Heaney
2002-01-15 16:18       ` Hyman Rosen
2002-01-15 16:57       ` Darren New
2002-01-15 18:57         ` Matthew Heaney
2002-01-16  0:57           ` Darren New
2002-01-16 16:35             ` Stephen Leake
2002-01-16 18:07               ` Darren New
2002-01-16 23:18                 ` Matthew Heaney
2002-01-16 23:04             ` Matthew Heaney
2002-01-17  0:21               ` Darren New
2002-01-16 15:18       ` Dmitry A. Kazakov
2002-01-15 18:59     ` Nick Roberts [this message]
2002-01-16 15:05       ` Dmitry A. Kazakov
2002-01-16 18:30         ` Matthew Heaney
2002-01-17  8:58           ` Dmitry A. Kazakov
2002-01-17  9:19             ` Lutz Donnerhacke
2002-01-17 10:42               ` Dmitry A. Kazakov
2002-01-17 10:55                 ` Lutz Donnerhacke
2002-01-17 15:30                   ` Dmitry A. Kazakov
2002-01-17 16:29                     ` Lutz Donnerhacke
2002-01-16 20:28         ` Robert A Duff
2002-01-17 19:05         ` Nick Roberts
replies disabled

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