Tk
view release on metacpan or search on metacpan
pTk/mTk/tclGeneric/tclAlloc.c view on Meta::CPAN
/*
* tclAlloc.c --
*
* This is a very fast storage allocator. It allocates blocks of a
* small number of different sizes, and keeps free lists of each size.
* Blocks that don't exactly fit are passed up to the next larger size.
* Blocks over a certain size are directly allocated from the system.
*
* Copyright (c) 1983 Regents of the University of California.
* Copyright (c) 1996-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
*
* Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclAlloc.c,v 1.16 2002/04/23 17:03:34 hobbs Exp $
*/
/*
* Windows and Unix use an alternative allocator when building with threads
* that has significantly reduced lock contention.
*/
#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC)
#include "tclInt.h"
#include "tclPort.h"
#if USE_TCLALLOC
#ifdef TCL_DEBUG
# define DEBUG
/* #define MSTATS */
# define RCHECK
#endif
/*
* We should really make use of AC_CHECK_TYPE(caddr_t)
* here, but it can wait until Tcl uses config.h properly.
*/
#if defined(MAC_TCL) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__)
typedef unsigned long caddr_t;
#endif
/*
* The overhead on a block is at least 8 bytes. When free, this space
* contains a pointer to the next free block, and the bottom two bits must
* be zero. When in use, the first byte is set to MAGIC, and the second
* byte is the size index. The remaining bytes are for alignment.
* If range checking is enabled then a second word holds the size of the
* requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
* The order of elements is critical: ov_magic must overlay the low order
* bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
*/
union overhead {
union overhead *ov_next; /* when free */
unsigned char ov_padding[8]; /* Ensure the structure is 8-byte aligned. */
struct {
unsigned char ovu_magic0; /* magic number */
unsigned char ovu_index; /* bucket # */
unsigned char ovu_unused; /* unused */
unsigned char ovu_magic1; /* other magic number */
#ifdef RCHECK
unsigned short ovu_rmagic; /* range magic number */
unsigned long ovu_size; /* actual block size */
unsigned short ovu_unused2; /* padding to 8-byte align */
#endif
} ovu;
#define ov_magic0 ovu.ovu_magic0
#define ov_magic1 ovu.ovu_magic1
#define ov_index ovu.ovu_index
#define ov_rmagic ovu.ovu_rmagic
#define ov_size ovu.ovu_size
};
#define MAGIC 0xef /* magic # on accounting info */
#define RMAGIC 0x5555 /* magic # on range info */
#ifdef RCHECK
#define RSLOP sizeof (unsigned short)
#else
#define RSLOP 0
#endif
#define OVERHEAD (sizeof(union overhead) + RSLOP)
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
*/
#define NBUCKETS 13
#define MAXMALLOC (1<<(NBUCKETS+2))
static union overhead *nextf[NBUCKETS];
/*
* The following structure is used to keep track of all system memory
* currently owned by Tcl. When finalizing, all this memory will
* be returned to the system.
*/
struct block {
struct block *nextPtr; /* Linked list. */
struct block *prevPtr; /* Linked list for big blocks, ensures 8-byte
* alignment for suballocated blocks. */
};
static struct block *blockList; /* Tracks the suballocated blocks. */
static struct block bigBlocks = { /* Big blocks aren't suballocated. */
( run in 4.613 seconds using v1.01-cache-2.11-cpan-3c2a17b8caa )