comp.lang.ada
 help / color / mirror / Atom feed
From: Natasha Kerensikova <lithiumcat@instinctive.eu>
Subject: Termination of tasks waiting on a protected queue
Date: Sun, 18 May 2014 07:32:17 +0000 (UTC)
Date: 2014-05-18T07:32:17+00:00	[thread overview]
Message-ID: <slrnlngofv.i0l.lithiumcat@nat.rebma.instinctive.eu> (raw)

Hello,

I have been having a task termination issue, and I'm wondering whether I
got my design wrong or whether I'm missing something, so I ask you to
help me on that.

The basic need is delegating potentially long jobs to a dedicated task
(or pool of tasks) so that the program flow generating the jobs and
continue quickly. I furthermore assume that the jobs are "fire and
forget", that there is no need to report anything about completion (or
lack of thereof) to the code that generated the jobs (or more
realistically, that reporting is performed through channels outside of
the scope of the problem).

So I went with the basic design below:

   package Example is
      type Job_Description is private;

      function Create_Job (...) return Job_Description;
      procedure Enqueue_Job (Job : in Job_Description);

   private

      package Job_Lists is new Ada.Containers.Doubly_Linked_Lists
        (Job_Description);

      protected Queue is
         procedure Append (Job : in Job_Description);
         entry Get_Next (Job : out Job_Description);
      private
         List : Job_Lists.List;
         Has_Job : Boolean := False;
      end Queue;

      task Worker is
      end Worker;
   end Example;

   package body Example is
      procedure Enqueue_Job (Job : in Job_Description) is
      begin
         Queue.Append (Job);
      end Enqueue_Job;

      protected body Queue is
         procedure Append (Job : in Job_Description) is
         begin
            List.Append (Job);
            Has_Job := True;
         end Append;

         entry Get_Next (Job : out Job_Description)
            when Has_Job is
         begin
            Job := List.First_Element;
            List.Delete_First;
            Has_Job := not List.Is_Empty;
         end Get_Next;
      end Queue;

      task body Worker is
         Job : Job_Description;
      begin
         loop
            Queue.Get_Next (Job);
            <actually to the job>
         end loop;
      end Worker;
   end Example;

As you might have guessed, I have recently read a lot of material about
Ravenscar profile, and as far as I can tell this example does match the
profile, even though the original need happens in a much more relaxed
environment.

For example, without Ravenscar restrictions, the Worker task could
easily be turned into a task type, and use an array of them to
implement a pool of workers.

The problem is, how to terminate cleanly the worker tasks in a
non-Ravenscar environment when the main application is completed?

From my understanding of ARM 9.3, I need a terminate alternative in the
worker tasks. But those can only exist in selective accepts, so I have
to turn things around and make the task wait for one of its entries to
be called, rather than wait for an external protected entry.

But then, how can a worker task entry be used to solve my problem? A
protected operation cannot call a task entry, because it's potentially
blocking. The job generator cannot call the entry directly, because it
would block when the task is not ready, so I still need a queue between
the generator and the worker task.

Alternatively, I could use a special value for Job_Description (or a new
out parameter) to make the worker exit its infinite loop, and somehow
make the protect Queue object aware that the master is completed, so
that it can signal the worker task(s) to complete. But how can this be
implemented? Since the tasks block the finalization of the master, I
can't rely on a Finalize procedure to notify the protected object.


Thanks in advance for your help,
Natasha

             reply	other threads:[~2014-05-18  7:32 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-18  7:32 Natasha Kerensikova [this message]
2014-05-18  9:24 ` Termination of tasks waiting on a protected queue anon
2014-05-18 19:43   ` Natasha Kerensikova
2014-05-18 17:16 ` Jeffrey Carter
2014-05-18 19:54   ` Natasha Kerensikova
2014-05-18 21:54     ` Jeffrey Carter
2014-05-18 18:42 ` sbelmont700
2014-05-18 18:48   ` Jeffrey Carter
2014-05-18 20:51     ` sbelmont700
2014-05-18 21:44       ` Jeffrey Carter
2014-05-19 21:49   ` Randy Brukardt
2014-05-20  7:54     ` Dmitry A. Kazakov
2014-05-20  7:58       ` Dmitry A. Kazakov
2014-05-18 23:05 ` Brad Moore
2014-05-19  7:28   ` Natasha Kerensikova
2014-05-27 11:08   ` Alejandro R. Mosteo
2014-05-28  1:04     ` Brad Moore
replies disabled

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