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