comp.lang.ada
 help / color / mirror / Atom feed
From: "Nick Roberts" <nick.roberts@acm.org>
Subject: Re: Advantages
Date: Sun, 27 Jun 2004 16:16:59 +0100
Date: 2004-06-27T16:16:59+01:00	[thread overview]
Message-ID: <2k86nbF18idtrU1@uni-berlin.de> (raw)
In-Reply-To: mailman.165.1088318818.391.comp.lang.ada@ada-france.org

"Andrew Carroll" <andrew@carroll-tech.net> wrote in message
news:mailman.165.1088318818.391.comp.lang.ada@ada-france.org...

> ... What features of Ada make it easier to detect pitfalls
> in parallel programming?  What features of Ada help with
> debugging?

I don't wish to cross with Marin in answering this, but forgive me if I
throw my oar in a bit.

Suppose I have two threads (another name for 'tasks') which both need to
read a variable (which is a struct (record)) from time to time, and one of
them also updates the variable from time to time. When an update is done, it
involves assigning values to several of the variable's members (components),
so the update is not 'atomic'. This means that there needs to be some kind
of synchronisation between the threads, to prevent one thread trying to read
the variable right in the middle of it being updated.

In most programming languages, including C for example, under a typical
execution environment or OS, the usual or only way to do this will be by the
explicit use of semaphores (or a similar facility). When a thread wants to
read or update the variable, it sets the semaphore (which may cause it to
wait (to be 'blocked')). When it has finished, it resets the semaphore
(which may unblock another waiting thread). Let's say the function to set a
semaphore is named 'sem_p', and the function to reset it is 'sem_v'. If the
variable is named 'r' (and has members 'x' and 'y') and the semaphore is
named 's', a C program might contain code like this:

   /* Thread A */
   ...
   sem_p(s); /* set the semaphore, maybe wait */
   x = r.x; y = r.y; /* read the variable */
   sem_v(s); /* reset the semaphore */
   ...

   /* Thread B */
   ...
   sem_p(s); /* set the semaphore, maybe wait */
   r.x = x; r.y = y; /* update the variable */
   sem_v(s); /* reset the semaphore */
   ...

This is all well and dandy, but there are many things that can go wrong. For
example, supposing a programmer accidentally omitted one of the calls to
sem_p or sem_v? Or accidentally used the wrong semaphore in one of the
calls? This kind of mistake is easily done in a big, complex program with
lots of threads and semaphores. The consequences are often hard to debug: it
is typical that a problem is only manifested intermittently; it is typical
that using a debugger (single stepping or breakpoint jumping) destroys the
temporal circumstances of normal execution that are needed to observe the
problem at all; it is typical that, even when the problem is observed, the
cause is subtle and very hard to determine.

In Ada 95, you would typically use a protected object to protect the
variable from unwanted parallel access. (In Ada 83 you would typically have
used a task and a 'rendezvous', but I'll illustrate the protected object
approach here.)

   type R_Type is
      record
         X, Y: Float;
         ...
      end record;

   protected Prot_R is
      function Get return R_Type;
      procedure Set (New_R: in R_Type);
   private
      Inner_R: R_Type;
   end;

   protected body Prot_R is

      function Get return R_Type is
      begin
         return Inner_R;
      end;

      procedure Set (New_R: in R_Type) is
      begin
         Inner_R := New_R;
      end;

   end Prot_R;

   ...
   --- in task A
   declare
      Local_R: R_Type;
   begin
      Local_R := Prot_R.Get; -- read variable
      X := Local_R.X;
      Y := Local_R.Y;


   ...
   --- in task B
   Prot_R.Set((X,Y,...)); -- update variable

Because the use of OS primitives such as semaphores is hidden from the user
by Ada, many of the mistakes that would be easy to make in the C code are
either impossible -- for example, we cannot omit a call to set or reset a
semaphore, since Ada does these for us invisibly -- or caught by the
compiler and reported to us in an obvious way -- for example, if we tried to
use 'Inner_R' in an expression in task A or B, the compiler would complain
that Inner_R is not visible at that point (because it is private to Prot_R).

Obviously this example is simplistic compared to real software, but I hope
it gives a flavour of Ada's advantages in concurrent programming.

You might like to note that the use of an Ada protected object gives further
advantages than I have mentioned so far. It is implemented in such a way
that functions are permitted to be parallel with one another (but not with
any procedure). So, tasks A and B would be permitted to read Prot_R
simultaneously, but no task would be allowed to read it while another was in
the middle of setting it. Protected objects can provide yet more
sophisticated functionality (with 'entries'). And then there are tasks,
rendezvouses, and various other facilities too. All of this functionality
can be achieved in other languages, but generally only at a lower and more
error-prone level.

Really, one could write a big book about concurrent programming in Ada.
Hehe, in fact I'm sure somebody has! I'm sorry, I can't recall the details,
but I'm sure someone else will oblige.

-- 
Nick Roberts





  reply	other threads:[~2004-06-27 15:16 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-06-27  7:04 Advantages Andrew Carroll
2004-06-27 15:16 ` Nick Roberts [this message]
2004-06-27 21:22   ` Advantages Pascal Obry
2004-06-28  0:51   ` Advantages Robert I. Eachus
2004-06-28  1:59     ` Advantages Brian May
2004-06-29  0:24       ` Advantages Randy Brukardt
2004-06-29  3:32         ` Advantages Hyman Rosen
2004-06-29 18:41           ` Advantages Randy Brukardt
2004-07-02  0:49             ` Advantages Brian May
2004-07-02  1:31               ` Advantages Jeffrey Carter
2004-07-02  9:13               ` Advantages Dmitry A. Kazakov
2004-07-02 12:27               ` Advantages Marin David Condic
2004-07-04 17:42       ` Advantages Robert I. Eachus
2004-06-28 12:08   ` Advantages Marin David Condic
2004-06-27 18:32 ` Advantages Jim Rogers
  -- strict thread matches above, loose matches on Subject: below --
2004-06-28  9:52 Advantages Lionel.DRAGHI
     [not found] <20040628005515.0A1E74C4160@lovelace.ada-france.org>
2004-06-28  6:23 ` Advantages Andrew Carroll
2004-06-28 14:44   ` Advantages Jacob Sparre Andersen
2004-07-04 18:11   ` Advantages Robert I. Eachus
2004-06-26  6:28 Advantages Andrew Carroll
2004-06-25 19:41 Advantages Andrew Carroll
     [not found] <20040624170516.B4DFC4C4110@lovelace.ada-france.org>
2004-06-25 12:24 ` Advantages Andrew Carroll
2004-06-25 12:22   ` Advantages Peter Amey
2004-06-26 20:43   ` Advantages Marin David Condic
replies disabled

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