[net.unix-wizards] System V shared memory and Ultrix ?

dan@rna.UUCP (Dan Ts'o) (09/23/86)

x
	Has anyone used the System V-style shared memory facility in
Ultrix-32m (Microvax II), especially in double-buffered I/O operations ?
For example, the continuous DMA'ing in of data while DMA'ing out to
magtape. one process DMA's into shared memory and then signals the second
process for it to DMA's to magtape while the first process fills the second
buffer.

	Can someone mail me a simple C program in which to processes communicate
using these System V shared memory calls ?  Please educate a poor 4.XBSD user
to the wonders of shared memory. Thanks.

					Cheers,
					Dan Ts'o
					Dept. Neurobiology
					Rockefeller Univ.
					1230 York Ave.
					NY, NY 10021
					212-570-7671
					...cmcl2!rna!dan
					rna!dan@cmcl2.arpa

dan@rna.UUCP (Dan Ts'o) (09/24/86)

In article <547@rna.UUCP> dan@rna.UUCP (Dan Ts'o) writes:
>x
>	Has anyone used the System V-style shared memory facility in
>Ultrix-32m (Microvax II), especially in double-buffered I/O operations ?
>For example, the continuous DMA'ing in of data while DMA'ing out to
>magtape. one process DMA's into shared memory and then signals the second
>process for it to DMA's to magtape while the first process fills the second
>buffer.
>
>	Can someone mail me a simple C program in which to processes communicate
>using these System V shared memory calls ?  Please educate a poor 4.XBSD user
>to the wonders of shared memory. Thanks.
 
	Well, here I am answering my own question - sort of. I came up with a
simple shm*() program below which seems to work. However I'm still confused
about a number of the facilities of shm*(). For example, what role does "key"
play ? How do I pass the shared memory segment to non-related process ?
Perhaps what I should do (it doesn't seem to be documented) is stick a non
zero long in key and require that the communicating process shmget() with the
same key. Right ?
	Is the shared memory segment automatically destroyed if no process has
it "open" ? What constitutes the "open" - the shmget() or the shmat() ? If it
isn't destroyed then probably the shmat() is the "open" and the shmget() is
a lookup/create.
	Sorry if these questions are trivial but the documentation in Ultrix
seems scarce. I would still like to know if there are problems with using
these operations for the style of I/O mentioned above.


					Cheers,
					Dan Ts'o
					Dept. Neurobiology
					Rockefeller Univ.
					1230 York Ave.
					NY, NY 10021
					212-570-7671
					...cmcl2!rna!dan
					rna!dan@cmcl2.arpa


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

#define	NSHM	10

char *shmat();

main()
{
	key_t key;
	int size, shmflg;
	int shmid;
	int pid;
	register char *p;
	register int *v, i;

	size = NSHM * (sizeof *v);
	shmflg = IPC_CREAT + 0666;
	key = IPC_PRIVATE;
	shmid = shmget(key, size, shmflg);
	if (shmid < 0) {
		fprintf(stderr, "%d: Bad shmget(), ", shmid);
		perror("");
		exit(1);
	}
	pid = fork();
	if (pid == -1) {
		perror("Bad fork()");
		exit(1);
	}
	shmflg = SHM_RND;
	p = shmat(shmid, (char *)0, shmflg);
	if (p == (char *)-1) {
		perror("Bad shmat()");
		exit(1);
	}
	v = (int *)p;
	if (pid == 0) {
		for (i = 0; i < NSHM; i++)
			printf("%d ", v[i]);
		printf("\n");
		sleep(10);
		for (i = 0; i < NSHM; i++)
			printf("%d ", v[i]);
		printf("\n");
		exit(0);
	}
	sleep(3);
	for (i = 0; i < NSHM; i++)
		v[i] = i*i;
	sleep(10);
	exit(0);
}

jrw@hropus.UUCP (Jim Webb) (09/25/86)

> >	Has anyone used the System V-style shared memory facility in
> >Ultrix-32m (Microvax II)

Since Ultrix-32m is "supposedly" SV compatible, I will comment on how
"real" SV shared memory works.

> about a number of the facilities of shm*(). For example, what role does "key"
> play ? 

The "key" is used to generate a unique, yet reproducable, shared memory
identifier for use by the current or any other process.  One way is to
use ftok().  This function is in SV, so I am hoping it is in Ultrix...
It takes two arguments and returns a key:

		ftok(file,proj)		key=ftok("/unix",'x');
		char *file;
		char proj;

You pass it a file name and any character you choose and it diddles with
the info in the inode of the file and combines it with the character and
returns a key.  Just choose a file that doesn't change often.

>        How do I pass the shared memory segment to non-related process ?

You just use shmget() to get the shmid and then pass it to shmat().  For
example, you could do:

			key=ftok("/unix",'x');
			shmid=shmget(key,SIZE,FLAGS);
			shmat(shmid,ADDR,FLAGS);

or even: shmat(shmget(ftok("/unix",'x'),SIZE,FLAGS),ADDR,FLAGS);	:-)

> Perhaps what I should do (it doesn't seem to be documented) is stick a non
> zero long in key and require that the communicating process shmget() with the
> same key. Right ?

You got it right!  I guess the Ultrix docs are worse than the SV ones :-)

> 	Is the shared memory segment automatically destroyed if no process has
> it "open" ?

No, for several reasons.  For example, a program might want to use a 
shared memory segment for initialization data instead of a file, or,
a program might store info in a segment, exit, and come back later to
process the info.

However, there are two FLAGs (at least on my vax) SHM_CLEAR and SHM_DEST
that clear the segment on the next attach and destroy it when no one is
attached to it, respectively.  cat /usr/include/sys/shm.h to see if they
are on you machine as well.

>              What constitutes the "open" - the shmget() or the shmat() ? If it
> isn't destroyed then probably the shmat() is the "open" and the shmget() is
> a lookup/create.

There really is no "open."  shmget() creates an identifier in the kernel.
When you shmat() a segment, you utilize the resource, eg memory.
-- 
Jim Webb             "Out of phase--get help"          ...!ihnp4!hropus!jrw

dpw@rayssd.UUCP (Darryl P. Wagoner) (09/25/86)

> However I'm still confused
> about a number of the facilities of shm*(). For example, what role does "key"
> play ? How do I pass the shared memory segment to non-related process ?
> Perhaps what I should do (it doesn't seem to be documented) is stick a non
> zero long in key and require that the communicating process shmget() with the
> same key. Right ?

Let me start by saying that I am no expert on shared memory.  STDIPC(3C) is the 
System V standard for IPC.  The only routine that is currently in the stdipc
package is ftok, which when called and passed a file name and an "id", it 
returns a unique key in key_t (long int) format.  The key is based on the 
id (8 bits) minor device name (8 bits) and the inode number (16 bits).  By 
different processes knowing what file name and "id" that was passed to ftok, 
they can get the same key and therefore access the same shared memory.  The 
trick is to insure that all IPC programs adhere to this standard.  

> 	Is the shared memory segment automatically destroyed if no process has
> it "open" ? What constitutes the "open" - the shmget() or the shmat() ? If it
> isn't destroyed then probably the shmat() is the "open" and the shmget() is
> a lookup/create.

No, once shmget is called, the shared memory identifier will remain until one 
of two things happen.  First shmctl is called to remove it.  Second the system 
is rebooted.  

This is what I believe, but I could very well be wrong.  The shmget call creates
an entry for the key in a shared memory table (link list I would guess).
That contains the shared memory identifier, the key, a pointer to
the shared memory and the rest of the shared memory information.  
Shmat() attaches a segment to the shared memory identifier.

The question that I have is, if you call shmat with the address of a 
segment in your program, will that segment dry up and blow away when you 
program exited.  I know the shared memory identifier will remain.

> 	shmflg = IPC_CREAT + 0666;
> 	key = IPC_PRIVATE;

	key = ftok("/usr/bin/lint",'a');  
	/* if the file is change (as in remove then recreated) it will change
		the key that is returned */

Damn it Jim, I am a programmer, not a Englist Major

	Darryl Wagoner
	Raytheon Co.; Portsmouth RI; (401)-847-8000 x4089

best path             {allegra|gatech|mirror|raybed2}  ---------\
next best             {linus|ihnp4|pyrbos} ---------------------->!rayssd!dpw
if all else fails     {brunix|cci632} -------------------------/

-- 
	Darryl Wagoner
	Raytheon Co.; Portsmouth RI; (401)-847-8000 x4089

best path             {allegra|gatech|mirror|raybed2}  ---------\
next best             {linus|ihnp4|pyrbos} ---------------------->!rayssd!dpw
if all else fails     {brunix|cci632} -------------------------/

rml@hpfcdc.HP.COM (Bob Lenk) (09/26/86)

> > 	Is the shared memory segment automatically destroyed if no process has
> > it "open" ?
> 
> However, there are two FLAGs (at least on my vax) SHM_CLEAR and SHM_DEST
> that clear the segment on the next attach and destroy it when no one is
> attached to it, respectively.  cat /usr/include/sys/shm.h to see if they
> are on you machine as well.

These flags are in <sys/shm.h> on System V implementations, but they are
not documented or accessable to the user (eg. through shmget or shmctl).
The only way to get something like what was requested is to explicitly
remove the segement (with shmctl (,IPC_RMID,)); this must be done after
the last attach (as subsequent attaches will fail).  What the implementation
does, if any processes have the segement attached at the time of the IPC_RMID,
is to set the SHM_DEST bit.  On the last detach, the segment is actually
destroyed.  

			Bob Lenk
			{ihnp4, hplabs}!hpfcla!rml

dan@rna.UUCP (Dan Ts'o) (09/27/86)

In article <168@rayssd.UUCP> dpw@rayssd.UUCP (Darryl P. Wagoner) writes:
>System V standard for IPC.  The only routine that is currently in the stdipc
>package is ftok, which when called and passed a file name and an "id", it 
>returns a unique key in key_t (long int) format.  The key is based on the 
>id (8 bits) minor device name (8 bits) and the inode number (16 bits).  By 
>different processes knowing what file name and "id" that was passed to ftok, 
>they can get the same key and therefore access the same shared memory.  The 
>trick is to insure that all IPC programs adhere to this standard.  
	Since ftok() doesn't make use of the major device number, I would think
that one could get screwed.
	Also it appears that ftok() returns -1 if it can't stat() the filename
which is reasonable except that the user program had better check for it before
blindly giving it to sh*() otherwise many segments will have -1 as the key.
ftok() should probably be smarted than this if it is truly going to be the
standard convention for creating key_t's.
	Thanks for all the sh*() hints. In particular, thanks for reminding
me about ftok(). The reason that I had "forgotten" about ftok() is that it
doesn't appears to be in the older System V manuals and Ultrix-32 has stuck
ftok(3C) in the C (compatibility) section of the manual without any cross-
reference.