[comp.sys.sun] Idiots guide to shared memory

C.Elvin@ee.surrey.ac.uk (12/12/89)

Does anybody out there have a few small, simple programs that demonstrate
the use of the shared memory facilities.  I have tried to follow the
manual pages for shmget and shmat etc etc but am unable to attach a shared
segment.  I think a few example programs would help to cure my delinquency
in this area.

system details:
	diskless 3/60 8 MBytes, OS3.5, served from 3/280S OS3.5

			Thanx
			Chris

ghfeil@white.toronto.edu (Georg Feil) (12/22/89)

In article <3906@brazos.Rice.edu> C.Elvin@ee.surrey.ac.uk writes:
>Does anybody out there have a few small, simple programs that demonstrate
>the use of the shared memory facilities.  I have tried to follow the
>manual pages for shmget and shmat etc etc but am unable to attach a shared
>segment.

Yes, it is a bitch the first time you try it. The hardest part is figuring
out where to put the segment so it doesn't interfere with sbrk() and
malloc().  Here is a code fragment that I use to do things in a
semi-reasonable way.

Note that if you put pointers into shared memory (e.g. as part of a linked
list), you must map in the shared memory at the same place in all programs
involved. The code below will probably not do this properly. The solution
I use is to run the program once using the method below, and print out the
shared memory address obtained. This can then be hard-coded into all
programs involved.

Georg.

---------------------------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_KEY      12345678    /* shared mem segment id, some big number */
#define SHM_SIZE     0x8000      /* shared mem segment size, 32K */
#define MALLOC_SIZE  0x32000     /* amount of room to leave for malloc, 200K */

extern int errno;

int main()
{
   int err;
   int shmid;                  /* shared memory ID */
   char* shared_mem;           /* address of start of shared memory */
   struct shmid_ds dummy_m;    /* dummy return value from shmctl() */
   caddr_t break_addr;         /* original position of break */
   caddr_t sbrk();

   shmid=shmget(SHM_KEY,SHM_SIZE, SHM_R | SHM_W | IPC_CREAT);
   if (shmid<0)  {
      fprintf(stderr,"shmtest: Error %d from shmget\n",errno);
      exit(1);
   }

   break_addr=sbrk(0);              /* remember original position of break */

   err=(int) sbrk(0x32000);         /* add to data area to make room for */
                                    /*   malloc free store */
   /* **Note: The gap left between the break and the start of shared memory */
   /* counts under the "missing" category of the 'pstat -s' memory display, */
   /* i.e. it is not available for other processes! */

   if (err<0)  {
      fprintf(stderr,"shmtest: Error %d from sbrk()\n",errno);
      exit(1);
   }

   shared_mem = (char*) shmat(shmid, 0, 0);  /* let system choose position */
   if ((int) shared_mem==-1)  {
      fprintf(stderr,"shmtest: Error %d from shmat\n",errno);
      exit(1);
   }

   err= brk(break_addr);       /* put break back to original position */
   if (err<0)  {
      fprintf(stderr,"shmtest: Error %d from brk()\n",errno);
      exit(1);
   }


   /*** work with shared mem here, segment starts at shared_mem ***/


   shmdt((char*) shared_mem);      /* detach memory segment */

   /* Remove shared memory segment: this should be omitted if you want the
      segment to stick around between runs. */
   err=shmctl(shmid,IPC_RMID,&dummy_m);
   if (err==-1)
      fprintf(stderr,"shmtest: error %d from shmctl()!\n",errno);
}
-- 
Georg Feil                                 Internet: ghfeil@white.toronto.edu
                                             -or-  : georg@sgl.ists.ca
...if all else fails, try:
{uunet,pyramid,watmath,utzoo}!utcsri!white!ghfeil
ghfeil%white.toronto.edu@relay.cs.net     (ARPA)