5
/* $Header: /tmp/hpctools/ga/tcgmsg/ipcv4.0/shmem.c,v 1.13 2000-10-13 20:55:40 d3h325 Exp $ */
8
This stuff attempts to provide a simple interface to temporary shared
9
memory regions, loosely modelled after that of Alliant Concentrix 5.0
12
Note that the input arguments switch between integers and pointers
13
to integers depending on if they are modified on return.
16
Create a shared region of at least size bytes, returning the actual size,
17
the id associated with the region. The return value is a pointer to the
18
the region. Any error is a hard fail.
20
(char *) CreateSharedRegion((long *) id, (long *) size)
23
Detach a process from a shared memory region. 0 is returned on success,
24
-1 for failure. id, size, and addr must match exactly those items returned
25
from CreateSharedRegion
27
long DetachSharedRegion((long) id, (long) size, (char *) addr)
30
Delete a shared region from the system. This has to be done on the SUN
31
to remove it from the system. On the Alliant the shared region disappears
32
when the last process dies or detaches. Returns 0 on success, -1 on error.
34
long DeleteSharedRegion((long) id)
37
Delete all the shared regions associated with this process.
39
long DeleteSharedAll()
42
Attach to a shared memory region of known id and size. Returns the
43
address of the mapped memory. Size must exactly match the size returned
44
from CreateSharedRegion (which in turn is the requested size rounded
45
up to a multiple of 4096). Any error is a hard fail.
47
(char *) AttachSharedRegion((long) id, (long) size))
58
extern char *valloc();
60
char *CreateSharedRegion(id, size)
68
/* Have to round up to a multiple of page size before allocating
71
*size = ( (*size + 4095) / 4096 ) * 4096;
73
if ( (temp = valloc((unsigned) *size)) == (char *) NULL)
74
Error("CreateSharedRegion: failed in valloc", (long) 0);
76
/* Now have to get a unique id ... try using time of day in centi-sec */
78
if ( (status = gettimeofday(&tp, &tzp)) != 0)
79
Error("CreateSharedRegion: error from gettimeofday", (long) status);
81
*id = (tp.tv_sec + 10000*tp.tv_usec) & 0xffffff;
83
/* Now make the region */
85
if ( (status = create_shared_region(*id, temp, *size, 0)) != 0)
86
Error("CreateSharedRegion: error from create_shared_region", (long) status);
91
long DetachSharedRegion( id, size, addr)
95
return detach_shared_region( id, addr, size);
98
long DeleteSharedRegion(id)
101
return delete_shared_region(id);
104
char *AttachSharedRegion(id, size)
110
if (size != (((size + 4095) / 4096) * 4096))
111
Error("AttachSharedRegion: input size is not multiple of 4096",
114
if ( (temp = valloc((unsigned) size)) == (char *) NULL)
115
Error("AttachSharedRegion: failed in valloc", (long) 0);
117
/* Now try to attach */
119
if ( (status = attach_shared_region(id, temp, size)) != 0)
120
Error("AttachSharedRegion: error from attach_shared_region",
127
#if defined(SEQUENT) || defined(ENCORE) /* @**!ing SEQUENT and CRAY no elif */
132
#define SHMALLOC shmalloc
133
#define SHFREE shfree
136
#define SHMALLOC share_malloc
137
#define SHFREE share_free
140
extern char *SHMALLOC();
144
static int next_id = 0; /* Keep track of id */
145
static char *shaddr[MAX_ADDR]; /* Keep track of addresses */
147
char *CreateSharedRegion(id, size)
152
if (next_id >= MAX_ADDR)
153
Error("CreateSharedRegion: too many shared regions", (long) next_id);
155
if ( (temp = SHMALLOC((unsigned) *size)) == (char *) NULL)
156
Error("CreateSharedRegion: failed in SHMALLOC", (long) *size);
165
long DetachSharedRegion( id, size, addr)
169
/* This needs improving to make more robust */
173
long DeleteSharedRegion(id)
176
/* This needs improving to make more robust */
177
return SHFREE(shaddr[id]);
181
char *AttachSharedRegion(id, size)
184
Error("AttachSharedRegion: cannot do this on SEQUENT or BALANCE", (long) -1);
189
/* Bizarre sequent has sysv semaphores but proprietary shmem */
190
/* Encore has sysv shmem but is limited to total of 16384bytes! */
191
#if defined(SYSV) && !defined(SEQUENT) && !defined(ENCORE)
194
#include <sys/types.h>
198
char *CreateSharedRegion(id, size)
203
/* Create the region */
205
if ( (*id = shmget(IPC_PRIVATE, (int) *size,
206
(int) (IPC_CREAT | 00600))) < 0 )
207
Error("CreateSharedRegion: failed to create shared region", (long) *id);
209
/* Attach to the region */
211
if ( (long) (temp = shmat((int) *id, (char *) NULL, 0)) == -1L)
212
Error("CreateSharedRegion: failed to attach to shared region", (long) 0);
218
long DetachSharedRegion( id, size, addr)
225
long DeleteSharedRegion(id)
228
return shmctl((int) id, IPC_RMID, (struct shmid_ds *) NULL);
232
char *AttachSharedRegion(id, size)
237
if ( (long) (temp = shmat((int) id, (char *) NULL, 0)) == -1L)
238
Error("AttachSharedRegion: failed to attach to shared region", (long) 0);
244
#if (defined(CONVEX) || defined(APOLLO)) && !defined(HPUX)
247
#include <sys/time.h>
248
#include <sys/types.h>
249
#include <sys/file.h>
250
#include <sys/mman.h>
252
extern char *strdup();
253
extern char *mktemp();
256
static struct id_list_struct {
257
char *addr; /* pointer to shmem region */
258
unsigned size; /* size of region */
259
char *filename; /* associated file name */
260
int fd; /* file descriptor */
261
int status; /* = 1 if in use */
264
static int next_id = 0;
265
static char template[] = "/tmp/SHMEM.XXXXXX";
267
char *CreateSharedRegion(id, size)
272
if (next_id == MAX_ID)
273
Error("CreateSharedRegion: MAX_ID exceeded ", MAX_ID);
277
id_list[*id].fd = -1;
279
if ( (temp = strdup(template)) == (char *) NULL)
280
Error("CreateSharedRegion: failed to get space for filename", 0);
282
/* Generate scratch file to identify region ... need to know this
283
name to attach to the region so need to establish some policy
284
before AttachtoSharedRegion can work */
286
id_list[*id].filename = mktemp(temp);
287
if ( (id_list[*id].fd = open(id_list[*id].filename,
288
O_RDWR|O_CREAT, 0666)) < 0)
289
Error("CreateSharedRegion: failed to open temporary file",0);
292
id_list[*id].addr = mmap((caddr_t) 0, (unsigned *) size,
293
PROT_READ|PROT_WRITE,
294
MAP_ANON|MAP_SHARED, id_list[*id].fd, 0);
296
if (id_list[*id].addr == (char *) 0)
297
Error("CreateSharedRegion: mmap failed",-1);
299
if (id_list[*id].addr == (char *) -1)
300
Error("CreateSharedRegion: mmap failed",-1);
303
id_list[*id].size = *size;
304
id_list[*id].status = 1;
307
return id_list[*id].addr;
311
long DetachSharedRegion( id, size, addr)
315
if ( (id < 0) || (id > next_id))
318
if (id_list[id].status != 1)
321
id_list[id].status = 0;
323
return (long) munmap(id_list[id].addr, 0);
326
long DeleteSharedRegion(id)
329
if ( (id < 0) || (id > next_id) )
332
if (id_list[id].status != 1)
335
(void) DetachSharedRegion(id, 0, (char *) 0);
337
if (id_list[id].fd >= 0) {
338
(void) close(id_list[id].fd);
339
(void) unlink(id_list[id].filename);
346
char *AttachSharedRegion(id, size)
349
Error("AttachSharedRegion: need mods for this to work on CONVEX",
353
long DeleteSharedAll()
358
for (id=0; id<next_id; id++)
359
if (id_list[id].status == 1)
360
status += DeleteSharedRegion(id);