|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13:
14: #include "stddef.h"
15: #include "stdlib.h"
16: #include "unistd.h"
17: #include "malloc_defs.h"
18:
19:
20: static int clean(void);
21:
22:
23: /* act points to the end of the initialized heap and the start of uninitialized heap */
24: static char *act;
25:
26: /* Pointers to start and end of heap: */
27: static char *heap_start, *heap_end;
28:
29:
30: /*
31: * Standard malloc function
32: */
33: void *
34: malloc(size_t size)
35: {
36: char *header;
37: void *data;
38: size_t blksize; /* size of memory block including the chunk */
39:
40: blksize = size + sizeof(struct chunk);
41:
42: /* has malloc been called for the first time? */
43: if (act == 0) {
44: size_t initsize;
45: /* add some space so we have a good initial playground */
46: initsize = (blksize + 0x1000) & ~0x0fff;
47: /* get initial memory region with sbrk() */
48: heap_start = sbrk(initsize);
49: if (heap_start == (void*)-1)
50: return NULL;
51: heap_end = heap_start + initsize;
52: act = heap_start;
53: }
54:
55: header = act;
56: data = act + sizeof(struct chunk);
57:
58: /* Check if there is space left in the uninitialized part of the heap */
59: if (act + blksize > heap_end) {
60: //search at begin of heap
61: header = heap_start;
62:
63: while ((((struct chunk *) header)->inuse != 0
64: || ((struct chunk *) header)->length < size)
65: && header < act) {
66: header = header + sizeof(struct chunk)
67: + ((struct chunk *) header)->length;
68: }
69:
70: // check if heap is full
71: if (header >= act) {
72: if (clean()) {
73: // merging of free blocks succeeded, so try again
74: return malloc(size);
75: } else if (sbrk(blksize) == heap_end) {
76: // succeeded to get more memory, so try again
77: heap_end += blksize;
78: return malloc(size);
79: } else {
80: // No more memory available
81: return 0;
82: }
83: }
84:
85: // Check if we need to split this memory block into two
86: if (((struct chunk *) header)->length > blksize) {
87: //available memory is too big
88: int alt;
89:
90: alt = ((struct chunk *) header)->length;
91: ((struct chunk *) header)->inuse = 1;
92: ((struct chunk *) header)->length = size;
93: data = header + sizeof(struct chunk);
94:
95: //mark the rest of the heap
96: header = data + size;
97: ((struct chunk *) header)->inuse = 0;
98: ((struct chunk *) header)->length =
99: alt - blksize;
100: } else {
101: //new memory matched exactly in available memory
102: ((struct chunk *) header)->inuse = 1;
103: data = header + sizeof(struct chunk);
104: }
105:
106: } else {
107:
108: ((struct chunk *) header)->inuse = 1;
109: ((struct chunk *) header)->length = size;
110:
111: act += blksize;
112: }
113:
114: return data;
115: }
116:
117:
118: /*
119: * Merge free memory blocks in initialized heap if possible
120: */
121: static int
122: clean(void)
123: {
124: char *header;
125: char *firstfree = 0;
126: char check = 0;
127:
128: header = heap_start;
129: //if (act == 0) // This should never happen
130: // act = heap_end;
131:
132: while (header < act) {
133:
134: if (((struct chunk *) header)->inuse == 0) {
135: if (firstfree == 0) {
136: /* First free block in a row, only save address */
137: firstfree = header;
138:
139: } else {
140: /* more than one free block in a row, merge them! */
141: ((struct chunk *) firstfree)->length +=
142: ((struct chunk *) header)->length +
143: sizeof(struct chunk);
144: check = 1;
145: }
146: } else {
147: firstfree = 0;
148:
149: }
150:
151: header = header + sizeof(struct chunk)
152: + ((struct chunk *) header)->length;
153:
154: }
155:
156: return check;
157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.