1
+ /**
2
+ * @file heap.c
3
+
4
+ * @brief
5
+ * @version 0.1
6
+ * @date 2025-02-01
7
+ *
8
+ * @copyright Copyright (c) 2025
9
+ *
10
+ */
11
+ #define HEAP_H
1
12
#include <heap.h>
2
-
3
- #define PAGE_SIZE 4096 // Adjust as needed
4
-
5
- // Simplified memory management using a single linked list
6
- typedef struct Node {
7
- void * data ;
8
- size_t size ;
9
- struct Node * next ;
10
- } Node ;
11
-
12
- Node * head = NULL ;
13
-
14
- void * sbrk (int increment ) {
15
- static void * current_brk = NULL ; // Current break point
16
-
17
- if (current_brk == NULL ) {
18
- // Get initial break point
19
- current_brk = (void * )0x10000000 ; // Example initial break point
20
- }
21
-
22
- // Update break point
23
- void * new_brk = (void * )((char * )current_brk + increment );
24
-
25
- // Check for address space overflow (replace with actual checks)
26
- if ((unsigned long )new_brk < (unsigned long )current_brk ) {
27
- return (void * )-1 ; // Allocation failed
28
- }
29
-
30
- current_brk = new_brk ;
31
- return current_brk ;
13
+ #include <stddef.h>
14
+
15
+ uint32_t last_alloc = 0 ;
16
+ uint32_t heap_end = 0 ;
17
+ uint32_t heap_begin = 0 ;
18
+ uint32_t pheap_begin = 0 ;
19
+ uint32_t pheap_end = 0 ;
20
+ uint8_t * pheap_desc = 0 ;
21
+ uint32_t memory_used = 0 ;
22
+
23
+ void mm_init (uint32_t kernel_end )
24
+ {
25
+ last_alloc = kernel_end + 0x1000 ;
26
+ heap_begin = last_alloc ;
27
+ pheap_end = 0x400000 ;
28
+ pheap_begin = pheap_end - (MAX_PAGE_ALIGNED_ALLOCS * 4096 );
29
+ heap_end = pheap_begin ;
30
+ heap_begin = heap_end - heap_begin ;
31
+ pheap_desc = (uint8_t * )malloc (MAX_PAGE_ALIGNED_ALLOCS );
32
32
}
33
33
34
- void * malloc (size_t size ) {
35
- // Align allocation to page size
36
- size_t aligned_size = (size + PAGE_SIZE - 1 ) & ~(PAGE_SIZE - 1 );
37
-
38
- Node * current = head ;
39
- Node * prev = NULL ;
40
-
41
- // Find a suitable existing block
42
- while (current != NULL && current -> size < aligned_size ) {
43
- prev = current ;
44
- current = current -> next ;
45
- }
46
-
47
- if (current != NULL && current -> size == aligned_size ) {
48
- // Exact match found
49
- if (prev ) {
50
- prev -> next = current -> next ;
51
- } else {
52
- head = current -> next ;
53
- }
54
- return current -> data ;
55
- }
56
-
57
- // Allocate a new block
58
- void * ptr = sbrk (aligned_size );
59
- if (ptr == (void * )-1 ) {
60
- return NULL ; // Allocation failed
61
- }
62
-
63
- Node * new_node = (Node * )ptr ;
64
- new_node -> data = ptr ;
65
- new_node -> size = aligned_size ;
66
- new_node -> next = head ;
67
- head = new_node ;
68
-
69
- return ptr ;
34
+ void mm_print_out ()
35
+ {
36
+ printf ("Memory used : %d bytes" , memory_used );
37
+ printf ("Memory free : %d bytes" , heap_end - heap_begin - memory_used );
38
+ printf ("Heap size : %d bytes" , heap_end - heap_begin );
70
39
}
71
40
72
- void free (void * ptr ) {
73
- if (ptr == NULL ) {
74
- return ;
75
- }
76
-
77
- Node * current = head ;
78
- Node * prev = NULL ;
79
-
80
- while (current != NULL && current -> data != ptr ) {
81
- prev = current ;
82
- current = current -> next ;
83
- }
41
+ void free (void * mem )
42
+ {
43
+ alloc_t * alloc = (mem - sizeof (alloc_t ));
44
+ memory_used -= alloc -> size + sizeof (alloc_t );
45
+ alloc -> status = 0 ;
46
+ }
84
47
85
- if (current == NULL ) {
86
- return ; // Invalid pointer
87
- }
48
+ void pfree (void * mem )
49
+ {
50
+ if (mem < pheap_begin || mem > pheap_end ) return ;
51
+ /* Determine which page is it */
52
+ uint32_t ad = (uint32_t )mem ;
53
+ ad -= pheap_begin ;
54
+ ad /= 4096 ;
55
+ /* Now, ad has the id of the page */
56
+ pheap_desc [ad ] = 0 ;
57
+ return ;
58
+ }
88
59
89
- if (prev ) {
90
- prev -> next = current -> next ;
91
- } else {
92
- head = current -> next ;
93
- }
60
+ char * pmalloc (size_t size )
61
+ {
62
+ /* Loop through the avail_list */
63
+ for (int i = 0 ; i < MAX_PAGE_ALIGNED_ALLOCS ; i ++ )
64
+ {
65
+ if (pheap_desc [i ]) continue ;
66
+ pheap_desc [i ] = 1 ;
67
+ // printf("PAllocated from 0x%x to 0x%x\n", pheap_begin + i*4096, pheap_begin + (i+1)*4096);
68
+ return (char * )(pheap_begin + i * 4096 );
69
+ }
70
+ warn ("pmalloc: Failed to allocate memory! Out of memory." , __FILE__ );
71
+ return 0 ;
72
+ }
94
73
95
- // sbrk(0) - current->size; // Simplified deallocation (may not be entirely accurate)
74
+ char * malloc (size_t size )
75
+ {
76
+ if (!size ) return 0 ;
77
+
78
+ /* Loop through blocks and find a block sized the same or bigger */
79
+ uint8_t * mem = (uint8_t * )heap_begin ;
80
+ while ((uint32_t )mem < last_alloc )
81
+ {
82
+ alloc_t * a = (alloc_t * )mem ;
83
+ /* If the alloc has no size, we have reaced the end of allocation */
84
+ //mprint("mem=0x%x a={.status=%d, .size=%d}\n", mem, a->status, a->size);
85
+ if (!a -> size )
86
+ goto nalloc ;
87
+ /* If the alloc has a status of 1 (allocated), then add its size
88
+ * and the sizeof alloc_t to the memory and continue looking.
89
+ */
90
+ if (a -> status ) {
91
+ mem += a -> size ;
92
+ mem += sizeof (alloc_t );
93
+ mem += 4 ;
94
+ continue ;
95
+ }
96
+ /* If the is not allocated, and its size is bigger or equal to the
97
+ * requested size, then adjust its size, set status and return the location.
98
+ */
99
+ if (a -> size >= size )
100
+ {
101
+ /* Set to allocated */
102
+ a -> status = 1 ;
103
+
104
+ //mprint("RE:Allocated %d bytes from 0x%x to 0x%x\n", size, mem + sizeof(alloc_t), mem + sizeof(alloc_t) + size);
105
+ memset (mem + sizeof (alloc_t ), 0 , size );
106
+ memory_used += size + sizeof (alloc_t );
107
+ return (char * )(mem + sizeof (alloc_t ));
108
+ }
109
+ /* If it isn't allocated, but the size is not good, then
110
+ * add its size and the sizeof alloc_t to the pointer and
111
+ * continue;
112
+ */
113
+ mem += a -> size ;
114
+ mem += sizeof (alloc_t );
115
+ mem += 4 ;
116
+ }
117
+
118
+ nalloc :;
119
+ if (last_alloc + size + sizeof (alloc_t ) >= heap_end )
120
+ {
121
+ meltdown_screen ("Heap out of memory!" , __FILE__ , __LINE__ , 0 , 0 , 0 );
122
+ hcf ();
123
+ }
124
+ alloc_t * alloc = (alloc_t * )last_alloc ;
125
+ alloc -> status = 1 ;
126
+ alloc -> size = size ;
127
+
128
+ last_alloc += size ;
129
+ last_alloc += sizeof (alloc_t );
130
+ last_alloc += 4 ;
131
+ // printf("Allocated %d bytes from to 0x%x", size, (uint32_t)alloc + sizeof(alloc_t), last_alloc);
132
+ memory_used += size + 4 + sizeof (alloc_t );
133
+ memset ((char * )((uint32_t )alloc + sizeof (alloc_t )), 0 , size );
134
+ return (char * )((uint32_t )alloc + sizeof (alloc_t ));
135
+ /*
136
+ char* ret = (char*)last_alloc;
137
+ last_alloc += size;
138
+ if(last_alloc >= heap_end)
139
+ {
140
+ panic("Cannot allocate %d bytes! Out of memory.\n", size);
141
+ }
142
+ printf("Allocated %d bytes from 0x%x to 0x%x", size, ret, last_alloc);
143
+ return ret;*/
96
144
}
97
145
98
- void * realloc (void * ptr , size_t size ) {
99
- if (ptr == NULL ) {
100
- return malloc (size ); // Use your malloc
146
+ char * realloc (void * ptr , size_t size ) {
147
+ if (! ptr ) {
148
+ return malloc (size ); // If ptr is NULL, treat as malloc
101
149
}
102
150
103
151
if (size == 0 ) {
104
- free (ptr ); // Use your free
152
+ free (ptr ); // If size is 0, treat as free
105
153
return NULL ;
106
154
}
107
155
108
- Node * current = head ;
109
- while (current != NULL && current -> data != ptr ) {
110
- current = current -> next ;
111
- }
112
-
113
- if (current == NULL ) {
114
- return NULL ; // Invalid pointer
115
- }
156
+ alloc_t * old_alloc = (alloc_t * )((uint8_t * )ptr - sizeof (alloc_t ));
157
+ size_t old_size = old_alloc -> size ;
116
158
117
- if (current -> size == size ) {
118
- return ptr ; // No change needed
159
+ if (size == old_size ) {
160
+ return ptr ; // If size is the same, return the original pointer
119
161
}
120
162
121
- // Try to expand in place (more efficient)
122
- // ... (Implementation for expanding in place, if possible) ...
163
+ char * new_ptr = malloc (size ); // Allocate new memory
123
164
124
- // If expanding in place isn't possible, allocate a new block
125
- void * new_ptr = malloc (size ); // Use your malloc
126
- if (new_ptr == NULL ) {
127
- return NULL ;
165
+ if (!new_ptr ) {
166
+ return NULL ; // Allocation failed
128
167
}
129
168
130
- size_t copy_size = (size < current -> size ) ? size : current -> size ; // Don't copy more than the smaller size
131
- memcpy (new_ptr , ptr , copy_size );
132
- free (ptr ); // Use your free
169
+ size_t copy_size = (size < old_size ) ? size : old_size ; // Copy the smaller of the two sizes
170
+ memcpy (new_ptr , ptr , copy_size ); // Copy the data
171
+
172
+ free (ptr ); // Free the old memory block
133
173
134
- current -> data = new_ptr ;
135
- current -> size = size ; // Update the size!
136
174
return new_ptr ;
137
175
}
0 commit comments