📄 p4_md.c
字号:
#include "p4.h"#include "p4_sys.h"/* --------- Most Machine Dependent Stuff is in this file */#if defined(ALLIANT) && defined(USE_XX_SHMALLOC)char *xx_shmalloc();P4VOID xx_shfree();P4VOID xx_init_shmalloc();#endif#if defined(KSR) && defined(USE_XX_SHMALLOC)char *xx_shmalloc();P4VOID xx_shfree();P4VOID xx_init_shmalloc();#endif#ifdef SYSV_IPCvoid p4_shmat_errmsg ( int );void p4_shmat_errmsg( x )int x;{ switch (errno) { case EACCES: fprintf( stderr, "shmat called failed:\n\This process is not allowed to create shared memory.n\See your system administrator\n" ); break; case EMFILE: fprintf( stderr, "shmat called failed:\n\This process is not allowed to create any more shared memory regions\n\See your system administrator\n"); break; default: perror( "Reason " ); break; } p4_error("OOPS: shmat failed ",x);}#endifP4VOID MD_initmem(int memsize){#ifdef TC_2000 MD_malloc_hint(HEAP_INTERLEAVED | HEAP_UNCACHED, 0);#endif#if defined(GP_1000) xx_malloc(0, memsize);#endif#if defined(KSR) && defined(USE_XX_SHMALLOC)#define UNMAPPED (caddr_t) -1 caddr_t memory; unsigned size = ((memsize + 4095) / 4096) * 4096; /* create shared memory */ memory = (char *) mmap( NULL, memsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_VARIABLE |MAP_SHARED, -1,0); if ( memory == UNMAPPED) { p4_error("OOPS: mmap failed",memory); } xx_init_shmalloc(memory, size);#endif#if defined(ALLIANT) && !defined(USE_XX_SHMALLOC) xx_malloc(0, memsize);#endif#if defined(ALLIANT) && defined(USE_XX_SHMALLOC) unsigned size = ((memsize + 4095) / 4096) * 4096; char *memory = valloc(size); long id; if (!memory) p4_error("MD_initmem: failed in valloc", size); id = (long) getpid(); /* get a unique id */ if (create_shared_region(id, (char *) memory, size, 0)) p4_error("MD_init_mem: failed in create_shared_region", size); xx_init_shmalloc(memory, size);#endif#if defined(SYSV_IPC) && defined(USE_XX_SHMALLOC) int i,nsegs; unsigned size, segsize = P4_SYSV_SHM_SEGSIZE; char *mem, *tmem, *pmem; if (memsize && (memsize % P4_SYSV_SHM_SEGSIZE) == 0) nsegs = memsize / segsize; else nsegs = memsize / segsize + 1; if (nsegs > P4_MAX_SYSV_SHMIDS) p4_error( "exceeding max num of P4_MAX_SYSV_SHMIDS", P4_MAX_SYSV_SHMIDS ); size = nsegs * segsize; /* Try first to get a single section of memeory. If that doesn't work, try to piece it together */ if ((sysv_shmid[0] = shmget(getpid(),size,IPC_CREAT|0600)) >= 0) { if ((sysv_shmat[0] = mem = (char *)shmat(sysv_shmid[0],NULL,0)) == (char *)-1) { p4_shmat_errmsg( (int)(sysv_shmid[0]) ); } sysv_num_shmids++; } else { /* Piece it together */ if ((sysv_shmid[0] = shmget(getpid(),segsize,IPC_CREAT|0600)) == -1) { p4_error("OOPS: shmget failed",sysv_shmid[0]); } if ((mem = (char *)shmat(sysv_shmid[0],NULL,0)) == (char *)-1) { p4_shmat_errmsg( (int)(sysv_shmid[0]) ); } sysv_shmat[0] = mem; sysv_num_shmids++; nsegs--; pmem = mem; for (i=1; i <= nsegs; i++) { if ((sysv_shmid[i] = shmget(i+getpid(),segsize,IPC_CREAT|0600)) == -1) { p4_error("OOPS: shmget failed",sysv_shmid[i]); } if ((tmem = sysv_shmat[i] = (char *)shmat(sysv_shmid[i],pmem+segsize,0)) == (char *)-1) { if ((tmem = sysv_shmat[i] = (char *)shmat(sysv_shmid[i],pmem-segsize,0)) == (char *)-1) { p4_shmat_errmsg( i ); } else { mem = tmem; } } sysv_num_shmids++; pmem = tmem; } } xx_init_shmalloc(mem,size);#endif#if defined(SGI) && defined(VENDOR_IPC) /* * strcpy(p4_sgi_shared_arena_filename,"/tmp/shared_arena_"); */ strcpy(p4_sgi_shared_arena_filename,"/usr/tmp/p4_shared_arena_"); /* 7/12/95, bri@sgi.com */ sprintf(&(p4_sgi_shared_arena_filename[strlen(p4_sgi_shared_arena_filename)]),"%d",getpid()); if (usconfig(CONF_INITUSERS,P4_MAX_MSG_QUEUES) == -1) { p4_error("MD_initmem: usconfig failed for users: ",memsize); } if (usconfig(CONF_INITSIZE,memsize) == -1) { p4_error("MD_initmem: usconfig failed: cannot map shared arena",memsize); } p4_sgi_usptr = usinit(p4_sgi_shared_arena_filename); if (p4_sgi_usptr == NULL) { /* try usinit several times */ int ctr = 0; while ((ctr < 3) && (p4_sgi_usptr == NULL)) { ctr++; sleep(2); p4_sgi_usptr = usinit(p4_sgi_shared_arena_filename); } } if (p4_sgi_usptr == NULL) p4_error("MD_initmem: usinit failed: cannot map shared arena", memsize);#endif#if defined(USE_XX_SHMALLOC) && defined(SUN_SOLARIS) { caddr_t p4_start_shared_area; static int p4_shared_map_fd; p4_shared_map_fd = open("/dev/zero", O_RDWR); p4_start_shared_area = (char *) mmap((caddr_t) 0, memsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, p4_shared_map_fd, (off_t) 0); if (p4_start_shared_area == (caddr_t)-1) { p4_error("OOPS: mmap failed: cannot map shared memory",memsize); } xx_init_shmalloc(p4_start_shared_area,memsize); }#endif#if defined(MULTIMAX) share_malloc_init(memsize);#endif}P4VOID MD_initenv( void ){ /* next 2 should stay together -> used in MD_clock p4_global->reference_time = 0; p4_global->reference_time = MD_clock(); */ MD_set_reference_time();#if defined(FX2800_SWITCH) sw_attach(p4_global->application_id);#endif} /* MD_initenv *//* MD_malloc_hint variables. Needs to be initialized appropriately for each system. */#if defined(TC_2000)static int characteristic = HEAP_INTERLEAVED | HEAP_UNCACHED, /* "flag" arg to * heapmalloc(3) */ locality = HEAP_ANYWHERE; /* "node" arg to heapmalloc(3) */#endifP4VOID MD_malloc_hint( int a, int b ){#if defined(TC_2000) characteristic = a; locality = b; if (a == -1) xx_malloc(2, b); /* setting mapped filename */ else if (a == -2) xx_malloc(3, 0); /* doing heapsync() */#endif}char *MD_shmalloc( int size ){ char *p;#if defined(BALANCE) || defined(SYMMETRY) || defined(SYMMETRY_PTX) p = shmalloc(size);#else#if defined(GP_1000) || defined(TC_2000)/* size = (size | 0xff) + 1; $$$ Why? Nuked for now... -jb */ p = xx_malloc(1, size);# ifdef MALLOC_STATS allocated += size;# endif#else#if defined(KSR) && defined(USE_XX_SHMALLOC) p = xx_shmalloc((unsigned) size);#else#if defined(ALLIANT) && defined(USE_XX_SHMALLOC) p = xx_shmalloc((unsigned) size);#else#if defined(ALLIANT) && !defined(USE_XX_SHMALLOC) p = xx_malloc(1, size);#else#if defined(MULTIMAX) p = share_malloc(size);#else#if defined(SYSV_IPC) && defined(USE_XX_SHMALLOC) p = xx_shmalloc((unsigned) size);#else#if defined(SUN_SOLARIS) && defined(USE_XX_SHMALLOC) p = xx_shmalloc(size);#else#if defined(SGI) && defined(VENDOR_IPC) p = usmalloc(size,p4_sgi_usptr);#else p = (char *) p4_malloc(size);#endif#endif#endif#endif#endif#endif#endif#endif#endif return (p);}P4VOID MD_shfree(char *ptr){#if defined(BALANCE) || defined(SYMMETRY) || defined(SYMMETRY_PTX) shfree(ptr);#else#if defined(TC_2000) heapfree(ptr);#else#if defined(GP_1000) p4_dprintf("OOPS: MD_shfree not implemented on bfly1\n");#else#if defined(KSR) && defined(USE_XX_SHMALLOC) xx_shfree(ptr);#else#if defined(ALLIANT) && defined(USE_XX_SHMALLOC) xx_shfree(ptr);#else#if defined(ALLIANT) && !defined(USE_XX_SHMALLOC) p4_dprintf("OOPS: MD_shfree not yet implemented on alliant\n");#else /* ALLIANT */#if defined(MULTIMAX) share_free(ptr);#else#if defined(SYSV_IPC) && defined(USE_XX_SHMALLOC) xx_shfree(ptr);#else#if defined(SUN_SOLARIS) && defined(USE_XX_SHMALLOC) xx_shfree(ptr);#else#if defined(SGI) && defined(VENDOR_IPC) usfree(ptr,p4_sgi_usptr);#else p4_free(ptr);#endif#endif#endif#endif#endif#endif#endif#endif#endif#endif}#if defined(GP_1000)P4BOOL simple_lock(int *lock){ register short got_lock = 0; while(!got_lock) { while(*lock != 0) /* wait till clear */ waitspin(7); /* wait 70 microsecs - atomic ops take about 60 */ if (atomior32(lock, 1) == 0) got_lock = 1; } return(P4_TRUE);}#define wait_factor 13.0 /* appx 10 microseconds */P4VOID waitspin(n)register int n;{ n = (int) ((double) n * wait_factor); /* set wait time */ while (n > 0) n--;}P4BOOL simple_unlock(lock)int *lock;{ atomand32(lock, 0); return(P4_TRUE);}#endif#if defined(TC_2000)/* * simple_lock() * This function spins on a "semaphore" (lock location). * It spins until we get the requested semaphore. */P4BOOL simple_lock(lock)int *lock;{ register short got_lock = 0; while (!got_lock) { while (*lock != 0) /* wait till clear */ /* wait 70 microsecs - atomic ops take about 60 */ waitspin(7); /* * someone else may grab lock before we can - be sure to check what * the atomic op says WAS there */ if (xmemi(lock, 1) == 0) got_lock = 1; } return (P4_TRUE);}#define wait_factor 13.0 /* appx 10 microseconds */P4VOID waitspin(n)register int n;{ n = (int) ((double) n * wait_factor); /* set wait time */ while (n > 0) n--;}/* * simple_unlock() * This function releases the designated semaphore in the set. * It is called after a process leaves its critical section. */P4BOOL simple_unlock(lock)int *lock;{ *lock = 0; return (P4_TRUE);}#endif#if defined(ALLIANT) && !defined(USE_XX_SHMALLOC)/* * xx_malloc 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_malloc is that a single massive chunk * of memory is acquired and handed out by xx_malloc calls with 1 as first * argument. */struct mem_blk{ char *next; int l_mem; MD_lock_t MEM; int pad; /* pad out to 8-byte boundary */};char *xx_malloc(typ, n)int typ, n;{ static struct mem_blk *glob_mem = (struct mem_blk *) NULL; static int l_mem = 0; char *rc; int i; char *c; /* alliant stuff */ long id; /* end alliant stuff */ switch (typ) { case 0: /* initialize */ /* pad & malloc */ /* round to mult of pg size before allocing on page boundary */ n = ((n + 4095) / 4096) * 4096; if ((glob_mem = (struct mem_blk *) valloc((long) n)) == NULL) p4_error("xx_malloc: failed in valloc", n); id = (long) getpid(); /* get a unique id */ if (create_shared_region(id, (char *) glob_mem, (long) n, 0)) p4_error("xx_malloc: failed in create_shared_region", n); glob_mem->next = (char *) (glob_mem + sizeof(struct mem_blk)); glob_mem->l_mem = n; rc = glob_mem->next; MD_lock_init(&glob_mem->MEM); break; case 1: i = (n + 7) & (~007); MD_lock(&glob_mem->MEM); if (glob_mem->l_mem < i) { p4_dprintf("*** global allocation failure ***\n"); p4_dprintf("*** attempted %d bytes, %d left\n", i, glob_mem->l_mem); rc = NULL; MD_unlock(&glob_mem->MEM); p4_error("xx_malloc: global alloc failed", i); } 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 %x\n",rc); E */ } MD_unlock(&glob_mem->MEM); break; case 2: rc = (char *) glob_mem; break; default: printf("*** illegal call to xx_malloc *** typ=%d\n", typ); } return (rc);}#endif /* ALLIANT */#ifdef GP_1000/* * xx_malloc is a memory allocation routine. It is called in three ways: if typ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -