7
* $Header: /tmp/hpctools/ga/tcgmsg/ipcv5.0/shmem.c,v 1.4 2002-01-24 22:07:27 d3h325 Exp $
9
* This stuff attempts to provide a simple interface to temporary shared
10
* memory regions, loosely modelled after that of Alliant Concentrix 5.0
13
* Note that the input arguments switch between integers and pointers
14
* to integers depending on if they are modified on return.
17
* Create a shared region of at least size bytes, returning the actual size,
18
* the id associated with the region. The return value is a pointer to the
19
* the region. Any error is a hard fail.
21
* (char *) CreateSharedRegion((long *) id, (long *) size)
24
* Detach a process from a shared memory region. 0 is returned on success,
25
* -1 for failure. id, size, and addr must match exactly those items returned
26
* from CreateSharedRegion
28
* long DetachSharedRegion((long) id, (long) size, (char *) addr)
31
* Delete a shared region from the system. This has to be done on the SUN
32
* to remove it from the system. On the Alliant the shared region disappears
33
* when the last process dies or detaches. Returns 0 on success, -1 on error.
35
* long DeleteSharedRegion((long) id)
38
* Delete all the shared regions associated with this process.
40
* long DeleteSharedAll()
43
* Attach to a shared memory region of known id and size. Returns the
44
* address of the mapped memory. Size must exactly match the size returned
45
* from CreateSharedRegion (which in turn is the requested size rounded
46
* up to a multiple of 4096). Any error is a hard fail.
48
* (char *) AttachSharedRegion((long) id, (long) size))
51
extern void Error(const char *, long);
59
# include <sys/types.h>
69
extern int shmget(key_t, int, int);
70
extern int shmdt(void *);
71
extern int shmctl(int, int, struct shmid_ds *);
72
extern void *shmat(int, const void *, int);
76
char *CreateSharedRegion(long *id, long *size)
80
/* Create the region */
82
if ( (*id = shmget(IPC_PRIVATE, (int) *size,
83
(int) (IPC_CREAT | 00600))) < 0 )
84
Error("CreateSharedRegion: failed to create shared region", (long) *id);
86
/* Attach to the region */
88
if ( (long) (temp = shmat((int) *id, (char *) NULL, 0)) == -1L)
89
Error("CreateSharedRegion: failed to attach to shared region", 0L);
95
long DetachSharedRegion(long id, long size, char *addr)
101
long DeleteSharedRegion(long id)
103
return shmctl((int) id, IPC_RMID, (struct shmid_ds *) NULL);
107
char *AttachSharedRegion(long id, long size)
111
if ( (long) (temp = shmat((int) id, (char *) NULL, 0)) == -1L)
112
Error("AttachSharedRegion: failed to attach to shared region", 0L);
123
# include <sys/time.h>
126
# include <sys/types.h>
129
# include <sys/file.h>
132
# include <sys/mman.h>
135
extern char *strdup();
136
extern char *mktemp();
139
static struct id_list_struct {
140
char *addr; /* pointer to shmem region */
141
unsigned size; /* size of region */
142
char *filename; /* associated file name */
143
int fd; /* file descriptor */
144
int status; /* = 1 if in use */
147
static int next_id = 0;
148
static char template[] = "/tmp/SHMEM.XXXXXX";
150
char *CreateSharedRegion(id, size)
155
if (next_id == MAX_ID)
156
Error("CreateSharedRegion: MAX_ID exceeded ", MAX_ID);
159
if ( (temp = strdup(template)) == (char *) NULL)
160
Error("CreateSharedRegion: failed to get space for filename", 0);
162
/* Generate scratch file to identify region ... need to know this
163
name to attach to the region so need to establish some policy
164
before AttachtoSharedRegion can work */
166
id_list[*id].filename = mktemp(temp);
167
if ( (id_list[*id].fd = open(id_list[*id].filename,
168
O_RDWR|O_CREAT, 0666)) < 0)
169
Error("CreateSharedRegion: failed to open temporary file",0);
171
id_list[*id].addr = mmap((caddr_t) 0, (size_t)*size,
172
PROT_READ|PROT_WRITE,
173
MAP_ANON|MAP_SHARED, id_list[*id].fd, 0);
174
if (id_list[*id].addr == (char *) -1)
175
Error("CreateSharedRegion: mmap failed",-1);
177
id_list[*id].size = *size;
178
id_list[*id].status = 1;
181
return id_list[*id].addr;
185
long DetachSharedRegion(long id, long size, char *addr)
187
if ( (id < 0) || (id > next_id))
190
if (id_list[id].status != 1)
193
id_list[id].status = 0;
195
return (long) munmap(id_list[id].addr, 0);
199
long DeleteSharedRegion(long id)
201
if ( (id < 0) || (id > next_id) )
204
if (id_list[id].status != 1)
207
(void) DetachSharedRegion(id, 0, (char *) 0);
209
if (id_list[id].fd >= 0) {
210
(void) close(id_list[id].fd);
211
(void) unlink(id_list[id].filename);
218
char *AttachSharedRegion(long id, long size)
220
Error("AttachSharedRegion: need mods for this to work on CONVEX",
225
long DeleteSharedAll()
230
for (id=0; id<next_id; id++)
231
if (id_list[id].status == 1)
232
status += DeleteSharedRegion(id);