[mod.computers.masscomp] Update on my Shared Memory Examples

masscomp@soma.UUCP (Stan Barber, Moderator) (06/28/86)

Thanks to Guy Harris at Sun Microsystems for pointing out 3 problems
with  my shared memory examples. 

1) The BIT macro needed to be surrounded by parentheses

2) The variable "which" couldn't be declared and initialized inside 
   the loops as "which" would then be initialized to zero each time
   around the loop

3) As the third argument to "shmget" included IPC_CREAT, it was 
   required to specify the permissions of the shared memory segment


Guy also enclosed an updated copy of the code, which follows with
only a couple of other  changes

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

extern char *shmat();
extern int shmctl();
extern int shmdt();
extern int shmget();

/* warning! good for 32 bit unsigned only !!!! */
#define BIS(flag, bit)	(flag |= (1<<bit))
#define BIC(flag, bit)	(flag &= ^(1<<bit))
#define BIT(flag, bit)  (flag & (1<<bit))
#define INCMOD32(flag)	flag = (++flag % 32)

main()
{
	int flagd, bufd;		/* shared mem descriptors */
	char         *buf;		/* pointer to the buffer  */
	char         *buff[32];		/* sub-pointers to buffer */
	unsigned int *flag;		/* busy flags for buffer  */
	int which;			/* which bucket are we using now?? */
	int pid;			/* process ID of child    */
	int i;

	/* allocate shared memory for 32-bit flag and 32 1K buffers */
	if ((flagd = shmget((key_t)0, 4, IPC_CREAT|0600)) == -1) {
		printf("oops.\n");
		exit(1);
	}
	if ((bufd = shmget((key_t)1, 32*1024, IPC_CREAT|0600)) == -1) {
		printf("oops.\n");
		exit(1);
	}

	/* attach the shared memory */
	if ((flag = (unsigned int *)shmat(flagd, (char *)0, SHM_RND)) == (unsigned int *)-1) {
		printf("oops.\n");
		exit(1);
	}
	if ((buf = shmat(bufd, (char *)0, SHM_RND)) == (char *)-1) {
		printf("oops.\n");
		exit(1);
	}

	/* clear the shared flags -- this is important!!! */
	*flag = 0;
	/* build array of 1K buffers */
	for (i=0; i<32; i++) buff[i] = buf + i*1024;

	/* pause to procreat */
	switch (pid = fork()) {
		case -1:
			printf("oops.\n");
			exit(1);
			break;
		case  0:
			do_child_stuff(flagd, bufd);
			break;
		default:
			break;
	}

	/* parent now stuffs things into shared memory */
	which = 0; 		 /* start with first buffer */
	while (! done) {	 /* hey, what did you want for nothing??? */
		char sbuf[1024]; /* data that needs to be shared */

		if (BIT(*flag, which)) {
			printf("Yow! We wrapped around. Abandon program\n");
			exit(1);
		}
		get_stuff_to_be_shared(sbuf);
		bcopy(sbuf, buff[which], 1024); /* bcopy(from, to, nbytes) */
		BIS(*flag, which);		/* set busy bit */
		INCMOD32(which);		/* move to next bucket */
	}
}

/* here we are in another process, waiting on this data to arrive */
do_child_stuff(xflagd, xbufd)
int xflagd, xbufd;
{
	char *xbuf;
	char *xbuff[32];
	unsigned int *xflag;
	int which;			/* which bucket are we using now?? */
	int i;
	
	/* attach the shared memory */
	if ((xflag = (unsigned int *)shmat(xflagd, (char *)0, SHM_RND)) == (unsigned int *)-1) {
		printf("oops.\n");
		exit(1);
	}
	if ((xbuf = shmat(xbufd, (char *)0, SHM_RND)) == (char *)-1) {
		printf("oops.\n");
		exit(1);
	}
	/* build array of 1K buffers */
	for (i=0; i<32; i++) xbuff[i] = xbuf + i*1024;

	/* here we go.... */
	which = 0;		 /* start with first buffer */
	while (! done) {
		char rbuf[1024];	/* recieved data */

		/* we process in the same order as we fill, so */
		/* as to provide the same data ordering        */
		/* this also provides synchronization and      */
		/* eliminates the need for more serious mutex  */
		/* protocols. this of course changes if the    */
		/* data rates cause overruns                   */

		while(! BIT(*xflag, which))
			;			/* busy wait */
		bcopy(xbuff[which], rbuf, 1024);/* retrieve data */
		BIC(*xflag, which);		/* clear busy bit */
		INCMOD32(which);		/* look at next bucket */
		do_stuff_with_data(rbuf);
	}
}

======================================================================

Stan Hanks					...!drillsys!stan
Sr. Research Scientist				stan@rice.ARPA
Teleco Oilfield Services, Drilling Systems Technology
Houston TX					(713) 699-5594