#define NULL 0 ENV /* xx_mem is a memory allocation routine. It is called in three ways: if typ == 0, then n is the number of bytes to claim as globally-shared memory (from which routines can ask for shared memory). In this case the routine returns the address of the allocated block (NULL, if an allocation failure occurs). else if typ == 1, then n is taken to be the amount of shared memory requested. In this case, the routine returns the address of a block of at least n charecters in length. else if typ == 2, then the routine is being asked to return the address of the globally- shared block of memory. The view of shared memory supported by xx_mem is that a single massive chunk of memory is acquired (and handed out by xx_mem(1,...) calls). */ struct mem_blk { char *next; int l_mem; LOCKDEC(MEM) slock_t mlock; }; char *xx_mem(typ,n) int typ,n; { char *shmalloc(); static struct mem_blk *glob_mem = (struct mem_blk *) NULL; static int l_mem = 0; char *rc; int i; char *c; switch (typ) { case 0: /* initialize */ /* pad & malloc */ if ((c = shmalloc((n+sizeof(struct mem_blk)))) == NULL) { printf("*** malloc failed during shared memory initialization ***\n"); printf("shmalloc failed asking for %d\n", (n+sizeof(struct mem_blk))); exit(3); } else { glob_mem = (struct mem_blk *) c; glob_mem->next = c + sizeof(struct mem_blk); glob_mem->l_mem = n; rc = glob_mem->next; /* glob_mem->MEM.lock = &(glob_mem->mlock); */ s_init_lock(&(glob_mem->MEM.lock)); } break; case 1: i = (n + 7) & (~007); LOCK(glob_mem->MEM) if (glob_mem->l_mem < i) { printf("*** global allocation failure ***\n"); printf("*** attempted %d bytes, %d left\n", i,glob_mem->l_mem); rc = NULL; UNLOCK(glob_mem->MEM) exit(3); } else { rc = glob_mem->next; glob_mem->next += i; glob_mem->l_mem -= i; /* B printf("allocated %d bytes of shared memory\n",i); printf("at %d\n",rc); E */ } UNLOCK(glob_mem->MEM) break; case 2: rc = (char *) glob_mem; break; default: printf("*** illegal call to xx_mem *** typ=%d\n",typ); } return(rc); }