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

📄 tclalloc.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 2 页
字号:
 * *	Allocate more memory to the indicated bucket. * *	Assumes Mutex is already held. * * Results: *	None. * * Side effects: *	Attempts to get more memory from the system. * *---------------------------------------------------------------------- */static voidMoreCore(bucket)    int bucket;		/* What bucket to allocat to. */{    register union overhead *op;    register long sz;		/* size of desired block */    long amt;			/* amount to allocate */    int nblks;			/* how many blocks we get */    struct block *blockPtr;    /*     * sbrk_size <= 0 only for big, FLUFFY, requests (about     * 2^30 bytes on a VAX, I think) or for a negative arg.     */    sz = 1 << (bucket + 3);    ASSERT(sz > 0);    amt = MAXMALLOC;    nblks = amt / sz;    ASSERT(nblks*sz == amt);    blockPtr = (struct block *) TclpSysAlloc((unsigned) 	    (sizeof(struct block) + amt), 1);    /* no more room! */    if (blockPtr == NULL) {	return;    }    blockPtr->nextPtr = blockList;    blockList = blockPtr;    op = (union overhead *) (blockPtr + 1);        /*     * Add new memory allocated to that on     * free list for this hash bucket.     */    nextf[bucket] = op;    while (--nblks > 0) {	op->ov_next = (union overhead *)((caddr_t)op + sz);	op = (union overhead *)((caddr_t)op + sz);    }    op->ov_next = (union overhead *)NULL;}/* *---------------------------------------------------------------------- * * TclpFree -- * *	Free memory. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */voidTclpFree(cp)    char *cp;		/* Pointer to memory to free. */{       register long size;    register union overhead *op;    struct block *bigBlockPtr;    if (cp == NULL) {	return;    }    Tcl_MutexLock(allocMutexPtr);    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */    ASSERT(op->ov_magic1 == MAGIC);    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {	Tcl_MutexUnlock(allocMutexPtr);	return;    }    RANGE_ASSERT(op->ov_rmagic == RMAGIC);    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);    size = op->ov_index;    if ( size == 0xff ) {#ifdef MSTATS	nmalloc[NBUCKETS]--;#endif	bigBlockPtr = (struct block *) op - 1;	bigBlockPtr->prevPtr->nextPtr = bigBlockPtr->nextPtr;	bigBlockPtr->nextPtr->prevPtr = bigBlockPtr->prevPtr;	TclpSysFree(bigBlockPtr);	Tcl_MutexUnlock(allocMutexPtr);	return;    }    ASSERT(size < NBUCKETS);    op->ov_next = nextf[size];	/* also clobbers ov_magic */    nextf[size] = op;#ifdef MSTATS    nmalloc[size]--;#endif    Tcl_MutexUnlock(allocMutexPtr);}/* *---------------------------------------------------------------------- * * TclpRealloc -- * *	Reallocate memory. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *TclpRealloc(cp, nbytes)    char *cp;			/* Pointer to alloced block. */    unsigned int nbytes;	/* New size of memory. */{       int i;    union overhead *op;    struct block *bigBlockPtr;    int expensive;    unsigned long maxsize;    if (cp == NULL) {	return (TclpAlloc(nbytes));    }    Tcl_MutexLock(allocMutexPtr);    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */    ASSERT(op->ov_magic1 == MAGIC);    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {	Tcl_MutexUnlock(allocMutexPtr);	return NULL;    }    RANGE_ASSERT(op->ov_rmagic == RMAGIC);    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);    i = op->ov_index;    /*     * If the block isn't in a bin, just realloc it.     */    if (i == 0xff) {	struct block *prevPtr, *nextPtr;	bigBlockPtr = (struct block *) op - 1;	prevPtr = bigBlockPtr->prevPtr;	nextPtr = bigBlockPtr->nextPtr;	bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr, 		sizeof(struct block) + OVERHEAD + nbytes);	if (bigBlockPtr == NULL) {	    Tcl_MutexUnlock(allocMutexPtr);	    return NULL;	}	if (prevPtr->nextPtr != bigBlockPtr) {	    /*	     * If the block has moved, splice the new block into the list where	     * the old block used to be. 	     */	    prevPtr->nextPtr = bigBlockPtr;	    nextPtr->prevPtr = bigBlockPtr;	}	op = (union overhead *) (bigBlockPtr + 1);#ifdef MSTATS	nmalloc[NBUCKETS]++;#endif#ifdef RCHECK	/*	 * Record allocated size of block and update magic number bounds.	 */	op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);	*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;#endif	Tcl_MutexUnlock(allocMutexPtr);	return (char *)(op+1);    }    maxsize = 1 << (i+3);    expensive = 0;    if ( nbytes + OVERHEAD > maxsize ) {	expensive = 1;    } else if ( i > 0 && nbytes + OVERHEAD < (maxsize/2) ) {	expensive = 1;    }    if (expensive) {	void *newp;	Tcl_MutexUnlock(allocMutexPtr);	newp = TclpAlloc(nbytes);	if ( newp == NULL ) {	    return NULL;	}	maxsize -= OVERHEAD;	if ( maxsize < nbytes )	    nbytes = maxsize;	memcpy((VOID *) newp, (VOID *) cp, (size_t) nbytes);	TclpFree(cp);	return newp;    }        /*     * Ok, we don't have to copy, it fits as-is     */#ifdef RCHECK    op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);    *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;#endif    Tcl_MutexUnlock(allocMutexPtr);    return(cp);}/* *---------------------------------------------------------------------- * * mstats -- * *	Prints two lines of numbers, one showing the length of the  *	free list for each size category, the second showing the  *	number of mallocs - frees for each size category. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */#ifdef MSTATSvoidmstats(s)    char *s;	/* Where to write info. */{    register int i, j;    register union overhead *p;    int totfree = 0,	totused = 0;    Tcl_MutexLock(allocMutexPtr);    fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);    for (i = 0; i < NBUCKETS; i++) {	for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)	    fprintf(stderr, " %d", j);	totfree += j * (1 << (i + 3));    }    fprintf(stderr, "\nused:\t");    for (i = 0; i < NBUCKETS; i++) {	fprintf(stderr, " %d", nmalloc[i]);	totused += nmalloc[i] * (1 << (i + 3));    }    fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",	    totused, totfree);    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", 	    MAXMALLOC, nmalloc[NBUCKETS]);    Tcl_MutexUnlock(allocMutexPtr);}#endif#else  /* !USE_TCLALLOC *//* *---------------------------------------------------------------------- * * TclpAlloc -- * *	Allocate more memory. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *TclpAlloc(nbytes)    unsigned int nbytes;	/* Number of bytes to allocate. */{    return (char*) malloc(nbytes);}/* *---------------------------------------------------------------------- * * TclpFree -- * *	Free memory. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */voidTclpFree(cp)    char *cp;		/* Pointer to memory to free. */{       free(cp);    return;}/* *---------------------------------------------------------------------- * * TclpRealloc -- * *	Reallocate memory. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *TclpRealloc(cp, nbytes)    char *cp;			/* Pointer to alloced block. */    unsigned int nbytes;	/* New size of memory. */{       return (char*) realloc(cp, nbytes);}#endif /* !USE_TCLALLOC */#endif /* !TCL_THREADS */

⌨️ 快捷键说明

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