[comp.sys.amiga.programmer] Semaphors.

navas@cory.Berkeley.EDU (David C. Navas) (01/31/91)

Previously yorkw@stable.ecn.purdue.edu (Willis F York) writes:
>
>What's a Semaphore? a Signal of some type eh.. I use "showlist.rexx"
>and it displayes all semephores, but there are never any..

Oh there may be some, but they may not be public.  A semaphore is a signal
only in the English language -- SignalSemaphore is indicative of how they
are implemented.  The semaphore would need to be added to the public list
of semaphores before it was recognized (but not necessarily before it
was used).

>Why use one? I guess one program would say... I need the "colors"
>of the WB to be unchanged so i'll "LOCK" them "UP" 
>(Like preferences would do?) then "unlock" the when it's done?

Well, but then the protocol for changing colors on a viewport would have to
be changed.

WARNING:  Long example ahead written from fried memory cells.  Proceed with
	  caution.

Say I have a program with two tasks -- a Word Processor and a Print Spooler.
Now for some bizaare reason the Word Processor task needs to directly diddle
with some internal structures of the Print Spooler.  Perhaps it needs to
obtain a list of spooled documents.

Unfortunately, whilst looking at this linked list, the spooler may remove
the element of the list that you were currently looking at -- and what you
thought was part of a list, isn't anymore.  In the past such operations were
arbitrated by Forbid() and/or Disable().  Hence while your Word Processor was
looking at the print spool list, the print spooler would not be able to
remove the element, as it [and EVERYTHING else in the system] would not be
able to get any cycles to do ANYTHING.

Now, this sucks.  Just to look at a system structure you have to lock out
every other task in the system.  Even if the probablity is low that a
conflict would arise.  Semaphores were created to solve this problem.

[Note, the particular use of semaphors in this example will naturally restrict
 the strict meaning of a semaphore.  If you're interested there are many fine
 books written on the subject.]

A semaphore (in this instance) is an entity that can be owned by a single
requesting task.  Once a semaphore is owned, anyone else trying to lock the
semaphore will wait until said semaphore is available.

In our example we may do something like the following:

struct SharedList {
   struct List list;
   struct Semaphore sem;
};

DiddleWithPrintSpoolList()
{
   struct Node *node;

   ObtainSignalSemaphore( &SpoolerSharedList->sem);
   for(node = SpoolerSharedList->list.head; node->ln_Succ; node = node->ln_Succ)
      printf("spooled: %s\n", node-.ln_Name);
   ReleaseSignalSemaphore( &SpoolerSharedList->sem);
}

And in the spooler we may have code like:

struct Node *GetNextSpoolTask()
{
   struct Node *node;

   ObtainSignalSemaphore( &SpoolerSharedList->sem);
   node = RemHead( &SpoolerSharedList->list);
   ReleaseSignalSemaphore( &SpoolerSharedList->sem);
   return node;
}

IN this case we have "semaphored" the list structure.  If the print spooler
tries to GetNextSpoolTask() while the word processor is Diddle()ing the
list, the Print Spool task will pause in the ObtainSignalSemaphore() until
the Word Processor calls ReleaseSignalSemaphore().  The reverse case is true.

The way in which the task is notified to wake up is with a Signal.  Hence
the name SignalSemaphore.  The Amiga also has a more general purpose
semaphore capability via the Procure() Vacate() mechanism -- but I'll
refer you to the RKM's.

I hope that answered your question without boring the rest of you...

>yorkw@ecn.purdue.edu  Willis F York    

David Navas                                   navas@cory.berkeley.edu
"The crudest form of a working program is a program that doesn't work." -me
[Senior EECS major.  Also try c186br@holden, c260-ay@ara and c184-ap@torus]