Path: utzoo!attcan!uunet!husc6!uwvax!rutgers!iuvax!silver!cassidy
From: cassidy@silver (Patrick Cassidy)
Newsgroups: comp.os.minix
Subject: Semaphores
Message-ID: <1832@silver.bacs.indiana.edu>
Date: 1 Jun 88 18:33:23 GMT
Sender: cassidy@silver.bacs.indiana.edu
Reply-To: cassidy@silver (Patrick Cassidy)
Organization: Indiana University CSCI, Bloomington
Lines: 54


              This is in response to the postings a couple of weeks ago 
         concerning semaphores.  I have added semaphores to Minix, but have 
         not been able to throughly test them yet.  The implementation of 
         semaphores consists of 3 new memory manager system calls:  
         makesem, psem, and vsem. Makesem takes the initial semaphore value 
         as an argument, and returns an integer value which identifies the 
         new semaphore.  That returned value is then used in subsequent 
         calls to psem and vsem, much like using a file descriptor.  When 
         it is necessary to block a process doing a wait (psem), that is 
         accomplished by simply not replying to the incoming message -- as 
         is done in the Pause system call. My plan for testing involves a 
         producer/consumer type situation.  As far as I can see, the 
         producer/consumer problem requires shared memory.  Judging from my 
         experience, implementing shared memory is MUCH harder than 
         implementing semaphores themselves. 
              Can anyone suggest a way to test semaphores in Minix that 
         doesn't require shared memory?
              In the mean time, here is what my approach to shared memory 
         involves:
              1)  Adding user-to-user message passing to Minix. 
                  This is necessary to enable the process which contains 
                  the shared data structure to send a pointer to that data 
                  structure to the other sharing process(s). 
              2)  Adding a system task system call so the memory manager can
                  access umap in the kernel.
              3)  Adding a memory manager system call so user processes can 
                  access umap through the memory manager.
              These three steps have been accomplished, including the 
         addition of library routines for the new system calls.  Here's how 
         it works in a nutshell:  First, the process containing the data 
         structure sends a message to the other sharing process(s) 
         containing a pointer to the data structure.  The receiver of this 
         message also needs the sender's pid and the length of the data 
         structure, but that info can just be inherited from a fork.  Next, 
         the second process makes the new system call (#3 above) using the 
         parameters just described.  At this point the second process has 
         the value returned by the kernel function umap, (the foreign 
         pointer has been unmapped).  Having this value, the second process 
         can read and write the data structure (in the first processes' 
         address space).
              I have been using the Minix function get_byte to accomplish 
         the reading.  I haven't gotten the writing to work yet -- because 
         there isn't an analogus function "put_byte" in Minix, and I don't 
         have a good assembly language reference.
              Although it isn't well tested, I believe my semaphore code (3 
         new memory manager system calls) is essentially correct.  If 
         anyone wants the code, respond to this posting or send me mail.  
         Also, if anyone out there has a put_byte function which takes the 
         same type of arguments as get_byte in Minix (segment, offset), I 
         would appreciate hearing from them.

         Pat Cassidy
         Indiana University