• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

コミットメタ情報

リビジョン1ff29edccbb42f603859abb6eda22265df896a4f (tree)
日時2000-06-16 03:01:08
作者Ron Alder <alder@line...>
コミッターRon Alder

ログメッセージ

Implimented a simple allocation system that does not waste memory.
Added realloc. The allocation system was needed to support realloc.

変更サマリ

差分

--- a/libc/stdlib/malloc/alloc.c
+++ b/libc/stdlib/malloc/alloc.c
@@ -3,6 +3,28 @@
33 #include <stdio.h>
44 #include <stdlib.h>
55
6+struct chunkControl {
7+ size_t nodeCount;
8+ size_t chunkSize;
9+};
10+
11+struct nodeControl {
12+ struct chunkControl *chunk;
13+ size_t nodeSize;
14+};
15+
16+#define ROUND_UP_LENGTH(len) ((len+7) & ~0x07)
17+
18+extern struct nodeControl *mallocNextNode;
19+
20+#ifdef L_malloc
21+/* This variable is a pointer to the next place to allocate from.
22+ * Note: This variable makes the code NOT thread save. */
23+struct nodeControl *mallocNextNode = 0;
24+static size_t PageSize = 0;
25+
26+#endif
27+
628 #ifdef L_calloc_dbg
729
830 void *
@@ -61,12 +83,64 @@ calloc(size_t num, size_t size)
6183 void *
6284 malloc(size_t len)
6385 {
64- void * result = mmap((void *)0, len, PROT_READ | PROT_WRITE,
65- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
66- if (result == (void*)-1)
67- return 0;
68-
69- return result;
86+ void *result;
87+ struct chunkControl *chunk;
88+ struct nodeControl *next;
89+ size_t size;
90+
91+ /* round len up to keep things on even boundaries */
92+ len = ROUND_UP_LENGTH(len);
93+
94+ if (len == 0)
95+ return 0;
96+
97+TryAgain:
98+ if (mallocNextNode != 0) {
99+ /* first see if this request will fit on this chunk */
100+ next = mallocNextNode;
101+ chunk = next->chunk;
102+ if (((char *)next + sizeof(struct nodeControl)*2 + len) <
103+ ((char *)chunk + chunk->chunkSize))
104+ {
105+ /* this request will fit, so simply move the next
106+ * pointer ahead and update chunk node count */
107+ next->nodeSize = len;
108+ result = (char *)next + sizeof(struct nodeControl);
109+ chunk->nodeCount++;
110+ next = (struct nodeControl *)
111+ ((char *)next + (sizeof(struct nodeControl) + len));
112+ next->chunk = chunk;
113+ next->nodeSize = 0;
114+ mallocNextNode = next;
115+
116+ return result; /* normal return path */
117+ }
118+
119+ }
120+
121+ /* the request will not fit on this chunk, so get another chunk */
122+ if (PageSize == 0) {
123+ PageSize = getpagesize();
124+ }
125+ size = len + (sizeof(struct chunkControl) + (sizeof(struct nodeControl) * 2));
126+ if (size < PageSize * 2) {
127+ size = PageSize * 2;
128+ }
129+ size = (size + (PageSize-1)) & ~(PageSize-1);
130+
131+ chunk = mmap((void *)0, size, PROT_READ | PROT_WRITE,
132+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
133+ if (chunk == (void*)-1)
134+ return 0;
135+
136+ chunk->chunkSize = size;
137+ chunk->nodeCount = 0;
138+ next = (struct nodeControl *)
139+ ((char *)chunk + sizeof(struct chunkControl));
140+ next->chunk = chunk;
141+ mallocNextNode = next;
142+
143+ goto TryAgain;
70144 }
71145
72146 #endif
@@ -76,7 +150,58 @@ malloc(size_t len)
76150 void
77151 free(void * ptr)
78152 {
79- munmap(ptr, 0);
153+ struct chunkControl *chunk;
154+ struct nodeControl *node;
155+
156+ if (ptr == 0) {
157+ return;
158+ }
159+ /* get a pointer to the control information for this memory node
160+ * and the chunk it belongs to */
161+ node = (struct nodeControl *)ptr - 1;
162+ chunk = node->chunk;
163+ /* decrement the node count and if it is zero free the chunk */
164+ chunk->nodeCount--;
165+ if (chunk->nodeCount == 0) {
166+ if ((void *)mallocNextNode >= (void *)chunk &&
167+ ((void *)mallocNextNode < (void *)((char *)chunk + chunk->chunkSize)))
168+ {
169+ mallocNextNode = 0;
170+ }
171+ munmap(chunk, chunk->chunkSize);
172+ }
80173 }
81174
82175 #endif
176+
177+#ifdef L_realloc
178+
179+void *
180+realloc(void *ptr, size_t len)
181+{
182+ struct nodeControl *node;
183+ size_t oldSize;
184+ void *new;
185+
186+
187+ if (ptr == 0) {
188+ return malloc(len);
189+ }
190+ if (len == 0) {
191+ free(ptr);
192+ return 0;
193+ }
194+ node = (struct nodeControl *)ptr - 1;
195+ oldSize = node->nodeSize;
196+ if (oldSize >= len) {
197+ return ptr;
198+ }
199+
200+ new = malloc(len);
201+ memcpy(new, ptr, len);
202+ free(ptr);
203+ return new;
204+}
205+
206+#endif
207+