Skip to content

Commit 8e401f1

Browse files
author
whitequark
committedJan 10, 2016
Add liballoc.
1 parent 2957ecf commit 8e401f1

File tree

6 files changed

+176
-2
lines changed

6 files changed

+176
-2
lines changed
 

Diff for: ‎misoc/integration/builder.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
# in build order (for dependencies)
1313
misoc_software_packages = [
14-
"libbase",
1514
"libcompiler_rt",
15+
"libbase",
16+
"liballoc",
1617
"libdyld",
17-
"libnet",
1818
"libunwind",
19+
"libnet",
1920
"bios"
2021
]
2122

Diff for: ‎misoc/software/include/base/inttypes.h

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#ifndef __INTTYPES_H
2323
#define __INTTYPES_H
2424

25+
#include <stdint.h>
26+
2527
# if __WORDSIZE == 64
2628
# define __PRI64_PREFIX "l"
2729
# define __PRIPTR_PREFIX "l"

Diff for: ‎misoc/software/include/base/stdlib.h

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, con
7474
char *getenv(const char *name);
7575

7676
void *malloc(size_t size);
77+
void *calloc(size_t nmemb, size_t size);
7778
void free(void *ptr);
7879
void *realloc(void *ptr, size_t size);
7980

Diff for: ‎misoc/software/liballoc/Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
include ../include/generated/variables.mak
2+
include $(MISOC_DIRECTORY)/software/common.mak
3+
4+
OBJECTS=alloc.o
5+
6+
all: liballoc.a
7+
8+
liballoc.a: $(OBJECTS)
9+
$(AR) crs liballoc.a $(OBJECTS)
10+
11+
%.o: $(LIBALLOC_DIRECTORY)/%.c
12+
$(compile)
13+
14+
%.o: %.S
15+
$(assemble)
16+
17+
.PHONY: all clean
18+
19+
clean:
20+
$(RM) $(OBJECTS) liballoc.a .*~ *~

Diff for: ‎misoc/software/liballoc/alloc.c

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <inttypes.h>
5+
#include "alloc.h"
6+
7+
struct meta {
8+
uintptr_t magi;
9+
size_t size;
10+
struct meta *next;
11+
};
12+
13+
#define LIST(x) ((struct meta *)(x) - 1)
14+
#define DATA(x) ((uintptr_t)((struct meta*)(x) + 1))
15+
#define BUSY ((uintptr_t)0xFEEDFEEDFEEDFEEDU)
16+
#define IDLE ((uintptr_t)0xDEADDEADDEADDEADU)
17+
#define FILL sizeof(struct meta) /* no free fragments smaller than this */
18+
19+
static struct meta *root;
20+
21+
void *malloc(size_t size)
22+
{
23+
size += FILL - (size % FILL); /* round up */
24+
25+
for(struct meta *list = root; list; list = list->next) {
26+
if(list->magi == BUSY) {
27+
continue;
28+
} else if(list->magi == IDLE) {
29+
while(list->next && list->next->magi == IDLE) {
30+
/* Join */
31+
list->size += list->next->size + sizeof(struct meta);
32+
list->next->magi = 0;
33+
list->next = list->next->next;
34+
}
35+
36+
if(list->size < size)
37+
continue;
38+
39+
if(list->size > size + sizeof(struct meta) + FILL) {
40+
/* Fork */
41+
struct meta *newl = (struct meta*)(DATA(list) + size);
42+
newl->magi = IDLE;
43+
newl->size = list->size - size - sizeof(struct meta);
44+
newl->next = list->next;
45+
list->next = newl;
46+
list->size = size;
47+
}
48+
list->magi = BUSY;
49+
return (void*)DATA(list);
50+
} else {
51+
printf("malloc(): heap corruption detected at 0x%"PRIxPTR"\n", list);
52+
abort();
53+
}
54+
}
55+
56+
return NULL;
57+
}
58+
59+
void *calloc(size_t numb, size_t size)
60+
{
61+
size_t objs = numb * size;
62+
63+
/* Overflow check */
64+
#define HALF_SIZE_T (((size_t) 1) << (8 * sizeof(size_t) / 2))
65+
if(__builtin_expect((numb | size) >= HALF_SIZE_T, 0))
66+
if(size != 0 && objs / size != numb)
67+
return NULL;
68+
69+
void *objp = malloc(objs);
70+
if(objp)
71+
memset(objp, 0, objs);
72+
73+
return objp;
74+
}
75+
76+
void *realloc(void *oldp, size_t size)
77+
{
78+
void *newp = malloc(size);
79+
80+
if(oldp && newp) {
81+
size_t olds;
82+
if(size > LIST(oldp)->size)
83+
olds = LIST(oldp)->size;
84+
else
85+
olds = size;
86+
87+
memcpy(newp, oldp, olds);
88+
free(oldp);
89+
}
90+
91+
return newp;
92+
}
93+
94+
void free(void *objp)
95+
{
96+
if(objp == NULL)
97+
return;
98+
99+
struct meta *list = LIST(objp);
100+
if(list->magi != BUSY) {
101+
printf("free(): heap corruption detected at 0x%"PRIxPTR"\n", list);
102+
abort();
103+
}
104+
list->magi = IDLE;
105+
}
106+
107+
void alloc_give(void *area, size_t size)
108+
{
109+
if(size < sizeof(struct meta) + FILL)
110+
return;
111+
112+
struct meta *list = (struct meta *)area;
113+
list->magi = IDLE;
114+
list->size = size - sizeof(struct meta);
115+
list->next = root;
116+
root = list;
117+
}
118+
119+
void alloc_show()
120+
{
121+
size_t busy = 0, idle = 0, meta = 0;
122+
123+
printf("Heap view:\n");
124+
125+
for(struct meta *list = root; list; list = list->next) {
126+
meta += sizeof(struct meta);
127+
128+
const char *magi;
129+
switch(list->magi) {
130+
case IDLE: magi = "IDLE"; idle += list->size; break;
131+
case BUSY: magi = "BUSY"; busy += list->size; break;
132+
default: magi = "!!!!";
133+
}
134+
135+
printf("%s 0x%"PRIxPTR" + 0x%zx -> 0x%"PRIxPTR"\n",
136+
magi, (uintptr_t)list, list->size, list->next);
137+
if(list->magi != BUSY && list->magi != IDLE)
138+
return;
139+
}
140+
141+
printf(" === busy: 0x%zx idle: 0x%zx meta: 0x%zx full: 0x%zx\n",
142+
busy, idle, meta, busy + idle + meta);
143+
}

Diff for: ‎misoc/software/liballoc/alloc.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef _ALLOC_H
2+
#define _ALLOC_H
3+
4+
void alloc_give(void *addr, size_t size);
5+
void alloc_show(void);
6+
7+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.