source: trunk/tcl/tclAlloc.c

Last change on this file was 2, checked in by Pavel Demin, 16 years ago

first commit

File size: 5.0 KB
RevLine 
[2]1/*
2 * tclAlloc.c --
3 *
4 * This is a very fast storage allocator. It allocates blocks of a
5 * small number of different sizes, and keeps free lists of each size.
6 * Blocks that don't exactly fit are passed up to the next larger size.
7 * Blocks over a certain size are directly allocated from the system.
8 *
9 * Copyright (c) 1983 Regents of the University of California.
10 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
11 *
12 * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
13 *
14 * See the file "license.terms" for information on usage and redistribution
15 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 *
17 * RCS: @(#) $Id: tclAlloc.c,v 1.1 2008-06-04 13:58:03 demin Exp $
18 */
19
20#include "tclInt.h"
21#include "tclPort.h"
22
23#ifdef TCL_DEBUG
24# define DEBUG
25/* #define MSTATS */
26# define RCHECK
27#endif
28
29//typedef unsigned long caddr_t;
30
31/*
32 * The overhead on a block is at least 4 bytes. When free, this space
33 * contains a pointer to the next free block, and the bottom two bits must
34 * be zero. When in use, the first byte is set to MAGIC, and the second
35 * byte is the size index. The remaining bytes are for alignment.
36 * If range checking is enabled then a second word holds the size of the
37 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
38 * The order of elements is critical: ov_magic must overlay the low order
39 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
40 */
41
42union overhead {
43 union overhead *ov_next; /* when free */
44 struct {
45 unsigned char ovu_magic0; /* magic number */
46 unsigned char ovu_index; /* bucket # */
47 unsigned char ovu_unused; /* unused */
48 unsigned char ovu_magic1; /* other magic number */
49#ifdef RCHECK
50 unsigned short ovu_rmagic; /* range magic number */
51 unsigned long ovu_size; /* actual block size */
52#endif
53 } ovu;
54#define ov_magic0 ovu.ovu_magic0
55#define ov_magic1 ovu.ovu_magic1
56#define ov_index ovu.ovu_index
57#define ov_rmagic ovu.ovu_rmagic
58#define ov_size ovu.ovu_size
59};
60
61
62#define MAGIC 0xef /* magic # on accounting info */
63#define RMAGIC 0x5555 /* magic # on range info */
64
65#ifdef RCHECK
66#define RSLOP sizeof (unsigned short)
67#else
68#define RSLOP 0
69#endif
70
71#define OVERHEAD (sizeof(union overhead) + RSLOP)
72
73/*
74 * nextf[i] is the pointer to the next free block of size 2^(i+3). The
75 * smallest allocatable block is 8 bytes. The overhead information
76 * precedes the data area returned to the user.
77 */
78
79#define NBUCKETS 13
80#define MAXMALLOC (1<<(NBUCKETS+2))
81
82#ifdef MSTATS
83
84/*
85 * nmalloc[i] is the difference between the number of mallocs and frees
86 * for a given block size.
87 */
88
89static unsigned int nmalloc[NBUCKETS+1];
90#include <stdio.h>
91#endif
92
93#if defined(DEBUG) || defined(RCHECK)
94#define ASSERT(p) if (!(p)) panic(# p)
95#define RANGE_ASSERT(p) if (!(p)) panic(# p)
96#else
97#define ASSERT(p)
98#define RANGE_ASSERT(p)
99#endif
100
101/*
102 *----------------------------------------------------------------------
103 *
104 * TclpAlloc --
105 *
106 * Allocate more memory.
107 *
108 * Results:
109 * None.
110 *
111 * Side effects:
112 * None.
113 *
114 *----------------------------------------------------------------------
115 */
116
117char *
118TclpAlloc(
119 unsigned int nbytes) /* Number of bytes to allocate. */
120{
121 return (char*) malloc(nbytes);
122}
123
124/*
125 *----------------------------------------------------------------------
126 *
127 * TclpFree --
128 *
129 * Free memory.
130 *
131 * Results:
132 * None.
133 *
134 * Side effects:
135 * None.
136 *
137 *----------------------------------------------------------------------
138 */
139
140void
141TclpFree(
142 char *cp) /* Pointer to memory to free. */
143{
144 free(cp);
145 return;
146}
147
148
149/*
150 *----------------------------------------------------------------------
151 *
152 * TclpRealloc --
153 *
154 * Reallocate memory.
155 *
156 * Results:
157 * None.
158 *
159 * Side effects:
160 * None.
161 *
162 *----------------------------------------------------------------------
163 */
164
165char *
166TclpRealloc(
167 char *cp, /* Pointer to alloced block. */
168 unsigned int nbytes) /* New size of memory. */
169{
170 return (char*) realloc(cp, nbytes);
171}
172
173
174/*
175 *----------------------------------------------------------------------
176 *
177 * mstats --
178 *
179 * Prints two lines of numbers, one showing the length of the
180 * free list for each size category, the second showing the
181 * number of mallocs - frees for each size category.
182 *
183 * Results:
184 * None.
185 *
186 * Side effects:
187 * None.
188 *
189 *----------------------------------------------------------------------
190 */
191
192#ifdef MSTATS
193void
194mstats(
195 char *s) /* Where to write info. */
196{
197 register int i, j;
198 register union overhead *p;
199 int totfree = 0,
200 totused = 0;
201
202 fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);
203 for (i = 0; i < NBUCKETS; i++) {
204 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
205 fprintf(stderr, " %d", j);
206 totfree += j * (1 << (i + 3));
207 }
208 fprintf(stderr, "\nused:\t");
209 for (i = 0; i < NBUCKETS; i++) {
210 fprintf(stderr, " %d", nmalloc[i]);
211 totused += nmalloc[i] * (1 << (i + 3));
212 }
213 fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",
214 totused, totfree);
215 fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n",
216 MAXMALLOC, nmalloc[NBUCKETS]);
217}
218#endif
219
Note: See TracBrowser for help on using the repository browser.