andrew@gestetner.oz (Andrew Hunt) (09/21/90)
I am having problems with UNIX shared memory system functions (shmget, shmctl, shmop) - our system is SUN O/S 4.0.x. I am trying to attach some data to a shared memory identifier. assign global_start_address assign global_size global_shmid = shmget(IPC_PRIVATE,global_size,0777|IPC_CREAT); shmat(global_shmid,global_start_address,SHM_RDONLY); The shmget is always successful but the shmat fails. I have tried to assign the global_start_address to many different sizes and addresses. The addresses I have tried have been from malloc'ed memory, stack space, initialised data space, uninitialised data space.... I have experimented with changing permissions and have changed most of the parameters but the only thing that has worked is to set global_start_address = (char *)0; which allow the system to find some space for me. Does anyone know what areas of memory can be legally attached to shared memory? Thanks, Andrew Hunt PS: if it helps we are trying to set up the global data space of several UNIX processes to use common memory so that we can simulate the shared memory of an imbedded controller.
mark@DRD.Com (Mark Lawrence) (09/22/90)
andrew@gestetner.oz (Andrew Hunt) wrote: } I am having problems with UNIX shared memory system functions } (shmget, shmctl, shmop) - our system is SUN O/S 4.0.x. } I am trying to attach some data to a shared memory identifier. } } assign global_start_address } assign global_size } } global_shmid = shmget(IPC_PRIVATE,global_size,0777|IPC_CREAT); } } shmat(global_shmid,global_start_address,SHM_RDONLY); shmat returns the address. You can't tell it where you want it. Then dereference the members of interest in each process using the Psh pointer. An example: #include <sys/types.h> #include <sys/shm.h> #include <memory.h> /* +----------------------------------------------------------------- | declarations of scope process */ extern int errno; /* system call err status */ extern const char *strerror(int); typedef struct { int foo; float bar; short gex; double snark; } SHMEM; #define SHMEM_k 0x4444 /* arbitrary key */ #define SHMEM_PERMISSION 0666 /* rw-rw-rw */ SHMEM *Psh; /* +----------------------------------------------------------------- | declarations of scope file */ static int shmid; /* +----------------------------------------------------------------- | executable code begins here */ static void CrynDie(char *who, char *what) { fprintf(stderr, "\n\n%s: Fatal error from %s, %s", who, what, strerror(errno)); exit(1); } /* * The CreateShMem function is to be called only by one process at system * startup. It will create shared memory for the system. That process must * then AttachShMem. All other processes must use the AttachShMem function * only which will get and attach shared memory. */ void CreateShMem(char *caller) { SHMEM *pshmem; if ((shmid = shmget(SHMEM_k, sizeof(SHMEM), IPC_CREAT | SHMEM_PERMISSION)) == -1) CrynDie(caller, "Shared memory creation failed -- fatal error"); /* initialize the shared memory block to all NULLs */ if ((pshmem = (SHMEM *) shmat(shmid, 0, 0)) == (SHMEM *) - 1) CrynDie(caller, "attach failed"); memset((char *) pshmem, '\0', sizeof(SHMEM)); shmdt((char *) pshmem); } void AttachShMem(char *caller) { if ((shmid = shmget(SHMEM_k, sizeof(SHMEM), SHMEM_PERMISSION)) == -1) CrynDie(caller, "Get shared memory id failed"); if ((Psh = (SHMEM *) shmat(shmid, 0, 0)) == (SHMEM *) - 1) CrynDie(caller, "attach failed"); } -- mark@DRD.Com uunet!apctrc!drd!mark$B!J%^!<%/!!!&%m!<%l%s%9!K(B
cpcahil@virtech.uucp (Conor P. Cahill) (09/22/90)
In article <566@gestetner.oz> andrew@gestetner.oz (Andrew Hunt) writes: >Does anyone know what areas of memory can be legally attached to >shared memory? This is a very OS dependent portion of the code. What I usually do is attach a segment at the default address and compare the value of the pointer to the value of a malloc'd pointer (yes I know that comparing pointers to unrelated objects is not always defined). If the two are too close, I detach the segment and re-attache it at a much higher address (like 1MB higher). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/22/90)
in article <1990Sep21.183326.13116@DRD.Com>, mark@DRD.Com (Mark Lawrence) says: > shmat returns the address. You can't tell it where you want it. Then Machine dependent. > /* > +----------------------------------------------------------------- > | declarations of scope process > */ > extern int errno; /* system call err status */ > extern const char *strerror(int); I had more compile troubles w/this last line then any other in the program. I had to substitute: extern char *sys_errlist[]; and for: fprintf(stderr, "\n%s: Fatal error from %s, %s\n", who, what, strerror(errno));*/ in CrynDie, I had to substitute: fprintf(stderr, "\n%s: Fatal error from %s, %s\n", who, what, sys_errlist[errno]); to get it to compile and load on Dynix, SunOS 4.0.3, A/UX 1.1, & Ultrix 4.0. > * The CreateShMem function is to be called only by one process at system > * startup. It will create shared memory for the system. That process must > * then AttachShMem. All other processes must use the AttachShMem function > * only which will get and attach shared memory. [...] > if ((shmid = shmget(SHMEM_k, sizeof(SHMEM), > IPC_CREAT | SHMEM_PERMISSION)) == -1) [...] > memset((char *) pshmem, '\0', sizeof(SHMEM)); Just to avoid misunderstandings, these instructions are correct NOT because of the way he's calling shmget(2), but simply because he's initializing the shm seg. (Of course, he's also immediately doing a shmdt(). ) It would only be an error to call shmget(2) w/IPC_CREAT or'd in w/SHMEM_PERMISSION in the 2nd process if it ALSO had IPC_EXCL or'd in as well, as the man pages on the above systems state. I mention this because some systems guarantee that the first shmat() will zero out the shm seg. From the HP 9000/800 HP-UX Real Time Programmers Manual: [example program omitted] "Note that the fields of the tallytab entries that were not written in subroutine write_and_read_shm() have values of 0. This is because the first shmat called (by any process) on that shared memory identifier will zero out all of the contents of shared memory." I have not seen this documented in the man pages of the other above systems, altho' a simple: main() { CreateShMem("main"); /* I commented out the memset in here */ AttachShMem("main"); printf("%d %f %d %f\n",Psh->foo,Psh->bar,Psh->gex,Psh->snark); printf("%d\n",shmctl(shmid,IPC_RMID,0)); printf("main exiting\n"); exit(0); } added to the end of the posted subroutines shows all zeroes on A/UX and Ultrix. Anybody know if this is standard? -- BURNS,JIM Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332 uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a Internet: gt0178a@prism.gatech.edu
josef@nixpbe.UUCP (Moellers) (09/24/90)
In <566@gestetner.oz> andrew@gestetner.oz (Andrew Hunt) writes: >I am having problems with UNIX shared memory system functions >(shmget, shmctl, shmop) - our system is SUN O/S 4.0.x. >I am trying to attach some data to a shared memory identifier. > assign global_start_address > assign global_size > global_shmid = shmget(IPC_PRIVATE,global_size,0777|IPC_CREAT); > shmat(global_shmid,global_start_address,SHM_RDONLY); >The shmget is always successful but the shmat fails. I have tried >to assign the global_start_address to many different sizes and >addresses. The addresses I have tried have been from malloc'ed memory, >stack space, initialised data space, uninitialised data space.... >I have experimented with changing permissions and have changed most of >the parameters but the only thing that has worked is to set > global_start_address = (char *)0; >which allow the system to find some space for me. >Does anyone know what areas of memory can be legally attached to >shared memory? The system will ALLWAYS find space for You. It's YOUR task to tell it ^^^^^ where to put it. ^^^^^ The address where to put it ("global_start_address") must not result in part or all of the shared memory segment overlaying part or all of Your allocated virtual address space. So: break <= global_start_address < SP - global_size Try something like global_start_address = 0x80000000, which, on a 32 bit system, should put the shared memory segment in the middle of Your 4GB virtual address space. -- | Josef Moellers | c/o Nixdorf Computer AG | | USA: mollers.pad@nixdorf.com | Abt. PXD-S14 | | !USA: mollers.pad@nixdorf.de | Heinz-Nixdorf-Ring | | Phone: (+49) 5251 104662 | D-4790 Paderborn |
gt0178a@prism.gatech.EDU (BURNS,JIM) (09/26/90)
in article <13991@hydra.gatech.EDU>, gt0178a@prism.gatech.EDU (BURNS,JIM) says:
[deleted]
In my above reply, for some reason, it got marked as Followup:
comp.lang.c, which is NOT what I intended. I don't normally read that
group, but I suscribed to it just to find out if my question at the end of
that post got answered, and it didn't. So one more time:
HP-UX documents it; it tests out on A/UX 1.1 and Ultrix 4.0 : the first
call to shmat() (by any process) automatically zeroes out the shm seg, so
explicit initialization is NOT necessary. Is this standard? Which one?
--
BURNS,JIM
Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332
uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
Internet: gt0178a@prism.gatech.edu
cpcahil@virtech.uucp (Conor P. Cahill) (09/27/90)
In article <14140@hydra.gatech.EDU> gt0178a@prism.gatech.EDU (BURNS,JIM) writes: >HP-UX documents it; it tests out on A/UX 1.1 and Ultrix 4.0 : the first >call to shmat() (by any process) automatically zeroes out the shm seg, so >explicit initialization is NOT necessary. Is this standard? Which one? This is a basic rule of unix: All memory given to a program by the kernel must be cleared to zero. This applies to new sbrk()'d areas (not always to areas that you previously had and then released and then got back) uninitialized static data areas, and shared memory segments. It even applies to stack the first time it is used. This is a security measure (makes sure you can't see someone elses data). Note that it also applies to disk "memory" (if you seek past the end of a file, write a byte, seek back to the skipped portion and read, you will get all nulls). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
pthonda@bgsuvax.UUCP (Killer B) (02/28/91)
I am trying to use 'Shmget' call to get shared memory.I am getting the error message 'Invalid argument' even though the same program is working on Sun .Could anyone tell me what's happening on Vax 785. Thanx in advance Pratap.
pthonda@bgsuvax.UUCP (Killer B) (03/01/91)
The program given below is running fine on SPARC station, however when I tried to execute the same program on Vax 785 with Unix 4.3 BSD,Iam encountering the message "Shmget failed :Invalid argument".I tried to typecast the argumnets to call 'shmget' to the right types but the problem is still persistent. However after going through manuals I figured out that 'shmget' gives this whenever the programs specifies a shared memory segment size which is less than or greater than the system imposed limits.Could anyone tell me how to get the system information about default allowable shared memory segment sizes. Thanx in advance. Pratap. And here is the code.. /*=========================================================================*/ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #define SHMKEY (key_t)0x10 /* Establish a key for shared memory */ #define IPCFLAGS IPC_CREAT | IPC_EXCL #define RDWR 0666 #define ERROR -1 struct shmid_ds *buf ; static int shmId ; static int prId; long *shmPtr ; main(argc,argv) int argc ; char *argv[] ; { char *shmat(), *malloc() ; int retValue ; /* Get the shared memory segment */ shmId = shmget(SHMKEY,sizeof(long),RDWR|IPCFLAGS) ; if(shmId < 0) { /* It's failing here. *********/ perror("shmget failed") ; exit(ERROR) ; } /* Set the required permissions */ /* buf = (struct shmid_ds *) malloc(sizeof(struct shmid_ds)) ; buf->shm_perm.cuid = getpid() ; buf->shm_perm.mode = 0600 ; if(shmctl(shmId,IPC_SET,buf) < 0) { perror("Shmctl failed"); exit(ERROR) ; } */ /* Attach the shared memory segment */ shmPtr = (long *) shmat(shmId,0,0) ; if((char *) shmPtr == (char *)-1) { perror("Shmat failed") ; exit(ERROR) ; } /* Initialize to a value for testing ....*/ *shmPtr = 120L ; if((prId = fork()) < 0) { perror("Fork failed") ; exit(ERROR) ; } if(prId == 0) consumer() ; else producer() ; shmdt(shmPtr) ; shmctl(shmId,IPC_RMID,0) ; } int producer() { int i ; for(i = 0 ; i < 100 ; i++) { ++*shmPtr ; printf("Producer incremented. Current value is %ld\n",*shmPtr); } } int consumer() { int k ; for(k = 0 ; k < 100 ; k++) { --*shmPtr ; printf("Consumer decremented. Current value is %ld\n",*shmPtr); } }
pfalstad@phoenix.Princeton.EDU (Paul Falstad) (03/01/91)
pthonda@bgsuvax.UUCP (Killer B) wrote: >encountering the message "Shmget failed :Invalid argument".I tried to >typecast the argumnets to call 'shmget' to the right types but the >problem is still persistent. However after going through manuals I figured That has nothing to do with it, as you probably figured out. The program wouldn't have gotten past compilation if typecasting were the answer. >out that 'shmget' gives this whenever the programs specifies a >shared memory segment size which is less than or greater than the system >imposed limits.Could anyone tell me how to get the system information >about default allowable shared memory segment sizes. SunOS #defines the minimum shared memory segment size as SHMMIN, in /usr/include/sys/shm.h. Your VAX probably doesn't have this, though. A nonportable solution is to do "adb /vmunix" and type "_shminfo+4?X" to get the minimum page size in hex. If all else fails, you're probably not losing much by simply setting your shared memory segment size to whatever the page size is on your machine. -- Paul Falstad, pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD How DO you delete a file called "-"? For viewers at home, the answer is coming up on your screen. For those of you who wish to play it the hard way, stand upside down with your head in a bucket of piranha fish.