File: malloc.c

package info (click to toggle)
gbdk 2.0.17-3
  • links: PTS
  • area: non-free
  • in suites: potato
  • size: 8,472 kB
  • ctags: 9,307
  • sloc: ansic: 42,333; asm: 7,010; makefile: 912; yacc: 375; awk: 154; csh: 144; sh: 59
file content (111 lines) | stat: -rw-r--r-- 2,627 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <sys/malloc.h>
#include <stdio.h>

pmmalloc_hunk malloc_first;

void debug( char *fun, char *msg )
{
/*	return; */
/*	printf("%s: %s\n", fun, msg );*/
}

BYTE malloc_init(void)
{
	if (malloc_first->magic!=MALLOC_MAGIC) {
		/* Init by setting up the first hunk */

		debug("malloc_init", "Setting up");
		malloc_first = (pmmalloc_hunk)&malloc_heap_start;

		malloc_first->next = NULL;
		malloc_first->size = 0xDFFFU - 0x200 - sizeof(mmalloc_hunk) - (UWORD)&malloc_heap_start;
		malloc_first->status = MALLOC_FREE;

		malloc_first->magic = MALLOC_MAGIC;
		return 0;
	}
	return -1;
}

void malloc_gc(void)
{
	/* Do a garbage collect on the hunks to create bigger hunks */
	/* Note: assumes that hunks are consecutive */

	pmmalloc_hunk thisHunk, nextHunk;
	UBYTE changed;

	changed = 1;

	debug("malloc_gc","Running");
	while (changed) {
		thisHunk = malloc_first;
		changed = 0;
		while (thisHunk && (thisHunk->magic==MALLOC_MAGIC)) {
			if (thisHunk->status == MALLOC_FREE) {
				nextHunk = thisHunk->next;
				if (nextHunk->status == MALLOC_FREE) {
					/* Must be consecutive */
					changed = 1;
					thisHunk->size+=nextHunk->size+sizeof(mmalloc_hunk);
					thisHunk->next = nextHunk->next;
				}
			}
			thisHunk=thisHunk->next;
		}
		if (thisHunk!=NULL)
			debug("malloc_gc", "Corrupted malloc list found.");
	}
}
		
void *malloc( UWORD size )
{
	pmmalloc_hunk thisHunk, insertBefore;
	pmmalloc_hunk newHunk;
	UBYTE firstTry;

	if (malloc_first->magic != MALLOC_MAGIC)
		malloc_init();

	firstTry = 1;	/* Allows gc if no big enough hunk is found */
	
	while (firstTry) {
		thisHunk = malloc_first;
		if (firstTry == 2)
			firstTry = 0;

		while (thisHunk&&(thisHunk->magic == MALLOC_MAGIC)) {
			debug("malloc", "Entering hunk" );
			if (thisHunk->status == MALLOC_FREE) {
				debug("malloc", "Found free hunk" );

				/* Free, is it big enough? */
				if (thisHunk->size >= size+sizeof(mmalloc_hunk)) {
					
					debug("malloc","Found a big enough hunk.");
					
					/* Yes, big enough */
					insertBefore = thisHunk->next;
					newHunk = (pmmalloc_hunk)((UWORD)thisHunk + size + sizeof(mmalloc_hunk));
					newHunk->size = thisHunk->size - sizeof(mmalloc_hunk) - size;
					newHunk->status = MALLOC_FREE;
					newHunk->next = insertBefore;
					newHunk->magic = MALLOC_MAGIC;
					
					thisHunk->size = size;
					thisHunk->status = MALLOC_USED;
					thisHunk->next = newHunk;
					
					return (void *)((UWORD)thisHunk + sizeof(mmalloc_hunk));
				}
			}
			thisHunk = thisHunk->next;
		}
		if (firstTry) {
			/* Try again after a garbage collect */
			malloc_gc();
			firstTry = 2;
		}
	}
	return NULL;
}