REDUCE

21.5 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);  
}