
26.10     Shared Memory Interface (Unix only)
The PSL shared memory interface provides all function for operating with shared memory regions
and semaphores (See e.g. Unix man pages for shmop,shmget,shmctl,semop,semctl,semget
etc.) The definitions of these man pages are used in the paragraph. Using the memory
address map mechanism described below,it is easy to write one’s own shared memory
application.
In the rest of this paragraph we describe a simple model implementation of a ’pipe’ using
shared memory and a semaphore. This code is contained in the file $pu/shmem.sl.
(shm!-open S:pair M:Mode): any                          expr
      
      - If  S  =  0  a  new  shared  memory  area  is  allocated.  Otherwise  S  is  expected
      to  be  a  dotted  pair  of  shmid  and  semid  of  an  existing  shared  memory.  Legal
      modes are input_create, output_create, input and output. A list consisting of
      channelnumber shmid and semid is returned.
 
(independentdetachshm C:channel): any                   expr
      
      - Detaches the shared memory region used by C, closes the channel.
 
(readfromshm C:channel): any                            expr
      
      - Waits until the shared memory region is readable, reads an expression and resets
      the mode to writable. Returns the expression.
 
(writetoshm C:channel E:expression): list               expr
      
      - Waits until the shared memory region is writeable, prints the expression using prin2.
      Returns the value of prin2.
 
The following C program works together with the PSL part such that it prints the
messages read from shared memory when they are ready for printing. It must be started
with two paramemters, namely the shmid and the semid to synchronize with the PSL
part.
 
#include <stdio.h>
 
#include <sys/types.h>
 
#include <sys/ipc.h>
 
#include <sys/sem.h>
 
 
struct sembuf ;
 
 
struct sembuf sembu;
 
struct sembuf ⋆sembuptr;
 
 
main (argc,argv)
 
     int argc;
 
     char ⋆argv[];
 
 
{ int sema , shmemid;
 
  char ⋆ shmaddress;
 
 
  sembuptr = &sembu;
 
 
  sscanf(argv[1],"%d",&shmemid);
 
  sscanf(argv[2],"%d",&sema);
 
 
  /⋆ open shared memory ⋆/
 
 
 printf("the data is : %d %d\n",shmemid,sema);
 
  shmaddress = shmat(shmemid,0,0);
 
 
  while (1)
 
  { waitsema(sema) ; /⋆ wait for a 0 ⋆/
 
    printf("the message is : %s \n",shmaddress +4);
 
    setsema (sema,2) ; /⋆ ok, eaten ⋆/
 
  }
 
}
 
 
setsema (sema,val)
 
int sema,val;
 
{ semctl(sema,0,SETVAL,val); }
 
 
waitsema (sema)
 
 
int sema;
 
{
 
  sembu.sem_num =0; sembu.sem_op = 0; sembu.sem_flg =0;
 
 
  semop (sema, sembuptr , 1);
 
}