annotate packages/services/memalloc/common/current/doc/dlmalloc/dlmalloc-2.6.6.c @ 115:6ed91473a1cd ecos-sw-2000-08-21

Merge from eCos master repository on 2000-08-21-22:40:54-BST
author jlarmour
date Fri, 25 Aug 2000 17:32:38 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1 /* ---------- To make a malloc.h, start cutting here ------------ */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
4 A version of malloc/free/realloc written by Doug Lea and released to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
5 public domain. Send questions/comments/complaints/performance data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
6 to dl@cs.oswego.edu
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
7
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
8 * VERSION 2.6.6 Sun Mar 5 19:10:03 2000 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
9
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
10 Note: There may be an updated version of this malloc obtainable at
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
11 ftp://g.oswego.edu/pub/misc/malloc.c
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
12 Check before installing!
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
13
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
14 * Why use this malloc?
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
15
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
16 This is not the fastest, most space-conserving, most portable, or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
17 most tunable malloc ever written. However it is among the fastest
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
18 while also being among the most space-conserving, portable and tunable.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
19 Consistent balance across these factors results in a good general-purpose
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
20 allocator. For a high-level description, see
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
21 http://g.oswego.edu/dl/html/malloc.html
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
22
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
23 * Synopsis of public routines
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
24
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
25 (Much fuller descriptions are contained in the program documentation below.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
26
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
27 malloc(size_t n);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
28 Return a pointer to a newly allocated chunk of at least n bytes, or null
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
29 if no space is available.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
30 free(Void_t* p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
31 Release the chunk of memory pointed to by p, or no effect if p is null.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
32 realloc(Void_t* p, size_t n);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
33 Return a pointer to a chunk of size n that contains the same data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
34 as does chunk p up to the minimum of (n, p's size) bytes, or null
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
35 if no space is available. The returned pointer may or may not be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
36 the same as p. If p is null, equivalent to malloc. Unless the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
37 #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
38 size argument of zero (re)allocates a minimum-sized chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
39 memalign(size_t alignment, size_t n);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
40 Return a pointer to a newly allocated chunk of n bytes, aligned
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
41 in accord with the alignment argument, which must be a power of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
42 two.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
43 valloc(size_t n);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
44 Equivalent to memalign(pagesize, n), where pagesize is the page
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
45 size of the system (or as near to this as can be figured out from
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
46 all the includes/defines below.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
47 pvalloc(size_t n);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
48 Equivalent to valloc(minimum-page-that-holds(n)), that is,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
49 round up n to nearest pagesize.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
50 calloc(size_t unit, size_t quantity);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
51 Returns a pointer to quantity * unit bytes, with all locations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
52 set to zero.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
53 cfree(Void_t* p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
54 Equivalent to free(p).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
55 malloc_trim(size_t pad);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
56 Release all but pad bytes of freed top-most memory back
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
57 to the system. Return 1 if successful, else 0.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
58 malloc_usable_size(Void_t* p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
59 Report the number usable allocated bytes associated with allocated
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
60 chunk p. This may or may not report more bytes than were requested,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
61 due to alignment and minimum size constraints.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
62 malloc_stats();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
63 Prints brief summary statistics on stderr.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
64 mallinfo()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
65 Returns (by copy) a struct containing various summary statistics.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
66 mallopt(int parameter_number, int parameter_value)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
67 Changes one of the tunable parameters described below. Returns
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
68 1 if successful in changing the parameter, else 0.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
69
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
70 * Vital statistics:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
71
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
72 Alignment: 8-byte
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
73 8 byte alignment is currently hardwired into the design. This
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
74 seems to suffice for all current machines and C compilers.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
75
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
76 Assumed pointer representation: 4 or 8 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
77 Code for 8-byte pointers is untested by me but has worked
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
78 reliably by Wolfram Gloger, who contributed most of the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
79 changes supporting this.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
80
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
81 Assumed size_t representation: 4 or 8 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
82 Note that size_t is allowed to be 4 bytes even if pointers are 8.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
83
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
84 Minimum overhead per allocated chunk: 4 or 8 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
85 Each malloced chunk has a hidden overhead of 4 bytes holding size
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
86 and status information.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
87
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
88 Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
89 8-byte ptrs: 24/32 bytes (including, 4/8 overhead)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
90
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
91 When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
92 ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
93 needed; 4 (8) for a trailing size field
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
94 and 8 (16) bytes for free list pointers. Thus, the minimum
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
95 allocatable size is 16/24/32 bytes.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
96
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
97 Even a request for zero bytes (i.e., malloc(0)) returns a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
98 pointer to something of the minimum allocatable size.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
99
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
100 Maximum allocated size: 4-byte size_t: 2^31 - 8 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
101 8-byte size_t: 2^63 - 16 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
102
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
103 It is assumed that (possibly signed) size_t bit values suffice to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
104 represent chunk sizes. `Possibly signed' is due to the fact
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
105 that `size_t' may be defined on a system as either a signed or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
106 an unsigned type. To be conservative, values that would appear
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
107 as negative numbers are avoided.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
108 Requests for sizes with a negative sign bit when the request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
109 size is treaded as a long will return null.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
110
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
111 Maximum overhead wastage per allocated chunk: normally 15 bytes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
112
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
113 Alignnment demands, plus the minimum allocatable size restriction
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
114 make the normal worst-case wastage 15 bytes (i.e., up to 15
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
115 more bytes will be allocated than were requested in malloc), with
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
116 two exceptions:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
117 1. Because requests for zero bytes allocate non-zero space,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
118 the worst case wastage for a request of zero bytes is 24 bytes.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
119 2. For requests >= mmap_threshold that are serviced via
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
120 mmap(), the worst case wastage is 8 bytes plus the remainder
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
121 from a system page (the minimal mmap unit); typically 4096 bytes.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
122
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
123 * Limitations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
124
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
125 Here are some features that are NOT currently supported
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
126
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
127 * No user-definable hooks for callbacks and the like.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
128 * No automated mechanism for fully checking that all accesses
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
129 to malloced memory stay within their bounds.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
130 * No support for compaction.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
131
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
132 * Synopsis of compile-time options:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
133
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
134 People have reported using previous versions of this malloc on all
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
135 versions of Unix, sometimes by tweaking some of the defines
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
136 below. It has been tested most extensively on Solaris and
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
137 Linux. It is also reported to work on WIN32 platforms.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
138 People have also reported adapting this malloc for use in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
139 stand-alone embedded systems.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
140
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
141 The implementation is in straight, hand-tuned ANSI C. Among other
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
142 consequences, it uses a lot of macros. Because of this, to be at
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
143 all usable, this code should be compiled using an optimizing compiler
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
144 (for example gcc -O2) that can simplify expressions and control
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
145 paths.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
146
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
147 __STD_C (default: derived from C compiler defines)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
148 Nonzero if using ANSI-standard C compiler, a C++ compiler, or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
149 a C compiler sufficiently close to ANSI to get away with it.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
150 DEBUG (default: NOT defined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
151 Define to enable debugging. Adds fairly extensive assertion-based
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
152 checking to help track down memory errors, but noticeably slows down
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
153 execution.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
154 REALLOC_ZERO_BYTES_FREES (default: NOT defined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
155 Define this if you think that realloc(p, 0) should be equivalent
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
156 to free(p). Otherwise, since malloc returns a unique pointer for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
157 malloc(0), so does realloc(p, 0).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
158 HAVE_MEMCPY (default: defined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
159 Define if you are not otherwise using ANSI STD C, but still
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
160 have memcpy and memset in your C library and want to use them.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
161 Otherwise, simple internal versions are supplied.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
162 USE_MEMCPY (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
163 Define as 1 if you want the C library versions of memset and
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
164 memcpy called in realloc and calloc (otherwise macro versions are used).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
165 At least on some platforms, the simple macro versions usually
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
166 outperform libc versions.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
167 HAVE_MMAP (default: defined as 1)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
168 Define to non-zero to optionally make malloc() use mmap() to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
169 allocate very large blocks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
170 HAVE_MREMAP (default: defined as 0 unless Linux libc set)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
171 Define to non-zero to optionally make realloc() use mremap() to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
172 reallocate very large blocks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
173 malloc_getpagesize (default: derived from system #includes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
174 Either a constant or routine call returning the system page size.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
175 HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
176 Optionally define if you are on a system with a /usr/include/malloc.h
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
177 that declares struct mallinfo. It is not at all necessary to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
178 define this even if you do, but will ensure consistency.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
179 INTERNAL_SIZE_T (default: size_t)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
180 Define to a 32-bit type (probably `unsigned int') if you are on a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
181 64-bit machine, yet do not want or need to allow malloc requests of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
182 greater than 2^31 to be handled. This saves space, especially for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
183 very small chunks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
184 INTERNAL_LINUX_C_LIB (default: NOT defined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
185 Defined only when compiled as part of Linux libc.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
186 Also note that there is some odd internal name-mangling via defines
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
187 (for example, internally, `malloc' is named `mALLOc') needed
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
188 when compiling in this case. These look funny but don't otherwise
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
189 affect anything.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
190 WIN32 (default: undefined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
191 Define this on MS win (95, nt) platforms to compile in sbrk emulation.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
192 LACKS_UNISTD_H (default: undefined if not WIN32)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
193 Define this if your system does not have a <unistd.h>.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
194 LACKS_SYS_PARAM_H (default: undefined if not WIN32)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
195 Define this if your system does not have a <sys/param.h>.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
196 MORECORE (default: sbrk)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
197 The name of the routine to call to obtain more memory from the system.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
198 MORECORE_FAILURE (default: -1)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
199 The value returned upon failure of MORECORE.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
200 MORECORE_CLEARS (default 1)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
201 True (1) if the routine mapped to MORECORE zeroes out memory (which
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
202 holds for sbrk).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
203 DEFAULT_TRIM_THRESHOLD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
204 DEFAULT_TOP_PAD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
205 DEFAULT_MMAP_THRESHOLD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
206 DEFAULT_MMAP_MAX
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
207 Default values of tunable parameters (described in detail below)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
208 controlling interaction with host system routines (sbrk, mmap, etc).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
209 These values may also be changed dynamically via mallopt(). The
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
210 preset defaults are those that give best performance for typical
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
211 programs/systems.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
212 USE_DL_PREFIX (default: undefined)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
213 Prefix all public routines with the string 'dl'. Useful to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
214 quickly avoid procedure declaration conflicts and linker symbol
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
215 conflicts with existing memory allocation routines.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
216
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
217
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
218 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
219
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
220
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
221
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
222
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
223 /* Preliminaries */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
224
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
225 #ifndef __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
226 #ifdef __STDC__
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
227 #define __STD_C 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
228 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
229 #if __cplusplus
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
230 #define __STD_C 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
231 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
232 #define __STD_C 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
233 #endif /*__cplusplus*/
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
234 #endif /*__STDC__*/
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
235 #endif /*__STD_C*/
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
236
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
237 #ifndef Void_t
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
238 #if (__STD_C || defined(WIN32))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
239 #define Void_t void
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
240 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
241 #define Void_t char
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
242 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
243 #endif /*Void_t*/
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
244
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
245 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
246 #include <stddef.h> /* for size_t */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
247 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
248 #include <sys/types.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
249 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
250
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
251 #ifdef __cplusplus
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
252 extern "C" {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
253 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
254
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
255 #include <stdio.h> /* needed for malloc_stats */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
256
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
257
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
258 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
259 Compile-time options
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
260 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
261
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
262
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
263 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
264 Debugging:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
265
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
266 Because freed chunks may be overwritten with link fields, this
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
267 malloc will often die when freed memory is overwritten by user
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
268 programs. This can be very effective (albeit in an annoying way)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
269 in helping track down dangling pointers.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
270
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
271 If you compile with -DDEBUG, a number of assertion checks are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
272 enabled that will catch more memory errors. You probably won't be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
273 able to make much sense of the actual assertion errors, but they
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
274 should help you locate incorrectly overwritten memory. The
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
275 checking is fairly extensive, and will slow down execution
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
276 noticeably. Calling malloc_stats or mallinfo with DEBUG set will
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
277 attempt to check every non-mmapped allocated and free chunk in the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
278 course of computing the summmaries. (By nature, mmapped regions
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
279 cannot be checked very much automatically.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
280
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
281 Setting DEBUG may also be helpful if you are trying to modify
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
282 this code. The assertions in the check routines spell out in more
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
283 detail the assumptions and invariants underlying the algorithms.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
284
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
285 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
286
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
287 #if DEBUG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
288 #include <assert.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
289 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
290 #define assert(x) ((void)0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
291 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
292
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
293
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
294 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
295 INTERNAL_SIZE_T is the word-size used for internal bookkeeping
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
296 of chunk sizes. On a 64-bit machine, you can reduce malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
297 overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
298 at the expense of not being able to handle requests greater than
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
299 2^31. This limitation is hardly ever a concern; you are encouraged
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
300 to set this. However, the default version is the same as size_t.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
301 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
302
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
303 #ifndef INTERNAL_SIZE_T
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
304 #define INTERNAL_SIZE_T size_t
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
305 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
306
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
307 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
308 REALLOC_ZERO_BYTES_FREES should be set if a call to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
309 realloc with zero bytes should be the same as a call to free.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
310 Some people think it should. Otherwise, since this malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
311 returns a unique pointer for malloc(0), so does realloc(p, 0).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
312 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
313
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
314
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
315 /* #define REALLOC_ZERO_BYTES_FREES */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
316
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
317
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
318 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
319 WIN32 causes an emulation of sbrk to be compiled in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
320 mmap-based options are not currently supported in WIN32.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
321 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
322
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
323 /* #define WIN32 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
324 #ifdef WIN32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
325 #define MORECORE wsbrk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
326 #define HAVE_MMAP 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
327
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
328 #define LACKS_UNISTD_H
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
329 #define LACKS_SYS_PARAM_H
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
330
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
331 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
332 Include 'windows.h' to get the necessary declarations for the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
333 Microsoft Visual C++ data structures and routines used in the 'sbrk'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
334 emulation.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
335
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
336 Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
337 Visual C++ header files are included.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
338 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
339 #define WIN32_LEAN_AND_MEAN
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
340 #include <windows.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
341 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
342
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
343
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
344 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
345 HAVE_MEMCPY should be defined if you are not otherwise using
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
346 ANSI STD C, but still have memcpy and memset in your C library
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
347 and want to use them in calloc and realloc. Otherwise simple
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
348 macro versions are defined here.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
349
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
350 USE_MEMCPY should be defined as 1 if you actually want to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
351 have memset and memcpy called. People report that the macro
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
352 versions are often enough faster than libc versions on many
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
353 systems that it is better to use them.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
354
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
355 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
356
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
357 #define HAVE_MEMCPY
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
358
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
359 #ifndef USE_MEMCPY
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
360 #ifdef HAVE_MEMCPY
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
361 #define USE_MEMCPY 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
362 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
363 #define USE_MEMCPY 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
364 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
365 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
366
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
367 #if (__STD_C || defined(HAVE_MEMCPY))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
368
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
369 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
370 void* memset(void*, int, size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
371 void* memcpy(void*, const void*, size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
372 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
373 #ifdef WIN32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
374 // On Win32 platforms, 'memset()' and 'memcpy()' are already declared in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
375 // 'windows.h'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
376 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
377 Void_t* memset();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
378 Void_t* memcpy();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
379 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
380 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
381 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
382
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
383 #if USE_MEMCPY
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
384
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
385 /* The following macros are only invoked with (2n+1)-multiples of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
386 INTERNAL_SIZE_T units, with a positive integer n. This is exploited
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
387 for fast inline execution when n is small. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
388
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
389 #define MALLOC_ZERO(charp, nbytes) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
390 do { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
391 INTERNAL_SIZE_T mzsz = (nbytes); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
392 if(mzsz <= 9*sizeof(mzsz)) { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
393 INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
394 if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
395 *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
396 if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
397 *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
398 if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
399 *mz++ = 0; }}} \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
400 *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
401 *mz++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
402 *mz = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
403 } else memset((charp), 0, mzsz); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
404 } while(0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
405
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
406 #define MALLOC_COPY(dest,src,nbytes) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
407 do { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
408 INTERNAL_SIZE_T mcsz = (nbytes); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
409 if(mcsz <= 9*sizeof(mcsz)) { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
410 INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
411 INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
412 if(mcsz >= 5*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
413 *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
414 if(mcsz >= 7*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
415 *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
416 if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
417 *mcdst++ = *mcsrc++; }}} \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
418 *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
419 *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
420 *mcdst = *mcsrc ; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
421 } else memcpy(dest, src, mcsz); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
422 } while(0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
423
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
424 #else /* !USE_MEMCPY */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
425
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
426 /* Use Duff's device for good zeroing/copying performance. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
427
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
428 #define MALLOC_ZERO(charp, nbytes) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
429 do { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
430 INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
431 long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
432 if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
433 switch (mctmp) { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
434 case 0: for(;;) { *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
435 case 7: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
436 case 6: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
437 case 5: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
438 case 4: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
439 case 3: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
440 case 2: *mzp++ = 0; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
441 case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
442 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
443 } while(0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
444
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
445 #define MALLOC_COPY(dest,src,nbytes) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
446 do { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
447 INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
448 INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
449 long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
450 if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
451 switch (mctmp) { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
452 case 0: for(;;) { *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
453 case 7: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
454 case 6: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
455 case 5: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
456 case 4: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
457 case 3: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
458 case 2: *mcdst++ = *mcsrc++; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
459 case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
460 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
461 } while(0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
462
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
463 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
464
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
465
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
466 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
467 Define HAVE_MMAP to optionally make malloc() use mmap() to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
468 allocate very large blocks. These will be returned to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
469 operating system immediately after a free().
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
470 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
471
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
472 #ifndef HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
473 #define HAVE_MMAP 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
474 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
475
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
476 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
477 Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
478 large blocks. This is currently only possible on Linux with
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
479 kernel versions newer than 1.3.77.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
480 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
481
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
482 #ifndef HAVE_MREMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
483 #ifdef INTERNAL_LINUX_C_LIB
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
484 #define HAVE_MREMAP 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
485 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
486 #define HAVE_MREMAP 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
487 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
488 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
489
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
490 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
491
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
492 #include <unistd.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
493 #include <fcntl.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
494 #include <sys/mman.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
495
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
496 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
497 #define MAP_ANONYMOUS MAP_ANON
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
498 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
499
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
500 #endif /* HAVE_MMAP */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
501
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
502 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
503 Access to system page size. To the extent possible, this malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
504 manages memory from the system in page-size units.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
505
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
506 The following mechanics for getpagesize were adapted from
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
507 bsd/gnu getpagesize.h
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
508 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
509
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
510 #ifndef LACKS_UNISTD_H
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
511 # include <unistd.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
512 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
513
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
514 #ifndef malloc_getpagesize
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
515 # ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
516 # ifndef _SC_PAGE_SIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
517 # define _SC_PAGE_SIZE _SC_PAGESIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
518 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
519 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
520 # ifdef _SC_PAGE_SIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
521 # define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
522 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
523 # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
524 extern size_t getpagesize();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
525 # define malloc_getpagesize getpagesize()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
526 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
527 # ifdef WIN32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
528 # define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
529 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
530 # ifndef LACKS_SYS_PARAM_H
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
531 # include <sys/param.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
532 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
533 # ifdef EXEC_PAGESIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
534 # define malloc_getpagesize EXEC_PAGESIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
535 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
536 # ifdef NBPG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
537 # ifndef CLSIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
538 # define malloc_getpagesize NBPG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
539 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
540 # define malloc_getpagesize (NBPG * CLSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
541 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
542 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
543 # ifdef NBPC
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
544 # define malloc_getpagesize NBPC
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
545 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
546 # ifdef PAGESIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
547 # define malloc_getpagesize PAGESIZE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
548 # else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
549 # define malloc_getpagesize (4096) /* just guess */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
550 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
551 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
552 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
553 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
554 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
555 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
556 # endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
557 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
558
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
559
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
560
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
561 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
562
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
563 This version of malloc supports the standard SVID/XPG mallinfo
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
564 routine that returns a struct containing the same kind of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
565 information you can get from malloc_stats. It should work on
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
566 any SVID/XPG compliant system that has a /usr/include/malloc.h
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
567 defining struct mallinfo. (If you'd like to install such a thing
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
568 yourself, cut out the preliminary declarations as described above
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
569 and below and save them in a malloc.h file. But there's no
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
570 compelling reason to bother to do this.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
571
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
572 The main declaration needed is the mallinfo struct that is returned
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
573 (by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
574 bunch of fields, most of which are not even meaningful in this
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
575 version of malloc. Some of these fields are are instead filled by
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
576 mallinfo() with other numbers that might possibly be of interest.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
577
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
578 HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
579 /usr/include/malloc.h file that includes a declaration of struct
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
580 mallinfo. If so, it is included; else an SVID2/XPG2 compliant
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
581 version is declared below. These must be precisely the same for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
582 mallinfo() to work.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
583
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
584 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
585
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
586 /* #define HAVE_USR_INCLUDE_MALLOC_H */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
587
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
588 #if HAVE_USR_INCLUDE_MALLOC_H
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
589 #include "/usr/include/malloc.h"
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
590 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
591
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
592 /* SVID2/XPG mallinfo structure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
593
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
594 struct mallinfo {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
595 int arena; /* total space allocated from system */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
596 int ordblks; /* number of non-inuse chunks */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
597 int smblks; /* unused -- always zero */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
598 int hblks; /* number of mmapped regions */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
599 int hblkhd; /* total space in mmapped regions */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
600 int usmblks; /* unused -- always zero */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
601 int fsmblks; /* unused -- always zero */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
602 int uordblks; /* total allocated space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
603 int fordblks; /* total non-inuse space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
604 int keepcost; /* top-most, releasable (via malloc_trim) space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
605 };
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
606
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
607 /* SVID2/XPG mallopt options */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
608
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
609 #define M_MXFAST 1 /* UNUSED in this malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
610 #define M_NLBLKS 2 /* UNUSED in this malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
611 #define M_GRAIN 3 /* UNUSED in this malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
612 #define M_KEEP 4 /* UNUSED in this malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
613
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
614 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
615
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
616 /* mallopt options that actually do something */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
617
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
618 #define M_TRIM_THRESHOLD -1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
619 #define M_TOP_PAD -2
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
620 #define M_MMAP_THRESHOLD -3
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
621 #define M_MMAP_MAX -4
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
622
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
623
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
624
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
625 #ifndef DEFAULT_TRIM_THRESHOLD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
626 #define DEFAULT_TRIM_THRESHOLD (128 * 1024)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
627 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
628
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
629 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
630 M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
631 to keep before releasing via malloc_trim in free().
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
632
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
633 Automatic trimming is mainly useful in long-lived programs.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
634 Because trimming via sbrk can be slow on some systems, and can
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
635 sometimes be wasteful (in cases where programs immediately
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
636 afterward allocate more large chunks) the value should be high
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
637 enough so that your overall system performance would improve by
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
638 releasing.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
639
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
640 The trim threshold and the mmap control parameters (see below)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
641 can be traded off with one another. Trimming and mmapping are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
642 two different ways of releasing unused memory back to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
643 system. Between these two, it is often possible to keep
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
644 system-level demands of a long-lived program down to a bare
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
645 minimum. For example, in one test suite of sessions measuring
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
646 the XF86 X server on Linux, using a trim threshold of 128K and a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
647 mmap threshold of 192K led to near-minimal long term resource
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
648 consumption.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
649
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
650 If you are using this malloc in a long-lived program, it should
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
651 pay to experiment with these values. As a rough guide, you
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
652 might set to a value close to the average size of a process
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
653 (program) running on your system. Releasing this much memory
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
654 would allow such a process to run in memory. Generally, it's
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
655 worth it to tune for trimming rather tham memory mapping when a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
656 program undergoes phases where several large chunks are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
657 allocated and released in ways that can reuse each other's
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
658 storage, perhaps mixed with phases where there are no such
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
659 chunks at all. And in well-behaved long-lived programs,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
660 controlling release of large blocks via trimming versus mapping
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
661 is usually faster.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
662
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
663 However, in most programs, these parameters serve mainly as
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
664 protection against the system-level effects of carrying around
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
665 massive amounts of unneeded memory. Since frequent calls to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
666 sbrk, mmap, and munmap otherwise degrade performance, the default
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
667 parameters are set to relatively high values that serve only as
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
668 safeguards.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
669
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
670 The default trim value is high enough to cause trimming only in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
671 fairly extreme (by current memory consumption standards) cases.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
672 It must be greater than page size to have any useful effect. To
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
673 disable trimming completely, you can set to (unsigned long)(-1);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
674
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
675
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
676 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
677
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
678
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
679 #ifndef DEFAULT_TOP_PAD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
680 #define DEFAULT_TOP_PAD (0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
681 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
682
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
683 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
684 M_TOP_PAD is the amount of extra `padding' space to allocate or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
685 retain whenever sbrk is called. It is used in two ways internally:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
686
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
687 * When sbrk is called to extend the top of the arena to satisfy
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
688 a new malloc request, this much padding is added to the sbrk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
689 request.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
690
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
691 * When malloc_trim is called automatically from free(),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
692 it is used as the `pad' argument.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
693
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
694 In both cases, the actual amount of padding is rounded
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
695 so that the end of the arena is always a system page boundary.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
696
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
697 The main reason for using padding is to avoid calling sbrk so
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
698 often. Having even a small pad greatly reduces the likelihood
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
699 that nearly every malloc request during program start-up (or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
700 after trimming) will invoke sbrk, which needlessly wastes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
701 time.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
702
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
703 Automatic rounding-up to page-size units is normally sufficient
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
704 to avoid measurable overhead, so the default is 0. However, in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
705 systems where sbrk is relatively slow, it can pay to increase
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
706 this value, at the expense of carrying around more memory than
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
707 the program needs.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
708
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
709 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
710
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
711
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
712 #ifndef DEFAULT_MMAP_THRESHOLD
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
713 #define DEFAULT_MMAP_THRESHOLD (128 * 1024)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
714 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
715
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
716 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
717
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
718 M_MMAP_THRESHOLD is the request size threshold for using mmap()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
719 to service a request. Requests of at least this size that cannot
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
720 be allocated using already-existing space will be serviced via mmap.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
721 (If enough normal freed space already exists it is used instead.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
722
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
723 Using mmap segregates relatively large chunks of memory so that
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
724 they can be individually obtained and released from the host
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
725 system. A request serviced through mmap is never reused by any
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
726 other request (at least not directly; the system may just so
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
727 happen to remap successive requests to the same locations).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
728
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
729 Segregating space in this way has the benefit that mmapped space
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
730 can ALWAYS be individually released back to the system, which
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
731 helps keep the system level memory demands of a long-lived
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
732 program low. Mapped memory can never become `locked' between
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
733 other chunks, as can happen with normally allocated chunks, which
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
734 menas that even trimming via malloc_trim would not release them.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
735
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
736 However, it has the disadvantages that:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
737
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
738 1. The space cannot be reclaimed, consolidated, and then
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
739 used to service later requests, as happens with normal chunks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
740 2. It can lead to more wastage because of mmap page alignment
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
741 requirements
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
742 3. It causes malloc performance to be more dependent on host
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
743 system memory management support routines which may vary in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
744 implementation quality and may impose arbitrary
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
745 limitations. Generally, servicing a request via normal
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
746 malloc steps is faster than going through a system's mmap.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
747
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
748 All together, these considerations should lead you to use mmap
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
749 only for relatively large requests.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
750
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
751
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
752 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
753
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
754
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
755
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
756 #ifndef DEFAULT_MMAP_MAX
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
757 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
758 #define DEFAULT_MMAP_MAX (64)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
759 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
760 #define DEFAULT_MMAP_MAX (0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
761 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
762 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
763
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
764 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
765 M_MMAP_MAX is the maximum number of requests to simultaneously
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
766 service using mmap. This parameter exists because:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
767
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
768 1. Some systems have a limited number of internal tables for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
769 use by mmap.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
770 2. In most systems, overreliance on mmap can degrade overall
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
771 performance.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
772 3. If a program allocates many large regions, it is probably
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
773 better off using normal sbrk-based allocation routines that
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
774 can reclaim and reallocate normal heap memory. Using a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
775 small value allows transition into this mode after the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
776 first few allocations.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
777
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
778 Setting to 0 disables all use of mmap. If HAVE_MMAP is not set,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
779 the default value is 0, and attempts to set it to non-zero values
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
780 in mallopt will fail.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
781 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
782
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
783
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
784
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
785
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
786 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
787 USE_DL_PREFIX will prefix all public routines with the string 'dl'.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
788 Useful to quickly avoid procedure declaration conflicts and linker
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
789 symbol conflicts with existing memory allocation routines.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
790
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
791 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
792
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
793 /* #define USE_DL_PREFIX */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
794
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
795
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
796
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
797
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
798 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
799
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
800 Special defines for linux libc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
801
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
802 Except when compiled using these special defines for Linux libc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
803 using weak aliases, this malloc is NOT designed to work in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
804 multithreaded applications. No semaphores or other concurrency
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
805 control are provided to ensure that multiple malloc or free calls
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
806 don't run at the same time, which could be disasterous. A single
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
807 semaphore could be used across malloc, realloc, and free (which is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
808 essentially the effect of the linux weak alias approach). It would
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
809 be hard to obtain finer granularity.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
810
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
811 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
812
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
813
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
814 #ifdef INTERNAL_LINUX_C_LIB
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
815
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
816 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
817
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
818 Void_t * __default_morecore_init (ptrdiff_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
819 Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
820
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
821 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
822
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
823 Void_t * __default_morecore_init ();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
824 Void_t *(*__morecore)() = __default_morecore_init;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
825
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
826 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
827
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
828 #define MORECORE (*__morecore)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
829 #define MORECORE_FAILURE 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
830 #define MORECORE_CLEARS 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
831
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
832 #else /* INTERNAL_LINUX_C_LIB */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
833
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
834 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
835 extern Void_t* sbrk(ptrdiff_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
836 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
837 extern Void_t* sbrk();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
838 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
839
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
840 #ifndef MORECORE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
841 #define MORECORE sbrk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
842 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
843
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
844 #ifndef MORECORE_FAILURE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
845 #define MORECORE_FAILURE -1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
846 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
847
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
848 #ifndef MORECORE_CLEARS
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
849 #define MORECORE_CLEARS 1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
850 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
851
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
852 #endif /* INTERNAL_LINUX_C_LIB */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
853
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
854 #if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
855
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
856 #define cALLOc __libc_calloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
857 #define fREe __libc_free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
858 #define mALLOc __libc_malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
859 #define mEMALIGn __libc_memalign
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
860 #define rEALLOc __libc_realloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
861 #define vALLOc __libc_valloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
862 #define pvALLOc __libc_pvalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
863 #define mALLINFo __libc_mallinfo
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
864 #define mALLOPt __libc_mallopt
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
865
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
866 #pragma weak calloc = __libc_calloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
867 #pragma weak free = __libc_free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
868 #pragma weak cfree = __libc_free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
869 #pragma weak malloc = __libc_malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
870 #pragma weak memalign = __libc_memalign
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
871 #pragma weak realloc = __libc_realloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
872 #pragma weak valloc = __libc_valloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
873 #pragma weak pvalloc = __libc_pvalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
874 #pragma weak mallinfo = __libc_mallinfo
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
875 #pragma weak mallopt = __libc_mallopt
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
876
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
877 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
878
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
879 #ifdef USE_DL_PREFIX
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
880 #define cALLOc dlcalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
881 #define fREe dlfree
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
882 #define mALLOc dlmalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
883 #define mEMALIGn dlmemalign
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
884 #define rEALLOc dlrealloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
885 #define vALLOc dlvalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
886 #define pvALLOc dlpvalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
887 #define mALLINFo dlmallinfo
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
888 #define mALLOPt dlmallopt
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
889 #else /* USE_DL_PREFIX */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
890 #define cALLOc calloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
891 #define fREe free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
892 #define mALLOc malloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
893 #define mEMALIGn memalign
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
894 #define rEALLOc realloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
895 #define vALLOc valloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
896 #define pvALLOc pvalloc
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
897 #define mALLINFo mallinfo
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
898 #define mALLOPt mallopt
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
899 #endif /* USE_DL_PREFIX */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
900
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
901 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
902
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
903 /* Public routines */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
904
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
905 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
906
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
907 Void_t* mALLOc(size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
908 void fREe(Void_t*);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
909 Void_t* rEALLOc(Void_t*, size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
910 Void_t* mEMALIGn(size_t, size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
911 Void_t* vALLOc(size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
912 Void_t* pvALLOc(size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
913 Void_t* cALLOc(size_t, size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
914 void cfree(Void_t*);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
915 int malloc_trim(size_t);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
916 size_t malloc_usable_size(Void_t*);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
917 void malloc_stats();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
918 int mALLOPt(int, int);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
919 struct mallinfo mALLINFo(void);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
920 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
921 Void_t* mALLOc();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
922 void fREe();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
923 Void_t* rEALLOc();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
924 Void_t* mEMALIGn();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
925 Void_t* vALLOc();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
926 Void_t* pvALLOc();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
927 Void_t* cALLOc();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
928 void cfree();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
929 int malloc_trim();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
930 size_t malloc_usable_size();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
931 void malloc_stats();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
932 int mALLOPt();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
933 struct mallinfo mALLINFo();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
934 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
935
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
936
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
937 #ifdef __cplusplus
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
938 }; /* end of extern "C" */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
939 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
940
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
941 /* ---------- To make a malloc.h, end cutting here ------------ */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
942
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
943
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
944 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
945 Emulation of sbrk for WIN32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
946 All code within the ifdef WIN32 is untested by me.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
947
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
948 Thanks to Martin Fong and others for supplying this.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
949 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
950
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
951
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
952 #ifdef WIN32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
953
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
954 #define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
955 ~(malloc_getpagesize-1))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
956 #define AlignPage64K(add) (((add) + (0x10000 - 1)) & ~(0x10000 - 1))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
957
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
958 /* resrve 64MB to insure large contiguous space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
959 #define RESERVED_SIZE (1024*1024*64)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
960 #define NEXT_SIZE (2048*1024)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
961 #define TOP_MEMORY ((unsigned long)2*1024*1024*1024)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
962
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
963 struct GmListElement;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
964 typedef struct GmListElement GmListElement;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
965
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
966 struct GmListElement
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
967 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
968 GmListElement* next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
969 void* base;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
970 };
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
971
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
972 static GmListElement* head = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
973 static unsigned int gNextAddress = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
974 static unsigned int gAddressBase = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
975 static unsigned int gAllocatedSize = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
976
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
977 static
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
978 GmListElement* makeGmListElement (void* bas)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
979 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
980 GmListElement* this;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
981 this = (GmListElement*)(void*)LocalAlloc (0, sizeof (GmListElement));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
982 assert (this);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
983 if (this)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
984 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
985 this->base = bas;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
986 this->next = head;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
987 head = this;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
988 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
989 return this;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
990 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
991
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
992 void gcleanup ()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
993 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
994 BOOL rval;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
995 assert ( (head == NULL) || (head->base == (void*)gAddressBase));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
996 if (gAddressBase && (gNextAddress - gAddressBase))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
997 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
998 rval = VirtualFree ((void*)gAddressBase,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
999 gNextAddress - gAddressBase,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1000 MEM_DECOMMIT);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1001 assert (rval);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1002 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1003 while (head)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1004 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1005 GmListElement* next = head->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1006 rval = VirtualFree (head->base, 0, MEM_RELEASE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1007 assert (rval);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1008 LocalFree (head);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1009 head = next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1010 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1011 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1012
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1013 static
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1014 void* findRegion (void* start_address, unsigned long size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1015 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1016 MEMORY_BASIC_INFORMATION info;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1017 if (size >= TOP_MEMORY) return NULL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1018
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1019 while ((unsigned long)start_address + size < TOP_MEMORY)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1020 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1021 VirtualQuery (start_address, &info, sizeof (info));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1022 if ((info.State == MEM_FREE) && (info.RegionSize >= size))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1023 return start_address;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1024 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1025 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1026 // Requested region is not available so see if the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1027 // next region is available. Set 'start_address'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1028 // to the next region and call 'VirtualQuery()'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1029 // again.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1030
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1031 start_address = (char*)info.BaseAddress + info.RegionSize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1032
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1033 // Make sure we start looking for the next region
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1034 // on the *next* 64K boundary. Otherwise, even if
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1035 // the new region is free according to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1036 // 'VirtualQuery()', the subsequent call to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1037 // 'VirtualAlloc()' (which follows the call to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1038 // this routine in 'wsbrk()') will round *down*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1039 // the requested address to a 64K boundary which
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1040 // we already know is an address in the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1041 // unavailable region. Thus, the subsequent call
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1042 // to 'VirtualAlloc()' will fail and bring us back
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1043 // here, causing us to go into an infinite loop.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1044
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1045 start_address =
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1046 (void *) AlignPage64K((unsigned long) start_address);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1047 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1048 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1049 return NULL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1050
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1051 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1052
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1053
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1054 void* wsbrk (long size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1055 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1056 void* tmp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1057 if (size > 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1058 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1059 if (gAddressBase == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1060 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1061 gAllocatedSize = max (RESERVED_SIZE, AlignPage (size));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1062 gNextAddress = gAddressBase =
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1063 (unsigned int)VirtualAlloc (NULL, gAllocatedSize,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1064 MEM_RESERVE, PAGE_NOACCESS);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1065 } else if (AlignPage (gNextAddress + size) > (gAddressBase +
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1066 gAllocatedSize))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1067 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1068 long new_size = max (NEXT_SIZE, AlignPage (size));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1069 void* new_address = (void*)(gAddressBase+gAllocatedSize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1070 do
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1071 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1072 new_address = findRegion (new_address, new_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1073
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1074 if (new_address == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1075 return (void*)-1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1076
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1077 gAddressBase = gNextAddress =
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1078 (unsigned int)VirtualAlloc (new_address, new_size,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1079 MEM_RESERVE, PAGE_NOACCESS);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1080 // repeat in case of race condition
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1081 // The region that we found has been snagged
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1082 // by another thread
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1083 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1084 while (gAddressBase == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1085
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1086 assert (new_address == (void*)gAddressBase);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1087
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1088 gAllocatedSize = new_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1089
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1090 if (!makeGmListElement ((void*)gAddressBase))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1091 return (void*)-1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1092 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1093 if ((size + gNextAddress) > AlignPage (gNextAddress))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1094 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1095 void* res;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1096 res = VirtualAlloc ((void*)AlignPage (gNextAddress),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1097 (size + gNextAddress -
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1098 AlignPage (gNextAddress)),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1099 MEM_COMMIT, PAGE_READWRITE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1100 if (res == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1101 return (void*)-1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1102 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1103 tmp = (void*)gNextAddress;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1104 gNextAddress = (unsigned int)tmp + size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1105 return tmp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1106 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1107 else if (size < 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1108 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1109 unsigned int alignedGoal = AlignPage (gNextAddress + size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1110 /* Trim by releasing the virtual memory */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1111 if (alignedGoal >= gAddressBase)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1112 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1113 VirtualFree ((void*)alignedGoal, gNextAddress - alignedGoal,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1114 MEM_DECOMMIT);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1115 gNextAddress = gNextAddress + size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1116 return (void*)gNextAddress;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1117 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1118 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1119 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1120 VirtualFree ((void*)gAddressBase, gNextAddress - gAddressBase,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1121 MEM_DECOMMIT);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1122 gNextAddress = gAddressBase;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1123 return (void*)-1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1124 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1125 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1126 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1127 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1128 return (void*)gNextAddress;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1129 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1130 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1131
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1132 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1133
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1134
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1135
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1136 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1137 Type declarations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1138 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1139
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1140
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1141 struct malloc_chunk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1142 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1143 INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1144 INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1145 struct malloc_chunk* fd; /* double links -- used only if free. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1146 struct malloc_chunk* bk;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1147 };
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1148
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1149 typedef struct malloc_chunk* mchunkptr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1150
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1151 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1152
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1153 malloc_chunk details:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1154
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1155 (The following includes lightly edited explanations by Colin Plumb.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1156
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1157 Chunks of memory are maintained using a `boundary tag' method as
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1158 described in e.g., Knuth or Standish. (See the paper by Paul
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1159 Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1160 survey of such techniques.) Sizes of free chunks are stored both
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1161 in the front of each chunk and at the end. This makes
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1162 consolidating fragmented chunks into bigger chunks very fast. The
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1163 size fields also hold bits representing whether chunks are free or
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1164 in use.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1165
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1166 An allocated chunk looks like this:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1167
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1168
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1169 chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1170 | Size of previous chunk, if allocated | |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1171 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1172 | Size of chunk, in bytes |P|
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1173 mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1174 | User data starts here... .
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1175 . .
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1176 . (malloc_usable_space() bytes) .
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1177 . |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1178 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1179 | Size of chunk |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1180 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1181
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1182
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1183 Where "chunk" is the front of the chunk for the purpose of most of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1184 the malloc code, but "mem" is the pointer that is returned to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1185 user. "Nextchunk" is the beginning of the next contiguous chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1186
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1187 Chunks always begin on even word boundries, so the mem portion
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1188 (which is returned to the user) is also on an even word boundary, and
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1189 thus double-word aligned.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1190
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1191 Free chunks are stored in circular doubly-linked lists, and look like this:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1192
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1193 chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1194 | Size of previous chunk |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1195 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1196 `head:' | Size of chunk, in bytes |P|
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1197 mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1198 | Forward pointer to next chunk in list |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1199 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1200 | Back pointer to previous chunk in list |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1201 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1202 | Unused space (may be 0 bytes long) .
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1203 . .
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1204 . |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1205 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1206 `foot:' | Size of chunk, in bytes |
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1207 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1208
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1209 The P (PREV_INUSE) bit, stored in the unused low-order bit of the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1210 chunk size (which is always a multiple of two words), is an in-use
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1211 bit for the *previous* chunk. If that bit is *clear*, then the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1212 word before the current chunk size contains the previous chunk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1213 size, and can be used to find the front of the previous chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1214 (The very first chunk allocated always has this bit set,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1215 preventing access to non-existent (or non-owned) memory.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1216
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1217 Note that the `foot' of the current chunk is actually represented
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1218 as the prev_size of the NEXT chunk. (This makes it easier to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1219 deal with alignments etc).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1220
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1221 The two exceptions to all this are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1222
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1223 1. The special chunk `top', which doesn't bother using the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1224 trailing size field since there is no
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1225 next contiguous chunk that would have to index off it. (After
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1226 initialization, `top' is forced to always exist. If it would
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1227 become less than MINSIZE bytes long, it is replenished via
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1228 malloc_extend_top.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1229
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1230 2. Chunks allocated via mmap, which have the second-lowest-order
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1231 bit (IS_MMAPPED) set in their size fields. Because they are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1232 never merged or traversed from any other chunk, they have no
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1233 foot size or inuse information.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1234
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1235 Available chunks are kept in any of several places (all declared below):
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1236
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1237 * `av': An array of chunks serving as bin headers for consolidated
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1238 chunks. Each bin is doubly linked. The bins are approximately
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1239 proportionally (log) spaced. There are a lot of these bins
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1240 (128). This may look excessive, but works very well in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1241 practice. All procedures maintain the invariant that no
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1242 consolidated chunk physically borders another one. Chunks in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1243 bins are kept in size order, with ties going to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1244 approximately least recently used chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1245
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1246 The chunks in each bin are maintained in decreasing sorted order by
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1247 size. This is irrelevant for the small bins, which all contain
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1248 the same-sized chunks, but facilitates best-fit allocation for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1249 larger chunks. (These lists are just sequential. Keeping them in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1250 order almost never requires enough traversal to warrant using
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1251 fancier ordered data structures.) Chunks of the same size are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1252 linked with the most recently freed at the front, and allocations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1253 are taken from the back. This results in LRU or FIFO allocation
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1254 order, which tends to give each chunk an equal opportunity to be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1255 consolidated with adjacent freed chunks, resulting in larger free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1256 chunks and less fragmentation.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1257
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1258 * `top': The top-most available chunk (i.e., the one bordering the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1259 end of available memory) is treated specially. It is never
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1260 included in any bin, is used only if no other chunk is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1261 available, and is released back to the system if it is very
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1262 large (see M_TRIM_THRESHOLD).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1263
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1264 * `last_remainder': A bin holding only the remainder of the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1265 most recently split (non-top) chunk. This bin is checked
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1266 before other non-fitting chunks, so as to provide better
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1267 locality for runs of sequentially allocated chunks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1268
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1269 * Implicitly, through the host system's memory mapping tables.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1270 If supported, requests greater than a threshold are usually
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1271 serviced via calls to mmap, and then later released via munmap.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1272
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1273 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1274
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1275
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1276
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1277
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1278
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1279
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1280 /* sizes, alignments */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1281
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1282 #define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1283 #define MALLOC_ALIGNMENT (SIZE_SZ + SIZE_SZ)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1284 #define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1285 #define MINSIZE (sizeof(struct malloc_chunk))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1286
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1287 /* conversion from malloc headers to user pointers, and back */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1288
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1289 #define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1290 #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1291
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1292 /* pad request bytes into a usable size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1293
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1294 #define request2size(req) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1295 (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1296 (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1297 (((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1298
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1299 /* Check if m has acceptable alignment */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1300
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1301 #define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1302
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1303
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1304
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1305
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1306 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1307 Physical chunk operations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1308 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1309
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1310
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1311 /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1312
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1313 #define PREV_INUSE 0x1
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1314
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1315 /* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1316
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1317 #define IS_MMAPPED 0x2
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1318
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1319 /* Bits to mask off when extracting size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1320
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1321 #define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1322
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1323
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1324 /* Ptr to next physical malloc_chunk. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1325
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1326 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1327
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1328 /* Ptr to previous physical malloc_chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1329
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1330 #define prev_chunk(p)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1331 ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1332
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1333
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1334 /* Treat space at ptr + offset as a chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1335
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1336 #define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1337
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1338
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1339
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1340
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1341 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1342 Dealing with use bits
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1343 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1344
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1345 /* extract p's inuse bit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1346
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1347 #define inuse(p)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1348 ((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1349
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1350 /* extract inuse bit of previous chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1351
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1352 #define prev_inuse(p) ((p)->size & PREV_INUSE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1353
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1354 /* check for mmap()'ed chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1355
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1356 #define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1357
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1358 /* set/clear chunk as in use without otherwise disturbing */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1359
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1360 #define set_inuse(p)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1361 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1362
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1363 #define clear_inuse(p)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1364 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1365
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1366 /* check/set/clear inuse bits in known places */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1367
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1368 #define inuse_bit_at_offset(p, s)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1369 (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1370
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1371 #define set_inuse_bit_at_offset(p, s)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1372 (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1373
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1374 #define clear_inuse_bit_at_offset(p, s)\
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1375 (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1376
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1377
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1378
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1379
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1380 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1381 Dealing with size fields
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1382 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1383
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1384 /* Get size, ignoring use bits */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1385
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1386 #define chunksize(p) ((p)->size & ~(SIZE_BITS))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1387
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1388 /* Set size at head, without disturbing its use bit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1389
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1390 #define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1391
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1392 /* Set size/use ignoring previous bits in header */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1393
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1394 #define set_head(p, s) ((p)->size = (s))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1395
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1396 /* Set size at footer (only when chunk is not in use) */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1397
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1398 #define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1399
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1400
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1401
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1402
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1403
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1404 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1405 Bins
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1406
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1407 The bins, `av_' are an array of pairs of pointers serving as the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1408 heads of (initially empty) doubly-linked lists of chunks, laid out
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1409 in a way so that each pair can be treated as if it were in a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1410 malloc_chunk. (This way, the fd/bk offsets for linking bin heads
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1411 and chunks are the same).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1412
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1413 Bins for sizes < 512 bytes contain chunks of all the same size, spaced
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1414 8 bytes apart. Larger bins are approximately logarithmically
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1415 spaced. (See the table below.) The `av_' array is never mentioned
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1416 directly in the code, but instead via bin access macros.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1417
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1418 Bin layout:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1419
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1420 64 bins of size 8
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1421 32 bins of size 64
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1422 16 bins of size 512
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1423 8 bins of size 4096
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1424 4 bins of size 32768
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1425 2 bins of size 262144
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1426 1 bin of size what's left
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1427
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1428 There is actually a little bit of slop in the numbers in bin_index
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1429 for the sake of speed. This makes no difference elsewhere.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1430
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1431 The special chunks `top' and `last_remainder' get their own bins,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1432 (this is implemented via yet more trickery with the av_ array),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1433 although `top' is never properly linked to its bin since it is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1434 always handled specially.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1435
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1436 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1437
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1438 #define NAV 128 /* number of bins */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1439
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1440 typedef struct malloc_chunk* mbinptr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1441
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1442 /* access macros */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1443
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1444 #define bin_at(i) ((mbinptr)((char*)&(av_[2*(i) + 2]) - 2*SIZE_SZ))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1445 #define next_bin(b) ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1446 #define prev_bin(b) ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1447
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1448 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1449 The first 2 bins are never indexed. The corresponding av_ cells are instead
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1450 used for bookkeeping. This is not to save space, but to simplify
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1451 indexing, maintain locality, and avoid some initialization tests.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1452 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1453
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1454 #define top (bin_at(0)->fd) /* The topmost chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1455 #define last_remainder (bin_at(1)) /* remainder from last split */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1456
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1457
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1458 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1459 Because top initially points to its own bin with initial
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1460 zero size, thus forcing extension on the first malloc request,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1461 we avoid having any special code in malloc to check whether
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1462 it even exists yet. But we still need to in malloc_extend_top.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1463 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1464
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1465 #define initial_top ((mchunkptr)(bin_at(0)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1466
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1467 /* Helper macro to initialize bins */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1468
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1469 #define IAV(i) bin_at(i), bin_at(i)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1470
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1471 static mbinptr av_[NAV * 2 + 2] = {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1472 0, 0,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1473 IAV(0), IAV(1), IAV(2), IAV(3), IAV(4), IAV(5), IAV(6), IAV(7),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1474 IAV(8), IAV(9), IAV(10), IAV(11), IAV(12), IAV(13), IAV(14), IAV(15),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1475 IAV(16), IAV(17), IAV(18), IAV(19), IAV(20), IAV(21), IAV(22), IAV(23),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1476 IAV(24), IAV(25), IAV(26), IAV(27), IAV(28), IAV(29), IAV(30), IAV(31),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1477 IAV(32), IAV(33), IAV(34), IAV(35), IAV(36), IAV(37), IAV(38), IAV(39),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1478 IAV(40), IAV(41), IAV(42), IAV(43), IAV(44), IAV(45), IAV(46), IAV(47),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1479 IAV(48), IAV(49), IAV(50), IAV(51), IAV(52), IAV(53), IAV(54), IAV(55),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1480 IAV(56), IAV(57), IAV(58), IAV(59), IAV(60), IAV(61), IAV(62), IAV(63),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1481 IAV(64), IAV(65), IAV(66), IAV(67), IAV(68), IAV(69), IAV(70), IAV(71),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1482 IAV(72), IAV(73), IAV(74), IAV(75), IAV(76), IAV(77), IAV(78), IAV(79),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1483 IAV(80), IAV(81), IAV(82), IAV(83), IAV(84), IAV(85), IAV(86), IAV(87),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1484 IAV(88), IAV(89), IAV(90), IAV(91), IAV(92), IAV(93), IAV(94), IAV(95),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1485 IAV(96), IAV(97), IAV(98), IAV(99), IAV(100), IAV(101), IAV(102), IAV(103),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1486 IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1487 IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1488 IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1489 };
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1490
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1491
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1492
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1493 /* field-extraction macros */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1494
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1495 #define first(b) ((b)->fd)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1496 #define last(b) ((b)->bk)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1497
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1498 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1499 Indexing into bins
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1500 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1501
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1502 #define bin_index(sz) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1503 (((((unsigned long)(sz)) >> 9) == 0) ? (((unsigned long)(sz)) >> 3): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1504 ((((unsigned long)(sz)) >> 9) <= 4) ? 56 + (((unsigned long)(sz)) >> 6): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1505 ((((unsigned long)(sz)) >> 9) <= 20) ? 91 + (((unsigned long)(sz)) >> 9): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1506 ((((unsigned long)(sz)) >> 9) <= 84) ? 110 + (((unsigned long)(sz)) >> 12): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1507 ((((unsigned long)(sz)) >> 9) <= 340) ? 119 + (((unsigned long)(sz)) >> 15): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1508 ((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18): \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1509 126)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1510 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1511 bins for chunks < 512 are all spaced 8 bytes apart, and hold
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1512 identically sized chunks. This is exploited in malloc.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1513 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1514
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1515 #define MAX_SMALLBIN 63
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1516 #define MAX_SMALLBIN_SIZE 512
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1517 #define SMALLBIN_WIDTH 8
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1518
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1519 #define smallbin_index(sz) (((unsigned long)(sz)) >> 3)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1520
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1521 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1522 Requests are `small' if both the corresponding and the next bin are small
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1523 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1524
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1525 #define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1526
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1527
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1528
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1529 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1530 To help compensate for the large number of bins, a one-level index
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1531 structure is used for bin-by-bin searching. `binblocks' is a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1532 one-word bitvector recording whether groups of BINBLOCKWIDTH bins
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1533 have any (possibly) non-empty bins, so they can be skipped over
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1534 all at once during during traversals. The bits are NOT always
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1535 cleared as soon as all bins in a block are empty, but instead only
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1536 when all are noticed to be empty during traversal in malloc.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1537 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1538
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1539 #define BINBLOCKWIDTH 4 /* bins per block */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1540
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1541 #define binblocks (bin_at(0)->size) /* bitvector of nonempty blocks */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1542
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1543 /* bin<->block macros */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1544
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1545 #define idx2binblock(ix) ((unsigned)1 << (ix / BINBLOCKWIDTH))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1546 #define mark_binblock(ii) (binblocks |= idx2binblock(ii))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1547 #define clear_binblock(ii) (binblocks &= ~(idx2binblock(ii)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1548
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1549
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1550
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1551
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1552
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1553 /* Other static bookkeeping data */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1554
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1555 /* variables holding tunable values */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1556
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1557 static unsigned long trim_threshold = DEFAULT_TRIM_THRESHOLD;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1558 static unsigned long top_pad = DEFAULT_TOP_PAD;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1559 static unsigned int n_mmaps_max = DEFAULT_MMAP_MAX;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1560 static unsigned long mmap_threshold = DEFAULT_MMAP_THRESHOLD;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1561
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1562 /* The first value returned from sbrk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1563 static char* sbrk_base = (char*)(-1);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1564
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1565 /* The maximum memory obtained from system via sbrk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1566 static unsigned long max_sbrked_mem = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1567
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1568 /* The maximum via either sbrk or mmap */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1569 static unsigned long max_total_mem = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1570
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1571 /* internal working copy of mallinfo */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1572 static struct mallinfo current_mallinfo = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1573
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1574 /* The total memory obtained from system via sbrk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1575 #define sbrked_mem (current_mallinfo.arena)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1576
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1577 /* Tracking mmaps */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1578
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1579 static unsigned int n_mmaps = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1580 static unsigned int max_n_mmaps = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1581 static unsigned long mmapped_mem = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1582 static unsigned long max_mmapped_mem = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1583
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1584
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1585
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1586 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1587 Debugging support
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1588 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1589
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1590 #if DEBUG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1591
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1592
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1593 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1594 These routines make a number of assertions about the states
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1595 of data structures that should be true at all times. If any
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1596 are not true, it's very likely that a user program has somehow
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1597 trashed memory. (It's also possible that there is a coding error
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1598 in malloc. In which case, please report it!)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1599 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1600
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1601 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1602 static void do_check_chunk(mchunkptr p)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1603 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1604 static void do_check_chunk(p) mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1605 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1606 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1607 INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1608
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1609 /* No checkable chunk is mmapped */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1610 assert(!chunk_is_mmapped(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1611
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1612 /* Check for legal address ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1613 assert((char*)p >= sbrk_base);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1614 if (p != top)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1615 assert((char*)p + sz <= (char*)top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1616 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1617 assert((char*)p + sz <= sbrk_base + sbrked_mem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1618
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1619 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1620
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1621
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1622 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1623 static void do_check_free_chunk(mchunkptr p)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1624 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1625 static void do_check_free_chunk(p) mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1626 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1627 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1628 INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1629 mchunkptr next = chunk_at_offset(p, sz);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1630
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1631 do_check_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1632
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1633 /* Check whether it claims to be free ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1634 assert(!inuse(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1635
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1636 /* Unless a special marker, must have OK fields */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1637 if ((long)sz >= (long)MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1638 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1639 assert((sz & MALLOC_ALIGN_MASK) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1640 assert(aligned_OK(chunk2mem(p)));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1641 /* ... matching footer field */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1642 assert(next->prev_size == sz);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1643 /* ... and is fully consolidated */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1644 assert(prev_inuse(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1645 assert (next == top || inuse(next));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1646
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1647 /* ... and has minimally sane links */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1648 assert(p->fd->bk == p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1649 assert(p->bk->fd == p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1650 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1651 else /* markers are always of size SIZE_SZ */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1652 assert(sz == SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1653 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1654
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1655 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1656 static void do_check_inuse_chunk(mchunkptr p)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1657 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1658 static void do_check_inuse_chunk(p) mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1659 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1660 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1661 mchunkptr next = next_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1662 do_check_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1663
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1664 /* Check whether it claims to be in use ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1665 assert(inuse(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1666
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1667 /* ... and is surrounded by OK chunks.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1668 Since more things can be checked with free chunks than inuse ones,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1669 if an inuse chunk borders them and debug is on, it's worth doing them.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1670 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1671 if (!prev_inuse(p))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1672 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1673 mchunkptr prv = prev_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1674 assert(next_chunk(prv) == p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1675 do_check_free_chunk(prv);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1676 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1677 if (next == top)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1678 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1679 assert(prev_inuse(next));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1680 assert(chunksize(next) >= MINSIZE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1681 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1682 else if (!inuse(next))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1683 do_check_free_chunk(next);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1684
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1685 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1686
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1687 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1688 static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1689 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1690 static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1691 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1692 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1693 INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1694 long room = sz - s;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1695
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1696 do_check_inuse_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1697
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1698 /* Legal size ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1699 assert((long)sz >= (long)MINSIZE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1700 assert((sz & MALLOC_ALIGN_MASK) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1701 assert(room >= 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1702 assert(room < (long)MINSIZE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1703
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1704 /* ... and alignment */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1705 assert(aligned_OK(chunk2mem(p)));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1706
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1707
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1708 /* ... and was allocated at front of an available chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1709 assert(prev_inuse(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1710
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1711 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1712
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1713
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1714 #define check_free_chunk(P) do_check_free_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1715 #define check_inuse_chunk(P) do_check_inuse_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1716 #define check_chunk(P) do_check_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1717 #define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1718 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1719 #define check_free_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1720 #define check_inuse_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1721 #define check_chunk(P)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1722 #define check_malloced_chunk(P,N)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1723 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1724
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1725
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1726
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1727 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1728 Macro-based internal utilities
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1729 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1730
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1731
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1732 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1733 Linking chunks in bin lists.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1734 Call these only with variables, not arbitrary expressions, as arguments.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1735 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1736
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1737 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1738 Place chunk p of size s in its bin, in size order,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1739 putting it ahead of others of same size.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1740 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1741
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1742
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1743 #define frontlink(P, S, IDX, BK, FD) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1744 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1745 if (S < MAX_SMALLBIN_SIZE) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1746 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1747 IDX = smallbin_index(S); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1748 mark_binblock(IDX); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1749 BK = bin_at(IDX); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1750 FD = BK->fd; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1751 P->bk = BK; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1752 P->fd = FD; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1753 FD->bk = BK->fd = P; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1754 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1755 else \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1756 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1757 IDX = bin_index(S); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1758 BK = bin_at(IDX); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1759 FD = BK->fd; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1760 if (FD == BK) mark_binblock(IDX); \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1761 else \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1762 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1763 while (FD != BK && S < chunksize(FD)) FD = FD->fd; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1764 BK = FD->bk; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1765 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1766 P->bk = BK; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1767 P->fd = FD; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1768 FD->bk = BK->fd = P; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1769 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1770 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1771
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1772
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1773 /* take a chunk off a list */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1774
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1775 #define unlink(P, BK, FD) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1776 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1777 BK = P->bk; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1778 FD = P->fd; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1779 FD->bk = BK; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1780 BK->fd = FD; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1781 } \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1782
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1783 /* Place p as the last remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1784
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1785 #define link_last_remainder(P) \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1786 { \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1787 last_remainder->fd = last_remainder->bk = P; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1788 P->fd = P->bk = last_remainder; \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1789 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1790
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1791 /* Clear the last_remainder bin */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1792
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1793 #define clear_last_remainder \
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1794 (last_remainder->fd = last_remainder->bk = last_remainder)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1795
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1796
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1797
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1798
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1799
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1800
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1801 /* Routines dealing with mmap(). */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1802
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1803 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1804
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1805 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1806 static mchunkptr mmap_chunk(size_t size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1807 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1808 static mchunkptr mmap_chunk(size) size_t size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1809 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1810 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1811 size_t page_mask = malloc_getpagesize - 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1812 mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1813
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1814 #ifndef MAP_ANONYMOUS
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1815 static int fd = -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1816 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1817
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1818 if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1819
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1820 /* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1821 * there is no following chunk whose prev_size field could be used.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1822 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1823 size = (size + SIZE_SZ + page_mask) & ~page_mask;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1824
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1825 #ifdef MAP_ANONYMOUS
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1826 p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1827 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1828 #else /* !MAP_ANONYMOUS */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1829 if (fd < 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1830 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1831 fd = open("/dev/zero", O_RDWR);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1832 if(fd < 0) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1833 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1834 p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1835 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1836
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1837 if(p == (mchunkptr)-1) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1838
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1839 n_mmaps++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1840 if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1841
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1842 /* We demand that eight bytes into a page must be 8-byte aligned. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1843 assert(aligned_OK(chunk2mem(p)));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1844
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1845 /* The offset to the start of the mmapped region is stored
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1846 * in the prev_size field of the chunk; normally it is zero,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1847 * but that can be changed in memalign().
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1848 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1849 p->prev_size = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1850 set_head(p, size|IS_MMAPPED);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1851
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1852 mmapped_mem += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1853 if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1854 max_mmapped_mem = mmapped_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1855 if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1856 max_total_mem = mmapped_mem + sbrked_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1857 return p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1858 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1859
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1860 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1861 static void munmap_chunk(mchunkptr p)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1862 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1863 static void munmap_chunk(p) mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1864 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1865 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1866 INTERNAL_SIZE_T size = chunksize(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1867 int ret;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1868
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1869 assert (chunk_is_mmapped(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1870 assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1871 assert((n_mmaps > 0));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1872 assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1873
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1874 n_mmaps--;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1875 mmapped_mem -= (size + p->prev_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1876
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1877 ret = munmap((char *)p - p->prev_size, size + p->prev_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1878
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1879 /* munmap returns non-zero on failure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1880 assert(ret == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1881 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1882
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1883 #if HAVE_MREMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1884
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1885 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1886 static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1887 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1888 static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1889 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1890 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1891 size_t page_mask = malloc_getpagesize - 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1892 INTERNAL_SIZE_T offset = p->prev_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1893 INTERNAL_SIZE_T size = chunksize(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1894 char *cp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1895
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1896 assert (chunk_is_mmapped(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1897 assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1898 assert((n_mmaps > 0));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1899 assert(((size + offset) & (malloc_getpagesize-1)) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1900
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1901 /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1902 new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1903
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1904 cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1905
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1906 if (cp == (char *)-1) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1907
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1908 p = (mchunkptr)(cp + offset);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1909
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1910 assert(aligned_OK(chunk2mem(p)));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1911
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1912 assert((p->prev_size == offset));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1913 set_head(p, (new_size - offset)|IS_MMAPPED);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1914
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1915 mmapped_mem -= size + offset;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1916 mmapped_mem += new_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1917 if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1918 max_mmapped_mem = mmapped_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1919 if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1920 max_total_mem = mmapped_mem + sbrked_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1921 return p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1922 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1923
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1924 #endif /* HAVE_MREMAP */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1925
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1926 #endif /* HAVE_MMAP */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1927
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1928
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1929
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1930
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1931 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1932 Extend the top-most chunk by obtaining memory from system.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1933 Main interface to sbrk (but see also malloc_trim).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1934 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1935
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1936 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1937 static void malloc_extend_top(INTERNAL_SIZE_T nb)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1938 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1939 static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1940 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1941 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1942 char* brk; /* return value from sbrk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1943 INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1944 INTERNAL_SIZE_T correction; /* bytes for 2nd sbrk call */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1945 char* new_brk; /* return of 2nd sbrk call */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1946 INTERNAL_SIZE_T top_size; /* new size of top chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1947
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1948 mchunkptr old_top = top; /* Record state of old top */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1949 INTERNAL_SIZE_T old_top_size = chunksize(old_top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1950 char* old_end = (char*)(chunk_at_offset(old_top, old_top_size));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1951
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1952 /* Pad request with top_pad plus minimal overhead */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1953
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1954 INTERNAL_SIZE_T sbrk_size = nb + top_pad + MINSIZE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1955 unsigned long pagesz = malloc_getpagesize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1956
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1957 /* If not the first time through, round to preserve page boundary */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1958 /* Otherwise, we need to correct to a page size below anyway. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1959 /* (We also correct below if an intervening foreign sbrk call.) */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1960
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1961 if (sbrk_base != (char*)(-1))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1962 sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1963
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1964 brk = (char*)(MORECORE (sbrk_size));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1965
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1966 /* Fail if sbrk failed or if a foreign sbrk call killed our space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1967 if (brk == (char*)(MORECORE_FAILURE) ||
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1968 (brk < old_end && old_top != initial_top))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1969 return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1970
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1971 sbrked_mem += sbrk_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1972
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1973 if (brk == old_end) /* can just add bytes to current top */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1974 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1975 top_size = sbrk_size + old_top_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1976 set_head(top, top_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1977 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1978 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1979 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1980 if (sbrk_base == (char*)(-1)) /* First time through. Record base */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1981 sbrk_base = brk;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1982 else /* Someone else called sbrk(). Count those bytes as sbrked_mem. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1983 sbrked_mem += brk - (char*)old_end;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1984
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1985 /* Guarantee alignment of first new chunk made from this space */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1986 front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1987 if (front_misalign > 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1988 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1989 correction = (MALLOC_ALIGNMENT) - front_misalign;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1990 brk += correction;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1991 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1992 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1993 correction = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1994
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1995 /* Guarantee the next brk will be at a page boundary */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1996
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1997 correction += ((((unsigned long)(brk + sbrk_size))+(pagesz-1)) &
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1998 ~(pagesz - 1)) - ((unsigned long)(brk + sbrk_size));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1999
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2000 /* Allocate correction */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2001 new_brk = (char*)(MORECORE (correction));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2002 if (new_brk == (char*)(MORECORE_FAILURE)) return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2003
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2004 sbrked_mem += correction;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2005
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2006 top = (mchunkptr)brk;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2007 top_size = new_brk - brk + correction;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2008 set_head(top, top_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2009
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2010 if (old_top != initial_top)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2011 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2012
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2013 /* There must have been an intervening foreign sbrk call. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2014 /* A double fencepost is necessary to prevent consolidation */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2015
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2016 /* If not enough space to do this, then user did something very wrong */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2017 if (old_top_size < MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2018 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2019 set_head(top, PREV_INUSE); /* will force null return from malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2020 return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2021 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2022
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2023 /* Also keep size a multiple of MALLOC_ALIGNMENT */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2024 old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2025 set_head_size(old_top, old_top_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2026 chunk_at_offset(old_top, old_top_size )->size =
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2027 SIZE_SZ|PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2028 chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2029 SIZE_SZ|PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2030 /* If possible, release the rest. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2031 if (old_top_size >= MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2032 fREe(chunk2mem(old_top));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2033 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2034 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2035
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2036 if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2037 max_sbrked_mem = sbrked_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2038 if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2039 max_total_mem = mmapped_mem + sbrked_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2040
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2041 /* We always land on a page boundary */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2042 assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2043 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2044
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2045
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2046
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2047
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2048 /* Main public routines */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2049
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2050
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2051 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2052 Malloc Algorthim:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2053
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2054 The requested size is first converted into a usable form, `nb'.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2055 This currently means to add 4 bytes overhead plus possibly more to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2056 obtain 8-byte alignment and/or to obtain a size of at least
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2057 MINSIZE (currently 16 bytes), the smallest allocatable size.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2058 (All fits are considered `exact' if they are within MINSIZE bytes.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2059
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2060 From there, the first successful of the following steps is taken:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2061
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2062 1. The bin corresponding to the request size is scanned, and if
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2063 a chunk of exactly the right size is found, it is taken.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2064
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2065 2. The most recently remaindered chunk is used if it is big
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2066 enough. This is a form of (roving) first fit, used only in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2067 the absence of exact fits. Runs of consecutive requests use
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2068 the remainder of the chunk used for the previous such request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2069 whenever possible. This limited use of a first-fit style
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2070 allocation strategy tends to give contiguous chunks
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2071 coextensive lifetimes, which improves locality and can reduce
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2072 fragmentation in the long run.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2073
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2074 3. Other bins are scanned in increasing size order, using a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2075 chunk big enough to fulfill the request, and splitting off
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2076 any remainder. This search is strictly by best-fit; i.e.,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2077 the smallest (with ties going to approximately the least
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2078 recently used) chunk that fits is selected.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2079
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2080 4. If large enough, the chunk bordering the end of memory
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2081 (`top') is split off. (This use of `top' is in accord with
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2082 the best-fit search rule. In effect, `top' is treated as
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2083 larger (and thus less well fitting) than any other available
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2084 chunk since it can be extended to be as large as necessary
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2085 (up to system limitations).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2086
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2087 5. If the request size meets the mmap threshold and the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2088 system supports mmap, and there are few enough currently
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2089 allocated mmapped regions, and a call to mmap succeeds,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2090 the request is allocated via direct memory mapping.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2091
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2092 6. Otherwise, the top of memory is extended by
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2093 obtaining more space from the system (normally using sbrk,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2094 but definable to anything else via the MORECORE macro).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2095 Memory is gathered from the system (in system page-sized
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2096 units) in a way that allows chunks obtained across different
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2097 sbrk calls to be consolidated, but does not require
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2098 contiguous memory. Thus, it should be safe to intersperse
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2099 mallocs with other sbrk calls.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2100
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2101
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2102 All allocations are made from the the `lowest' part of any found
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2103 chunk. (The implementation invariant is that prev_inuse is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2104 always true of any allocated chunk; i.e., that each allocated
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2105 chunk borders either a previously allocated and still in-use chunk,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2106 or the base of its memory arena.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2107
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2108 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2109
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2110 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2111 Void_t* mALLOc(size_t bytes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2112 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2113 Void_t* mALLOc(bytes) size_t bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2114 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2115 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2116 mchunkptr victim; /* inspected/selected chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2117 INTERNAL_SIZE_T victim_size; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2118 int idx; /* index for bin traversal */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2119 mbinptr bin; /* associated bin */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2120 mchunkptr remainder; /* remainder from a split */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2121 long remainder_size; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2122 int remainder_index; /* its bin index */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2123 unsigned long block; /* block traverser bit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2124 int startidx; /* first bin of a traversed block */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2125 mchunkptr fwd; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2126 mchunkptr bck; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2127 mbinptr q; /* misc temp */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2128
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2129 INTERNAL_SIZE_T nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2130
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2131 if ((long)bytes < 0) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2132
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2133 nb = request2size(bytes); /* padded request size; */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2134
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2135 /* Check for exact match in a bin */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2136
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2137 if (is_small_request(nb)) /* Faster version for small requests */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2138 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2139 idx = smallbin_index(nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2140
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2141 /* No traversal or size check necessary for small bins. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2142
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2143 q = bin_at(idx);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2144 victim = last(q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2145
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2146 /* Also scan the next one, since it would have a remainder < MINSIZE */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2147 if (victim == q)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2148 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2149 q = next_bin(q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2150 victim = last(q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2151 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2152 if (victim != q)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2153 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2154 victim_size = chunksize(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2155 unlink(victim, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2156 set_inuse_bit_at_offset(victim, victim_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2157 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2158 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2159 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2160
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2161 idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2162
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2163 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2164 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2165 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2166 idx = bin_index(nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2167 bin = bin_at(idx);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2168
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2169 for (victim = last(bin); victim != bin; victim = victim->bk)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2170 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2171 victim_size = chunksize(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2172 remainder_size = victim_size - nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2173
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2174 if (remainder_size >= (long)MINSIZE) /* too big */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2175 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2176 --idx; /* adjust to rescan below after checking last remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2177 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2178 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2179
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2180 else if (remainder_size >= 0) /* exact fit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2181 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2182 unlink(victim, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2183 set_inuse_bit_at_offset(victim, victim_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2184 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2185 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2186 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2187 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2188
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2189 ++idx;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2190
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2191 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2192
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2193 /* Try to use the last split-off remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2194
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2195 if ( (victim = last_remainder->fd) != last_remainder)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2196 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2197 victim_size = chunksize(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2198 remainder_size = victim_size - nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2199
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2200 if (remainder_size >= (long)MINSIZE) /* re-split */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2201 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2202 remainder = chunk_at_offset(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2203 set_head(victim, nb | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2204 link_last_remainder(remainder);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2205 set_head(remainder, remainder_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2206 set_foot(remainder, remainder_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2207 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2208 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2209 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2210
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2211 clear_last_remainder;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2212
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2213 if (remainder_size >= 0) /* exhaust */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2214 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2215 set_inuse_bit_at_offset(victim, victim_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2216 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2217 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2218 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2219
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2220 /* Else place in bin */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2221
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2222 frontlink(victim, victim_size, remainder_index, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2223 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2224
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2225 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2226 If there are any possibly nonempty big-enough blocks,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2227 search for best fitting chunk by scanning bins in blockwidth units.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2228 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2229
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2230 if ( (block = idx2binblock(idx)) <= binblocks)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2231 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2232
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2233 /* Get to the first marked block */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2234
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2235 if ( (block & binblocks) == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2236 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2237 /* force to an even block boundary */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2238 idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2239 block <<= 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2240 while ((block & binblocks) == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2241 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2242 idx += BINBLOCKWIDTH;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2243 block <<= 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2244 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2245 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2246
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2247 /* For each possibly nonempty block ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2248 for (;;)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2249 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2250 startidx = idx; /* (track incomplete blocks) */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2251 q = bin = bin_at(idx);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2252
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2253 /* For each bin in this block ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2254 do
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2255 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2256 /* Find and use first big enough chunk ... */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2257
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2258 for (victim = last(bin); victim != bin; victim = victim->bk)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2259 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2260 victim_size = chunksize(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2261 remainder_size = victim_size - nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2262
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2263 if (remainder_size >= (long)MINSIZE) /* split */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2264 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2265 remainder = chunk_at_offset(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2266 set_head(victim, nb | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2267 unlink(victim, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2268 link_last_remainder(remainder);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2269 set_head(remainder, remainder_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2270 set_foot(remainder, remainder_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2271 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2272 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2273 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2274
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2275 else if (remainder_size >= 0) /* take */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2276 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2277 set_inuse_bit_at_offset(victim, victim_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2278 unlink(victim, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2279 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2280 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2281 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2282
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2283 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2284
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2285 bin = next_bin(bin);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2286
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2287 } while ((++idx & (BINBLOCKWIDTH - 1)) != 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2288
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2289 /* Clear out the block bit. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2290
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2291 do /* Possibly backtrack to try to clear a partial block */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2292 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2293 if ((startidx & (BINBLOCKWIDTH - 1)) == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2294 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2295 binblocks &= ~block;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2296 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2297 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2298 --startidx;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2299 q = prev_bin(q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2300 } while (first(q) == q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2301
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2302 /* Get to the next possibly nonempty block */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2303
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2304 if ( (block <<= 1) <= binblocks && (block != 0) )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2305 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2306 while ((block & binblocks) == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2307 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2308 idx += BINBLOCKWIDTH;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2309 block <<= 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2310 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2311 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2312 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2313 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2314 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2315 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2316
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2317
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2318 /* Try to use top chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2319
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2320 /* Require that there be a remainder, ensuring top always exists */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2321 if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2322 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2323
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2324 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2325 /* If big and would otherwise need to extend, try to use mmap instead */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2326 if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2327 (victim = mmap_chunk(nb)) != 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2328 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2329 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2330
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2331 /* Try to extend */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2332 malloc_extend_top(nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2333 if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2334 return 0; /* propagate failure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2335 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2336
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2337 victim = top;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2338 set_head(victim, nb | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2339 top = chunk_at_offset(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2340 set_head(top, remainder_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2341 check_malloced_chunk(victim, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2342 return chunk2mem(victim);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2343
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2344 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2345
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2346
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2347
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2348
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2349 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2350
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2351 free() algorithm :
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2352
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2353 cases:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2354
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2355 1. free(0) has no effect.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2356
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2357 2. If the chunk was allocated via mmap, it is release via munmap().
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2358
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2359 3. If a returned chunk borders the current high end of memory,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2360 it is consolidated into the top, and if the total unused
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2361 topmost memory exceeds the trim threshold, malloc_trim is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2362 called.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2363
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2364 4. Other chunks are consolidated as they arrive, and
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2365 placed in corresponding bins. (This includes the case of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2366 consolidating with the current `last_remainder').
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2367
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2368 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2369
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2370
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2371 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2372 void fREe(Void_t* mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2373 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2374 void fREe(mem) Void_t* mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2375 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2376 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2377 mchunkptr p; /* chunk corresponding to mem */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2378 INTERNAL_SIZE_T hd; /* its head field */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2379 INTERNAL_SIZE_T sz; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2380 int idx; /* its bin index */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2381 mchunkptr next; /* next contiguous chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2382 INTERNAL_SIZE_T nextsz; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2383 INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2384 mchunkptr bck; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2385 mchunkptr fwd; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2386 int islr; /* track whether merging with last_remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2387
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2388 if (mem == 0) /* free(0) has no effect */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2389 return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2390
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2391 p = mem2chunk(mem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2392 hd = p->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2393
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2394 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2395 if (hd & IS_MMAPPED) /* release mmapped memory. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2396 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2397 munmap_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2398 return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2399 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2400 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2401
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2402 check_inuse_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2403
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2404 sz = hd & ~PREV_INUSE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2405 next = chunk_at_offset(p, sz);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2406 nextsz = chunksize(next);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2407
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2408 if (next == top) /* merge with top */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2409 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2410 sz += nextsz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2411
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2412 if (!(hd & PREV_INUSE)) /* consolidate backward */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2413 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2414 prevsz = p->prev_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2415 p = chunk_at_offset(p, -((long) prevsz));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2416 sz += prevsz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2417 unlink(p, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2418 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2419
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2420 set_head(p, sz | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2421 top = p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2422 if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2423 malloc_trim(top_pad);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2424 return;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2425 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2426
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2427 set_head(next, nextsz); /* clear inuse bit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2428
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2429 islr = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2430
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2431 if (!(hd & PREV_INUSE)) /* consolidate backward */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2432 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2433 prevsz = p->prev_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2434 p = chunk_at_offset(p, -((long) prevsz));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2435 sz += prevsz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2436
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2437 if (p->fd == last_remainder) /* keep as last_remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2438 islr = 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2439 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2440 unlink(p, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2441 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2442
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2443 if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2444 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2445 sz += nextsz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2446
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2447 if (!islr && next->fd == last_remainder) /* re-insert last_remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2448 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2449 islr = 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2450 link_last_remainder(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2451 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2452 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2453 unlink(next, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2454 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2455
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2456
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2457 set_head(p, sz | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2458 set_foot(p, sz);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2459 if (!islr)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2460 frontlink(p, sz, idx, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2461 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2462
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2463
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2464
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2465
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2466
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2467 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2468
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2469 Realloc algorithm:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2470
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2471 Chunks that were obtained via mmap cannot be extended or shrunk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2472 unless HAVE_MREMAP is defined, in which case mremap is used.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2473 Otherwise, if their reallocation is for additional space, they are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2474 copied. If for less, they are just left alone.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2475
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2476 Otherwise, if the reallocation is for additional space, and the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2477 chunk can be extended, it is, else a malloc-copy-free sequence is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2478 taken. There are several different ways that a chunk could be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2479 extended. All are tried:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2480
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2481 * Extending forward into following adjacent free chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2482 * Shifting backwards, joining preceding adjacent space
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2483 * Both shifting backwards and extending forward.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2484 * Extending into newly sbrked space
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2485
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2486 Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2487 size argument of zero (re)allocates a minimum-sized chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2488
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2489 If the reallocation is for less space, and the new request is for
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2490 a `small' (<512 bytes) size, then the newly unused space is lopped
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2491 off and freed.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2492
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2493 The old unix realloc convention of allowing the last-free'd chunk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2494 to be used as an argument to realloc is no longer supported.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2495 I don't know of any programs still relying on this feature,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2496 and allowing it would also allow too many other incorrect
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2497 usages of realloc to be sensible.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2498
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2499
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2500 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2501
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2502
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2503 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2504 Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2505 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2506 Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2507 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2508 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2509 INTERNAL_SIZE_T nb; /* padded request size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2510
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2511 mchunkptr oldp; /* chunk corresponding to oldmem */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2512 INTERNAL_SIZE_T oldsize; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2513
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2514 mchunkptr newp; /* chunk to return */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2515 INTERNAL_SIZE_T newsize; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2516 Void_t* newmem; /* corresponding user mem */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2517
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2518 mchunkptr next; /* next contiguous chunk after oldp */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2519 INTERNAL_SIZE_T nextsize; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2520
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2521 mchunkptr prev; /* previous contiguous chunk before oldp */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2522 INTERNAL_SIZE_T prevsize; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2523
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2524 mchunkptr remainder; /* holds split off extra space from newp */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2525 INTERNAL_SIZE_T remainder_size; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2526
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2527 mchunkptr bck; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2528 mchunkptr fwd; /* misc temp for linking */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2529
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2530 #ifdef REALLOC_ZERO_BYTES_FREES
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2531 if (bytes == 0) { fREe(oldmem); return 0; }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2532 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2533
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2534 if ((long)bytes < 0) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2535
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2536 /* realloc of null is supposed to be same as malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2537 if (oldmem == 0) return mALLOc(bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2538
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2539 newp = oldp = mem2chunk(oldmem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2540 newsize = oldsize = chunksize(oldp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2541
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2542
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2543 nb = request2size(bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2544
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2545 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2546 if (chunk_is_mmapped(oldp))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2547 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2548 #if HAVE_MREMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2549 newp = mremap_chunk(oldp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2550 if(newp) return chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2551 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2552 /* Note the extra SIZE_SZ overhead. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2553 if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2554 /* Must alloc, copy, free. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2555 newmem = mALLOc(bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2556 if (newmem == 0) return 0; /* propagate failure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2557 MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2558 munmap_chunk(oldp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2559 return newmem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2560 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2561 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2562
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2563 check_inuse_chunk(oldp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2564
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2565 if ((long)(oldsize) < (long)(nb))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2566 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2567
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2568 /* Try expanding forward */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2569
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2570 next = chunk_at_offset(oldp, oldsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2571 if (next == top || !inuse(next))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2572 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2573 nextsize = chunksize(next);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2574
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2575 /* Forward into top only if a remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2576 if (next == top)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2577 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2578 if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2579 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2580 newsize += nextsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2581 top = chunk_at_offset(oldp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2582 set_head(top, (newsize - nb) | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2583 set_head_size(oldp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2584 return chunk2mem(oldp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2585 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2586 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2587
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2588 /* Forward into next chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2589 else if (((long)(nextsize + newsize) >= (long)(nb)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2590 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2591 unlink(next, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2592 newsize += nextsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2593 goto split;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2594 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2595 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2596 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2597 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2598 next = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2599 nextsize = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2600 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2601
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2602 /* Try shifting backwards. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2603
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2604 if (!prev_inuse(oldp))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2605 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2606 prev = prev_chunk(oldp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2607 prevsize = chunksize(prev);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2608
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2609 /* try forward + backward first to save a later consolidation */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2610
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2611 if (next != 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2612 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2613 /* into top */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2614 if (next == top)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2615 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2616 if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2617 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2618 unlink(prev, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2619 newp = prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2620 newsize += prevsize + nextsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2621 newmem = chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2622 MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2623 top = chunk_at_offset(newp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2624 set_head(top, (newsize - nb) | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2625 set_head_size(newp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2626 return newmem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2627 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2628 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2629
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2630 /* into next chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2631 else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2632 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2633 unlink(next, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2634 unlink(prev, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2635 newp = prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2636 newsize += nextsize + prevsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2637 newmem = chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2638 MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2639 goto split;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2640 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2641 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2642
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2643 /* backward only */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2644 if (prev != 0 && (long)(prevsize + newsize) >= (long)nb)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2645 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2646 unlink(prev, bck, fwd);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2647 newp = prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2648 newsize += prevsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2649 newmem = chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2650 MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2651 goto split;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2652 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2653 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2654
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2655 /* Must allocate */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2656
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2657 newmem = mALLOc (bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2658
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2659 if (newmem == 0) /* propagate failure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2660 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2661
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2662 /* Avoid copy if newp is next chunk after oldp. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2663 /* (This can only happen when new chunk is sbrk'ed.) */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2664
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2665 if ( (newp = mem2chunk(newmem)) == next_chunk(oldp))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2666 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2667 newsize += chunksize(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2668 newp = oldp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2669 goto split;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2670 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2671
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2672 /* Otherwise copy, free, and exit */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2673 MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2674 fREe(oldmem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2675 return newmem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2676 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2677
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2678
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2679 split: /* split off extra room in old or expanded chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2680
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2681 if (newsize - nb >= MINSIZE) /* split off remainder */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2682 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2683 remainder = chunk_at_offset(newp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2684 remainder_size = newsize - nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2685 set_head_size(newp, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2686 set_head(remainder, remainder_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2687 set_inuse_bit_at_offset(remainder, remainder_size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2688 fREe(chunk2mem(remainder)); /* let free() deal with it */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2689 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2690 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2691 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2692 set_head_size(newp, newsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2693 set_inuse_bit_at_offset(newp, newsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2694 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2695
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2696 check_inuse_chunk(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2697 return chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2698 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2699
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2700
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2701
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2702
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2703 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2704
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2705 memalign algorithm:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2706
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2707 memalign requests more than enough space from malloc, finds a spot
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2708 within that chunk that meets the alignment request, and then
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2709 possibly frees the leading and trailing space.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2710
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2711 The alignment argument must be a power of two. This property is not
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2712 checked by memalign, so misuse may result in random runtime errors.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2713
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2714 8-byte alignment is guaranteed by normal malloc calls, so don't
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2715 bother calling memalign with an argument of 8 or less.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2716
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2717 Overreliance on memalign is a sure way to fragment space.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2718
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2719 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2720
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2721
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2722 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2723 Void_t* mEMALIGn(size_t alignment, size_t bytes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2724 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2725 Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2726 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2727 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2728 INTERNAL_SIZE_T nb; /* padded request size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2729 char* m; /* memory returned by malloc call */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2730 mchunkptr p; /* corresponding chunk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2731 char* brk; /* alignment point within p */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2732 mchunkptr newp; /* chunk to return */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2733 INTERNAL_SIZE_T newsize; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2734 INTERNAL_SIZE_T leadsize; /* leading space befor alignment point */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2735 mchunkptr remainder; /* spare room at end to split off */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2736 long remainder_size; /* its size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2737
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2738 if ((long)bytes < 0) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2739
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2740 /* If need less alignment than we give anyway, just relay to malloc */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2741
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2742 if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2743
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2744 /* Otherwise, ensure that it is at least a minimum chunk size */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2745
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2746 if (alignment < MINSIZE) alignment = MINSIZE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2747
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2748 /* Call malloc with worst case padding to hit alignment. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2749
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2750 nb = request2size(bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2751 m = (char*)(mALLOc(nb + alignment + MINSIZE));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2752
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2753 if (m == 0) return 0; /* propagate failure */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2754
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2755 p = mem2chunk(m);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2756
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2757 if ((((unsigned long)(m)) % alignment) == 0) /* aligned */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2758 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2759 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2760 if(chunk_is_mmapped(p))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2761 return chunk2mem(p); /* nothing more to do */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2762 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2763 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2764 else /* misaligned */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2765 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2766 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2767 Find an aligned spot inside chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2768 Since we need to give back leading space in a chunk of at
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2769 least MINSIZE, if the first calculation places us at
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2770 a spot with less than MINSIZE leader, we can move to the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2771 next aligned spot -- we've allocated enough total room so that
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2772 this is always possible.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2773 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2774
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2775 brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & -((signed) alignment));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2776 if ((long)(brk - (char*)(p)) < MINSIZE) brk = brk + alignment;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2777
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2778 newp = (mchunkptr)brk;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2779 leadsize = brk - (char*)(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2780 newsize = chunksize(p) - leadsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2781
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2782 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2783 if(chunk_is_mmapped(p))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2784 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2785 newp->prev_size = p->prev_size + leadsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2786 set_head(newp, newsize|IS_MMAPPED);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2787 return chunk2mem(newp);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2788 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2789 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2790
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2791 /* give back leader, use the rest */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2792
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2793 set_head(newp, newsize | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2794 set_inuse_bit_at_offset(newp, newsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2795 set_head_size(p, leadsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2796 fREe(chunk2mem(p));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2797 p = newp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2798
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2799 assert (newsize >= nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2800 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2801
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2802 /* Also give back spare room at the end */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2803
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2804 remainder_size = chunksize(p) - nb;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2805
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2806 if (remainder_size >= (long)MINSIZE)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2807 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2808 remainder = chunk_at_offset(p, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2809 set_head(remainder, remainder_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2810 set_head_size(p, nb);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2811 fREe(chunk2mem(remainder));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2812 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2813
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2814 check_inuse_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2815 return chunk2mem(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2816
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2817 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2818
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2819
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2820
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2821
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2822 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2823 valloc just invokes memalign with alignment argument equal
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2824 to the page size of the system (or as near to this as can
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2825 be figured out from all the includes/defines above.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2826 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2827
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2828 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2829 Void_t* vALLOc(size_t bytes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2830 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2831 Void_t* vALLOc(bytes) size_t bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2832 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2833 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2834 return mEMALIGn (malloc_getpagesize, bytes);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2835 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2836
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2837 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2838 pvalloc just invokes valloc for the nearest pagesize
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2839 that will accommodate request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2840 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2841
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2842
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2843 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2844 Void_t* pvALLOc(size_t bytes)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2845 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2846 Void_t* pvALLOc(bytes) size_t bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2847 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2848 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2849 size_t pagesize = malloc_getpagesize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2850 return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2851 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2852
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2853 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2854
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2855 calloc calls malloc, then zeroes out the allocated chunk.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2856
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2857 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2858
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2859 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2860 Void_t* cALLOc(size_t n, size_t elem_size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2861 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2862 Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2863 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2864 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2865 mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2866 INTERNAL_SIZE_T csz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2867
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2868 INTERNAL_SIZE_T sz = n * elem_size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2869
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2870
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2871 /* check if expand_top called, in which case don't need to clear */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2872 #if MORECORE_CLEARS
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2873 mchunkptr oldtop = top;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2874 INTERNAL_SIZE_T oldtopsize = chunksize(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2875 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2876 Void_t* mem = mALLOc (sz);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2877
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2878 if ((long)n < 0) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2879
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2880 if (mem == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2881 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2882 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2883 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2884 p = mem2chunk(mem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2885
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2886 /* Two optional cases in which clearing not necessary */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2887
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2888
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2889 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2890 if (chunk_is_mmapped(p)) return mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2891 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2892
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2893 csz = chunksize(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2894
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2895 #if MORECORE_CLEARS
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2896 if (p == oldtop && csz > oldtopsize)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2897 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2898 /* clear only the bytes from non-freshly-sbrked memory */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2899 csz = oldtopsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2900 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2901 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2902
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2903 MALLOC_ZERO(mem, csz - SIZE_SZ);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2904 return mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2905 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2906 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2907
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2908 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2909
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2910 cfree just calls free. It is needed/defined on some systems
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2911 that pair it with calloc, presumably for odd historical reasons.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2912
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2913 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2914
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2915 #if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2916 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2917 void cfree(Void_t *mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2918 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2919 void cfree(mem) Void_t *mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2920 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2921 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2922 fREe(mem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2923 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2924 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2925
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2926
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2927
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2928 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2929
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2930 Malloc_trim gives memory back to the system (via negative
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2931 arguments to sbrk) if there is unused memory at the `high' end of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2932 the malloc pool. You can call this after freeing large blocks of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2933 memory to potentially reduce the system-level memory requirements
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2934 of a program. However, it cannot guarantee to reduce memory. Under
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2935 some allocation patterns, some large free blocks of memory will be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2936 locked between two used chunks, so they cannot be given back to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2937 the system.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2938
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2939 The `pad' argument to malloc_trim represents the amount of free
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2940 trailing space to leave untrimmed. If this argument is zero,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2941 only the minimum amount of memory to maintain internal data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2942 structures will be left (one page or less). Non-zero arguments
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2943 can be supplied to maintain enough trailing space to service
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2944 future expected allocations without having to re-obtain memory
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2945 from the system.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2946
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2947 Malloc_trim returns 1 if it actually released any memory, else 0.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2948
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2949 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2950
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2951 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2952 int malloc_trim(size_t pad)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2953 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2954 int malloc_trim(pad) size_t pad;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2955 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2956 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2957 long top_size; /* Amount of top-most memory */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2958 long extra; /* Amount to release */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2959 char* current_brk; /* address returned by pre-check sbrk call */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2960 char* new_brk; /* address returned by negative sbrk call */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2961
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2962 unsigned long pagesz = malloc_getpagesize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2963
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2964 top_size = chunksize(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2965 extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2966
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2967 if (extra < (long)pagesz) /* Not enough memory to release */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2968 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2969
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2970 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2971 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2972 /* Test to make sure no one else called sbrk */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2973 current_brk = (char*)(MORECORE (0));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2974 if (current_brk != (char*)(top) + top_size)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2975 return 0; /* Apparently we don't own memory; must fail */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2976
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2977 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2978 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2979 new_brk = (char*)(MORECORE (-extra));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2980
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2981 if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2982 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2983 /* Try to figure out what we have */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2984 current_brk = (char*)(MORECORE (0));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2985 top_size = current_brk - (char*)top;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2986 if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2987 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2988 sbrked_mem = current_brk - sbrk_base;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2989 set_head(top, top_size | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2990 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2991 check_chunk(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2992 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2993 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2994
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2995 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2996 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2997 /* Success. Adjust top accordingly. */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2998 set_head(top, (top_size - extra) | PREV_INUSE);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2999 sbrked_mem -= extra;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3000 check_chunk(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3001 return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3002 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3003 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3004 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3005 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3006
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3007
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3008
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3009 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3010 malloc_usable_size:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3011
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3012 This routine tells you how many bytes you can actually use in an
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3013 allocated chunk, which may be more than you requested (although
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3014 often not). You can use this many bytes without worrying about
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3015 overwriting other allocated objects. Not a particularly great
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3016 programming practice, but still sometimes useful.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3017
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3018 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3019
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3020 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3021 size_t malloc_usable_size(Void_t* mem)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3022 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3023 size_t malloc_usable_size(mem) Void_t* mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3024 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3025 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3026 mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3027 if (mem == 0)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3028 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3029 else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3030 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3031 p = mem2chunk(mem);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3032 if(!chunk_is_mmapped(p))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3033 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3034 if (!inuse(p)) return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3035 check_inuse_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3036 return chunksize(p) - SIZE_SZ;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3037 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3038 return chunksize(p) - 2*SIZE_SZ;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3039 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3040 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3041
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3042
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3043
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3044
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3045 /* Utility to update current_mallinfo for malloc_stats and mallinfo() */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3046
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3047 static void malloc_update_mallinfo()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3048 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3049 int i;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3050 mbinptr b;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3051 mchunkptr p;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3052 #if DEBUG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3053 mchunkptr q;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3054 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3055
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3056 INTERNAL_SIZE_T avail = chunksize(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3057 int navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3058
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3059 for (i = 1; i < NAV; ++i)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3060 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3061 b = bin_at(i);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3062 for (p = last(b); p != b; p = p->bk)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3063 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3064 #if DEBUG
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3065 check_free_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3066 for (q = next_chunk(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3067 q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3068 q = next_chunk(q))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3069 check_inuse_chunk(q);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3070 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3071 avail += chunksize(p);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3072 navail++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3073 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3074 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3075
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3076 current_mallinfo.ordblks = navail;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3077 current_mallinfo.uordblks = sbrked_mem - avail;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3078 current_mallinfo.fordblks = avail;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3079 current_mallinfo.hblks = n_mmaps;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3080 current_mallinfo.hblkhd = mmapped_mem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3081 current_mallinfo.keepcost = chunksize(top);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3082
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3083 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3084
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3085
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3086
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3087 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3088
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3089 malloc_stats:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3090
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3091 Prints on stderr the amount of space obtain from the system (both
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3092 via sbrk and mmap), the maximum amount (which may be more than
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3093 current if malloc_trim and/or munmap got called), the maximum
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3094 number of simultaneous mmap regions used, and the current number
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3095 of bytes allocated via malloc (or realloc, etc) but not yet
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3096 freed. (Note that this is the number of bytes allocated, not the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3097 number requested. It will be larger than the number requested
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3098 because of alignment and bookkeeping overhead.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3099
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3100 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3101
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3102 void malloc_stats()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3103 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3104 malloc_update_mallinfo();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3105 fprintf(stderr, "max system bytes = %10u\n",
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3106 (unsigned int)(max_total_mem));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3107 fprintf(stderr, "system bytes = %10u\n",
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3108 (unsigned int)(sbrked_mem + mmapped_mem));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3109 fprintf(stderr, "in use bytes = %10u\n",
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3110 (unsigned int)(current_mallinfo.uordblks + mmapped_mem));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3111 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3112 fprintf(stderr, "max mmap regions = %10u\n",
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3113 (unsigned int)max_n_mmaps);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3114 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3115 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3116
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3117 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3118 mallinfo returns a copy of updated current mallinfo.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3119 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3120
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3121 struct mallinfo mALLINFo()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3122 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3123 malloc_update_mallinfo();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3124 return current_mallinfo;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3125 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3126
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3127
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3128
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3129
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3130 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3131 mallopt:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3132
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3133 mallopt is the general SVID/XPG interface to tunable parameters.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3134 The format is to provide a (parameter-number, parameter-value) pair.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3135 mallopt then sets the corresponding parameter to the argument
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3136 value if it can (i.e., so long as the value is meaningful),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3137 and returns 1 if successful else 0.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3138
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3139 See descriptions of tunable parameters above.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3140
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3141 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3142
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3143 #if __STD_C
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3144 int mALLOPt(int param_number, int value)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3145 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3146 int mALLOPt(param_number, value) int param_number; int value;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3147 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3148 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3149 switch(param_number)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3150 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3151 case M_TRIM_THRESHOLD:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3152 trim_threshold = value; return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3153 case M_TOP_PAD:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3154 top_pad = value; return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3155 case M_MMAP_THRESHOLD:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3156 mmap_threshold = value; return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3157 case M_MMAP_MAX:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3158 #if HAVE_MMAP
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3159 n_mmaps_max = value; return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3160 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3161 if (value != 0) return 0; else n_mmaps_max = value; return 1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3162 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3163
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3164 default:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3165 return 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3166 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3167 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3168
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3169 /*
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3170
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3171 History:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3172
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3173 V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3174 * return null for negative arguments
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3175 * Added Several WIN32 cleanups from Martin C. Fong <mcfong@yahoo.com>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3176 * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3177 (e.g. WIN32 platforms)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3178 * Cleanup up header file inclusion for WIN32 platforms
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3179 * Cleanup code to avoid Microsoft Visual C++ compiler complaints
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3180 * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3181 memory allocation routines
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3182 * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3183 * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3184 usage of 'assert' in non-WIN32 code
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3185 * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3186 avoid infinite loop
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3187 * Always call 'fREe()' rather than 'free()'
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3188
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3189 V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3190 * Fixed ordering problem with boundary-stamping
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3191
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3192 V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3193 * Added pvalloc, as recommended by H.J. Liu
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3194 * Added 64bit pointer support mainly from Wolfram Gloger
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3195 * Added anonymously donated WIN32 sbrk emulation
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3196 * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3197 * malloc_extend_top: fix mask error that caused wastage after
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3198 foreign sbrks
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3199 * Add linux mremap support code from HJ Liu
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3200
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3201 V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3202 * Integrated most documentation with the code.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3203 * Add support for mmap, with help from
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3204 Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3205 * Use last_remainder in more cases.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3206 * Pack bins using idea from colin@nyx10.cs.du.edu
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3207 * Use ordered bins instead of best-fit threshhold
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3208 * Eliminate block-local decls to simplify tracing and debugging.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3209 * Support another case of realloc via move into top
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3210 * Fix error occuring when initial sbrk_base not word-aligned.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3211 * Rely on page size for units instead of SBRK_UNIT to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3212 avoid surprises about sbrk alignment conventions.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3213 * Add mallinfo, mallopt. Thanks to Raymond Nijssen
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3214 (raymond@es.ele.tue.nl) for the suggestion.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3215 * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3216 * More precautions for cases where other routines call sbrk,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3217 courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3218 * Added macros etc., allowing use in linux libc from
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3219 H.J. Lu (hjl@gnu.ai.mit.edu)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3220 * Inverted this history list
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3221
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3222 V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3223 * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3224 * Removed all preallocation code since under current scheme
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3225 the work required to undo bad preallocations exceeds
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3226 the work saved in good cases for most test programs.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3227 * No longer use return list or unconsolidated bins since
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3228 no scheme using them consistently outperforms those that don't
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3229 given above changes.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3230 * Use best fit for very large chunks to prevent some worst-cases.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3231 * Added some support for debugging
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3232
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3233 V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3234 * Removed footers when chunks are in use. Thanks to
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3235 Paul Wilson (wilson@cs.texas.edu) for the suggestion.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3236
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3237 V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3238 * Added malloc_trim, with help from Wolfram Gloger
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3239 (wmglo@Dent.MED.Uni-Muenchen.DE).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3240
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3241 V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3242
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3243 V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3244 * realloc: try to expand in both directions
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3245 * malloc: swap order of clean-bin strategy;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3246 * realloc: only conditionally expand backwards
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3247 * Try not to scavenge used bins
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3248 * Use bin counts as a guide to preallocation
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3249 * Occasionally bin return list chunks in first scan
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3250 * Add a few optimizations from colin@nyx10.cs.du.edu
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3251
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3252 V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3253 * faster bin computation & slightly different binning
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3254 * merged all consolidations to one part of malloc proper
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3255 (eliminating old malloc_find_space & malloc_clean_bin)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3256 * Scan 2 returns chunks (not just 1)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3257 * Propagate failure in realloc if malloc returns 0
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3258 * Add stuff to allow compilation on non-ANSI compilers
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3259 from kpv@research.att.com
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3260
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3261 V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3262 * removed potential for odd address access in prev_chunk
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3263 * removed dependency on getpagesize.h
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3264 * misc cosmetics and a bit more internal documentation
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3265 * anticosmetics: mangled names in macros to evade debugger strangeness
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3266 * tested on sparc, hp-700, dec-mips, rs6000
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3267 with gcc & native cc (hp, dec only) allowing
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3268 Detlefs & Zorn comparison study (in SIGPLAN Notices.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3269
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3270 Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3271 * Based loosely on libg++-1.2X malloc. (It retains some of the overall
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3272 structure of old version, but most details differ.)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3273
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3274 */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3275
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3276