* AcessOS Microkernel Version
* heap.c
*/
-#include <common.h>
+#include <acess.h>
#include <mm_virt.h>
#include <heap.h>
#define WARNINGS 1
+#define DEBUG_TRACE 0
// === CONSTANTS ===
#define HEAP_BASE 0xE0800000
void Heap_Dump();
// === GLOBALS ===
- int giHeapSpinlock;
+ int glHeap;
void *gHeapStart;
void *gHeapEnd;
Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1);
// Lock Heap
- LOCK(&giHeapSpinlock);
+ LOCK(&glHeap);
// Traverse Heap
for( head = gHeapStart;
Warning("Size of heap address %p is invalid not aligned (0x%x)", head, head->Size);
Heap_Dump();
#endif
+ RELEASE(&glHeap);
return NULL;
}
Warning("Magic of heap address %p is invalid (0x%x)", head, head->Magic);
Heap_Dump();
#endif
- RELEASE(&giHeapSpinlock); // Release spinlock
+ RELEASE(&glHeap); // Release spinlock
return NULL;
}
// Perfect fit
if(head->Size == Bytes) {
head->Magic = MAGIC_USED;
- RELEASE(&giHeapSpinlock); // Release spinlock
+ RELEASE(&glHeap); // Release spinlock
+ #if DEBUG_TRACE
+ LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ #endif
return best->Data;
}
best = Heap_Extend( Bytes );
// Check for errors
if(!best) {
- RELEASE(&giHeapSpinlock); // Release spinlock
+ RELEASE(&glHeap); // Release spinlock
return NULL;
}
// Check size
if(best->Size == Bytes) {
- RELEASE(&giHeapSpinlock); // Release spinlock
+ RELEASE(&glHeap); // Release spinlock
+ #if DEBUG_TRACE
+ LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ #endif
return best->Data;
}
}
best->Size = Bytes; // Update size in old header
best->Magic = MAGIC_USED; // Mark block as used
- RELEASE(&giHeapSpinlock); // Release spinlock
+ RELEASE(&glHeap); // Release spinlock
+ #if DEBUG_TRACE
+ LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ #endif
return best->Data;
}
tHeapHead *head;
tHeapFoot *foot;
+ #if DEBUG_TRACE
LOG("Ptr = %p", Ptr);
LOG("Returns to %p", __builtin_return_address(0));
+ #endif
// Alignment Check
if( (Uint)Ptr & (sizeof(Uint)-1) ) {
- Warning("free - Passed a non-aligned address (%p)\n", Ptr);
+ Warning("free - Passed a non-aligned address (%p)", Ptr);
return;
}
// Check memory block - Header
head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
if(head->Magic == MAGIC_FREE) {
- Warning("free - Passed a freed block (%p)\n", head);
+ Warning("free - Passed a freed block (%p) by %p", head, __builtin_return_address(0));
return;
}
if(head->Magic != MAGIC_USED) {
return;
}
if(foot->Magic != MAGIC_FOOT) {
- Warning("free - Footer magic is invalid (%p, 0x%x)\n", head, foot->Magic);
+ Warning("free - Footer magic is invalid (%p, %p = 0x%x)\n", head, &foot->Magic, foot->Magic);
return;
}
// Lock
- LOCK( &giHeapSpinlock );
+ LOCK( &glHeap );
// Mark as free
head->Magic = MAGIC_FREE;
Heap_Merge( head );
// Release
- RELEASE( &giHeapSpinlock );
+ RELEASE( &glHeap );
}
/**
return NULL;
}
+/**
+ * \fn void *calloc(size_t num, size_t size)
+ * \brief Allocate and Zero a buffer in memory
+ * \param num Number of elements
+ * \param size Size of each element
+ */
+void *calloc(size_t num, size_t size)
+{
+ void *ret = malloc(num*size);
+ if(ret == NULL) return NULL;
+
+ memset( ret, 0, num*size );
+
+ return ret;
+}
+
+/**
+ * \fn int IsHeap(void *Ptr)
+ * \brief Checks if an address is a heap address
+ */
+int IsHeap(void *Ptr)
+{
+ tHeapHead *head;
+ if((Uint)Ptr < (Uint)gHeapStart) return 0;
+ if((Uint)Ptr > (Uint)gHeapEnd) return 0;
+
+ head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
+ if(head->Magic != MAGIC_USED && head->Magic != MAGIC_FREE)
+ return 0;
+
+ return 1;
+}
+
#if WARNINGS
void Heap_Dump()
{
}
}
#endif
+
+// === EXPORTS ===
+EXPORT(malloc);
+EXPORT(realloc);
+EXPORT(free);