Thread View: mod.computers.masscomp
2 messages
2 total messages
Started by Stan Hanks
Mon, 23 Jun 1986 21:36
Re: Shared memory examples sought
Author: Stan Hanks
Date: Mon, 23 Jun 1986 21:36
Date: Mon, 23 Jun 1986 21:36
140 lines
4614 bytes
4614 bytes
I recently finished a similar application for a positron emision
scanner. I'm not convinced that this is the best way to solve the
problem, but it certainly is one way.
Being a casual reader of this news group (Stan Barber is a good friend
and I occasionally do joint work with him on their Masscomp) and not
normally running System V (I'm actually a Sun OEM), I can't well
include code and say "Here, this works". And as the previously mentioned
work is copyrighted and owned by the company who leased me to do it,
I can't include it either. But, here is a scetch of how it goes.
Holler if you need more detail; I'll get onto a System V machine and
pound out the details.
=============================================
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
/* 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 i;
/* allocate shared memory for 32-bit flag and 32 1K buffers */
if ((flagd = shmget((key_t)0, 4, IPC_CREAT)) == -1) {
printf("oops.\n");
exit(1);
}
if ((bufd = shmget((key_t)1, 32*1024, IPC_CREAT)) == -1) {
printf("oops.\n");
exit(1);
}
/* attach the shared memory */
if ((flag = (unsigned int *)shmat(flagd, 0, SHM_RND))) == -1) {
printf("oops.\n");
exit(1);
}
if ((buf = shmat(bufd, 0, SHM_RND))) == -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 */
while (! done) { /* hey, what did you want for nothing??? */
char sbuf[1024]; /* data that needs to be shared */
int which = 0; /* which bucket are we using now?? */
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 i;
/* attach the shared memory */
if ((xflag = (unsigned int *)shmat(xflagd, 0, SHM_RND))) == -1) {
printf("oops.\n");
exit(1);
}
if ((xbuf = shmat(xbufd, 0, SHM_RND))) == -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.... */
while (! done) {
char rbuf[1024]; /* recieved data */
int which = 0; /* which buffer ? */
/* 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);
}
}
=================================
Hope this helps.
Stan Hanks ...!drillsys!stan
Sr. Research Scientist stan@rice.ARPA
Teleco Oilfield Services, Drilling Systems Technology
Houston TX (713) 699-5594
Update on my Shared Memory Examples
Author: Stan Barber, Moderator
Date: Sat, 28 Jun 1986 07:21
Date: Sat, 28 Jun 1986 07:21
146 lines
4925 bytes
4925 bytes
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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads