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

📄 t1malloc.c

📁 unix vnc 协议源码. VNC是一款远程控制工具软件.
💻 C
📖 第 1 页 / 共 2 页
字号:
updated if this block happened to be the old 'firstcombined'.  (Wewould never be unhooking 'firstfree' or 'lastfree', so we do nothave to worry about the end cases.)*/ static unhook(p)        register struct freeblock *p;  /* block to unhook                    */{        p->back->fore = p->fore;        p->fore->back = p->back;         if (firstcombined == p)                firstcombined = p->fore;}/*:h2.xiMalloc() - Main User Entry Point for Getting Memory We have two slightly different versions of xiMalloc().  In the casewhere we have TYPE1IMAGER and a font cache, we are prepared, when nominallyout of memory, to loop calling TYPE1IMAGER's GimeSpace() to release fontcache.*/ /* The following code put in by MDC on 11/10/90 */ #ifdef TYPE1IMAGER static char *malloc_local(); char *xiMalloc(size)        register unsigned size;{  char *memaddr;   while ( (memaddr = malloc_local(size)) == NULL ) {    /* Ask TYPE1IMAGER to give us some of its cache back */    if ( I_GimeSpace() == 0 ) break; /* We are really, really, out of memory */  }   return(memaddr);}#endif /*Now begins the real workhorse xiMalloc() (called 'malloc_local' ifwe are taking advantage of TYPE1IMAGER).  Its argument is an unsigned;at least that lets users with 16-bit integers get a 64K chunk ofmemory, and it is also compatible with the definition of a "size_t"in most systems.*/#ifdef TYPE1IMAGERstatic char *malloc_local(Size)#elsechar *xiMalloc(Size)#endif        unsigned Size;       /* number of bytes the user requested           */{        register long size = (long)Size;  /* a working register for size     */        register struct freeblock *p;  /* tentative block to be returned     */        register long excess; /* words in excess of user request             */        register long *area; /* a convenient synonym for 'p'                 */ /*First, we increase 'size' to allow for the two size fields we willsave with the block, plus any information for debug purposes.Then we ensure that the block will be large enough to hold our'freeblock' information.  Finally we convert it to be in words(longs), not bytes, increased to span an integral number of doublewords, so that all memory blocks dispensed with be properly aligned.*/        size += 2*sizeof(long) + DEBUGWORDS*sizeof(long);        if (size < sizeof(struct freeblock) + sizeof(long))               size = sizeof(struct freeblock) + sizeof(long);        size = ((unsigned) (size + sizeof(double) - 1) / sizeof(double)) * (sizeof(double)/sizeof(long)); /*For speed, we will try first to give the user back a very recentlyreturned block--one that is on the front of the chain before'firstcombined'.  These blocks still have negative sizes, and needonly to be "unhook"ed:*/        size = -size;        for (p=firstfree.fore; p != firstcombined; p=p->fore) {                if (p->size == size) {                        unhook(p);                        uncombined--;                        if (mallocdebug) {                               printf("fast xiMalloc(%d) = %08x, ", size, p);                               dumpchain();                        }                        AvailableWords += size;  /* decreases AvailableWords */                        whocalledme(p, &Size);                        return((char *)&p->fore);                }        }/*Well, if we get here, there are no uncombined blocks matching the user'srequest.  So, we search the rest of the chain for a block that is bigenough.  ('size' becomes positive again):*/        size = -size;        for (;; p = p->fore) {/*If we hit the end of the chain (p->size == 0), we are probably out ofmemory.  However, we should first try to combine any memory that hasnot yet been combined before we give that pessimistic answer.  Ifwe succeed in combining, we can call ourselves recursively to try toallocate the requested amount:*/               if (p->size == 0) {                       if (uncombined <= 0)                              return(NULL);                       while (firstfree.fore != firstcombined)                              combine();                       return(xiMalloc(sizeof(long) * (size - 2 - DEBUGWORDS)));               }/*Otherwise, we keep searching until we find a big enough block:*/               if (p->size >= size)                       break;        }/*At this point, 'p' contains a block at least as big as what the userrequested, so we take it off the free chain.  If it is excessively big,we return the excess to the free chain:*/        unhook(p);        excess = p->size - size;        area = (long *) p;         if (excess > MINEXCESS)                freeuncombinable(area + size, excess);        else                size = p->size;         AvailableWords -= size;/*Mark first and last word of block with the negative of the size, toflag that this block is allocated:*/        area[size - 1] = area[0] = - size;         if (mallocdebug) {                printf("slow xiMalloc(%d) @ %08x, ", size, area);                dumpchain();        }        whocalledme(area, &Size);/*The address we return to the user is one 'long' BELOW the address ofthe block.  This protects our 'size' field, so we can tell the sizeof the block when he returns it to us with xiFree().  Also, he better nottouch the 'size' field at the end of the block either.  (That would benasty of him, as he would be touching memory outside of the bytes herequested).*/        return((char *) (area + 1));} /*:h2 id=addmem.addmemory() - Initialize Free Memory This routine should be called at initialization to initialize thefree chain.  There is no standard way to do this in C.We want the memory dispensed by malloc to be aligned on a double wordboundary (because some machines either require alignment, or aremore efficient if accesses are aligned).  Since the total size ofany block created by malloc is an integral number of double words,all we have to do to ensure alignment is to adjust each large blockadded to the free chain to start on an odd long-word boundary.(Malloc's size field will occupy the odd long and the user's memorywill then begin on an even boundary.)  Since we fill in additionalsize fields at the beginning and end of each of the large freeblocks,we need only adjust the address passed to addmemory to a double wordboundary.*/ #define   MAXAREAS   10      /* there can be this many calls to addmemory()  */ static long *freearea[MAXAREAS] = { NULL };  /* so we can report later       */ void addmemory(addr, size)        register long *addr; /* beginning of free area                       */        register long size;  /* number of bytes of free area                 */{        register int i;      /* loop index variable                          */        register long *aaddr;  /* aligned beginning of free area             */ #if DEBUGWORDS        printf("malloc has DEBUGWORDS=%d\n", DEBUGWORDS);#endif/*First link together firstfree and lastfree if necessary:*/        if (firstfree.fore == NULL) {                firstfree.fore = &lastfree;                lastfree.back = &firstfree;        }/*We'll record where the area was that was given to us for later reports:*/        for (i=0; i < MAXAREAS; i++)                if (freearea[i] == NULL) break;        if (i >= MAXAREAS)                abort("too many addmemory()s");        aaddr = (long *) ( ((long) addr + sizeof(double) - 1) & - (long)sizeof(double) );        size -= (char *) aaddr - (char *) addr;        freearea[i] = aaddr;/*Convert 'size' to number of longs, and store '-size' guards at thebeginning and end of this area so we will not accidentally recombine thefirst or last block:*/        size /= sizeof(long);         AvailableWords += size - 2;         aaddr[size - 1] = aaddr[0] = -size;/*Finally, call 'freeuncombinable' to put the remaining memory on thefree list:*/        freeuncombinable(aaddr + 1, size - 2);} /*:h3.delmemory() - Delete Memory Pool*/void delmemory(){       register int i;        AvailableWords = 0;       firstfree.fore = &lastfree;       lastfree.back  = &firstfree;       firstcombined  = &lastfree;       uncombined     = 0;       for (i=0; i<MAXAREAS; i++)               freearea[i] = NULL;} /*:h2.Debug Routines :h3.dumpchain() - Print the Chain of Free Blocks*/ static dumpchain(){        register struct freeblock *p;  /* current free block                 */        register long size;  /* size of block                                */        register struct freeblock *back;  /* block before 'p'                */        register int i;      /* temp variable for counting                   */         printf("DUMPING FAST FREE LIST:\n");        back = &firstfree;        for (p = firstfree.fore, i=uncombined; p != firstcombined;                                 p = p->fore) {                if (--i < 0)                        abort("too many uncombined areas");                size = p->size;                printf(". . . area @ %08x, size = %ld\n", p, -size);                if (size >= 0 || size != ((int *) p)[-1 - size])                        abort("dumpchain: bad size");                if (p->back != back)                        abort("dumpchain: bad back");                back = p;        }        printf("DUMPING COMBINED FREE LIST:\n");        for (; p != &lastfree; p = p->fore)  {                size = p->size;                printf(". . . area @ %08x, size = %d\n", p, size);                if (size <= 0 || size != ((int *) p)[size - 1])                        abort("dumpchain: bad size");                if (p->back != back)                        abort("dumpchain: bad back");                back = p;        }        if (back != lastfree.back)                abort("dumpchain: bad lastfree");} /*:h3.reportarea() - Display a Contiguous Set of Memory Blocks*/ static reportarea(area)       register long *area;   /* start of blocks (from addmemory)            */{       register long size;    /* size of current block                       */       register long wholesize;  /* size of original area                    */       register struct freeblock *p;  /* pointer to block                    */        if (area == NULL)               return;       wholesize = - *area++;       wholesize -= 2;        while (wholesize > 0) {               size = *area;               if (size < 0) {                       register int i,j;                        size = -size;                       printf("Allocated %5d bytes at %08x, first words=%08x %08x\n",                               size * sizeof(long), area + 1, area[1], area[2]);#if DEBUGWORDS                       printf("  ...Last operator: %s\n",                               (char *)area[size-DEBUGWORDS-1]);#endif                       for (i = size - DEBUGWORDS; i < size - 2; i += 8) {                               printf("  ...");                               for (j=0; j<8; j++)                                       printf(" %08x", area[i+j]);                               printf("\n");                       }                }               else {                       printf("Free %d bytes at %x\n", size * sizeof(long),                               area);                       if (size == 0)                               abort("zero sized memory block");                        for (p = firstfree.fore; p != NULL; p = p->fore)                               if ((long *) p == area) break;                       if ((long *) p != area)                               abort("not found on forward chain");                        for (p = lastfree.back; p != NULL; p = p->back)                               if ((long *) p == area) break;                       if ((long *) p != area)                               abort("not found on backward chain");               }               if (area[0] != area[size - 1])                       abort("unmatched check sizes");               area += size;               wholesize -= size;       }} /*:h3.MemReport() - Display All of Memory*/ MemReport(){       register int i;        dumpchain();        for (i=0; i<MAXAREAS; i++)               reportarea(freearea[i]);} /*:h3.MemBytesAvail - Display Number of Bytes Now Available*/ MemBytesAvail(){       printf("There are now %d bytes available\n", AvailableWords *                                                    sizeof(long) );}

⌨️ 快捷键说明

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