⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shmalloc.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/*  Memory management routines from ANSI K&R C, modified to manage  a single block of shared memory.  Have stripped out all the usage monitoring to keep it simple.  The usage model is as follows:  1) A single process initializes shared memory management with     InitSharedMalloc(char *memory, unsigned nbytes)     memory ... points to a region of shared memory size nbytes     InitSharedMalloc() internally creates a semaphore to     co-ordinate access to its data structures.  2) The process then forks its children and can use SharedMalloc()     and SharedFree() as one would use malloc/free.*/  #define LOG_ALIGN 4#define ALIGNMENT (1 << LOG_ALIGN)/* ALIGNMENT is assumed below to be bigger than sizeof(Header *),    so do not reduce LOG_ALIGN below 4 */union header{  struct {    union header *ptr;  /* next block if on free list */    unsigned size;      /* size of this block*/  } s;  char align[ALIGNMENT]; /* Align to ALIGNMENT byte boundary */};typedef union header Header;static Header **freep;         /* pointer to pointer to start of free list */static int semid=-1, semnum=0; /* Id and number of semaphore */void InitSharedMalloc(memory, nbytes)     char *memory;     unsigned nbytes;/*  memory points to a region of shared memory nbytes long.  initialize the data structures needed to manage this memory*/{  int nunits = nbytes >> LOG_ALIGN;  Header *region = (Header *) memory;  /* Quick check that things are OK */  if (ALIGNMENT != sizeof(Header) || ALIGNMENT < sizeof(Header *))    p4_error("InitSharedMalloc: Alignment is wrong", ALIGNMENT);  if (!region)    p4_error("InitSharedMalloc: Passed null pointer",0);  if (nunits < 2)    p4_error("InitSharedMalloc: Initial region is ridiculously small", 	     (int) nbytes);  /* Shared memory region is structured as follows     1) (Header *) freep ... free list pointer     2) padding up to alignment boundary     3) First header of free list */  freep = (Header **) region;       /* Free space pointer in first block  */  (region+1)->s.ptr = *freep = region+1;   /* Data in rest */  (region+1)->s.size = nunits-1;           /* One header consumed already */  semid = SemSetCreate(1,0);  /* Make semaphore for access */}char *SharedMalloc(nbytes)     unsigned nbytes;{  Header *p, *prevp;  char *address = (char *) NULL;  unsigned nunits;    /* Force entire routine to be single threaded */  SemWait(semid, semnum);    nunits = ((nbytes + sizeof(Header) - 1)>>LOG_ALIGN) + 1;    prevp = *freep;  for (p=prevp->s.ptr; ; prevp = p, p = p->s.ptr) {    if (p->s.size >= nunits) {	/* Big enuf */      if (p->s.size == nunits)	/* exact fit */        prevp->s.ptr = p->s.ptr;      else {			/* allocate tail end */	p->s.size -= nunits;	p += p->s.size;	p->s.size = nunits;      }      *freep = prevp;      address = (char *) (p+1);      break;    }    if (p == *freep) {  /* wrapped around the free list ... no fit found */      address = (char *) NULL;      break;    }  }    /* End critical region */  SemPost(semid, semnum);    return address;}void SharedFree(ap)     char *ap;{  Header *bp, *p;    /* Begin critical region */  SemWait(semid, semnum);    if (!ap)    return;  /* Do nothing with NULL pointers */    bp = (Header *) ap - 1;  /* Point to block header */    for (p = *freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)    if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))      break; /* Freed block at start of end of arena */    if (bp + bp->s.size == p->s.ptr) {/* join to upper neighbour */    bp->s.size += p->s.ptr->s.size;    bp->s.ptr = p->s.ptr->s.ptr;  } else    bp->s.ptr = p->s.ptr;    if (p + p->s.size == bp) { /* Join to lower neighbour */    p->s.size += bp->s.size;    p->s.ptr = bp->s.ptr;  } else    p->s.ptr = bp;    *freep = p;    /* End critical region */  SemPost(semid, semnum);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -