From: agc@bmdhh298.bnr.ca (Alan Carter)
Newsgroups: comp.unix.questions
Subject: Re: Shared memories
Date: 5 Oct 92 19:09:41 GMT
Organization: BNR-Europe-Limited, Maidenhead, England

In article <1992Oct1.154637.4485@news.unige.ch>, robert@divsun.unige.ch (Gilbert Robert) writes:
|> I'm a problem with the shared memories. 
|> 
|> A main process create some (9 with average size 200Ko. The SHMAX of
|> Kernel has enough been raise) SM with the shmget() and shmat functions, 
|> 	shmid = shmget(id,size,IPC_CREAT|perm)
|> 	shmad = (UNCHAR)shmat(shmid,0,0)
|> 
|> 	perm  = 0600
|> 
|> The shmid of each returns is putting in the global structure and after 
|> I call the shmdt(shmad) function for all.
|> 
|> When a client connect to this main process, a fork is done and 
|> a attach to two SM previously loaded . One is a same for all of new
|> process and the other migth be different according to the client.
|> 
|> The problem is when a second client comes, the attach to the first SM
|> return a different value (shmad) that the first client. It seems to
|> append essentialy when the second attach is different.
|> It means that the second client have the good address of memory and I 
|> don't know why, the first client have the segmentation fault.
|> 
|> for everybody have explanations and suggestions, thank you.

When shmat(2) is called UNIX will map the address of the shared memory 
region into the virtual address space of your process at a 'sensible' 
place (where 'sensible' is defined by the people who did the port). 
It is possible have two different processes with their shared memory
being in different addresses in the two processes. Exactly what the
algorithms are vary from vendor to vendor. Sometimes you can specify
an address to attach the SM and the UNIX port promises to use your 
address, but then it is up to you to calculate a suitable address.

The best solution to this problem is to never include pointers TO SM
data structures IN SM data structures. Instead change the pointers 
to offsets from the attachment address, and store them. Then the other
process will read the offset, add on whatever *it* thinks the address
of shared memory is, and then dereference the number it comes up with
as a meaningful pointer into its own shared memory.

   region = shmat(mykey, NULL, myflags); /* No error handling - very sloppy! */

   /* Set up a linked list in shared memory here */

   while(thing) /* thing is a pointer into shared memory set up somewhere */
	{
		printf("%d\n", thing->data); /* Access the data in SM */

      /* Now get the pointer out of the data structure, (which should   */
      /* be an int), cast the address of the SM to an int and add them  */
      /* together, cast the result into a pointer to THING, and we can  */
      /* then use it like any other pointer, no matter what the address */
      /* held in region may be.                                         */

      thing = (THING *)(thing->next + (int)region);
   }

   Alan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Maidenhead itself is too snobby to be pleasant. It is the haunt of the
   river swell and his overdressed female companion. It is the town of showy
   hotels, patronized chiefly by dudes and ballet girls. 

   Three Men In A Boat, Jerome K. Jerome, 1889
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~