mirror of
https://github.com/FIX94/hbc.git
synced 2024-11-26 12:34:20 +01:00
85 lines
1.7 KiB
C
85 lines
1.7 KiB
C
|
#include <ogcsys.h>
|
||
|
#include <ogc/machine/processor.h>
|
||
|
|
||
|
#include "../config.h"
|
||
|
#include "debug.h"
|
||
|
#include "panic.h"
|
||
|
#include "blob.h"
|
||
|
|
||
|
#define MAX_BLOBS 8
|
||
|
#define BLOB_MINSLACK (512*1024)
|
||
|
|
||
|
typedef struct {
|
||
|
void *the_blob;
|
||
|
size_t blob_size;
|
||
|
void *old_arena2hi;
|
||
|
} blob_t;
|
||
|
|
||
|
blob_t blobs[MAX_BLOBS];
|
||
|
int num_blobs = 0;
|
||
|
|
||
|
// supports only stack-type allocs (free last alloced)
|
||
|
void *blob_alloc(size_t size)
|
||
|
{
|
||
|
u32 level;
|
||
|
u32 addr;
|
||
|
void *old_arena2hi;
|
||
|
|
||
|
_CPU_ISR_Disable(level);
|
||
|
if (num_blobs >= MAX_BLOBS) {
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("too many blobs\n");
|
||
|
panic();
|
||
|
}
|
||
|
|
||
|
old_arena2hi = SYS_GetArena2Hi();
|
||
|
addr = (((u32)old_arena2hi) - size) & (~0x1f);
|
||
|
|
||
|
if (addr < (BLOB_MINSLACK + (u32)SYS_GetArena2Lo())) {
|
||
|
_CPU_ISR_Restore(level);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
blobs[num_blobs].old_arena2hi = old_arena2hi;
|
||
|
blobs[num_blobs].the_blob = (void*)addr;
|
||
|
blobs[num_blobs].blob_size = size;
|
||
|
num_blobs++;
|
||
|
|
||
|
SYS_SetArena2Hi((void*)addr);
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("allocated blob size %d at 0x%08lx\n", size, addr);
|
||
|
return (void*)addr;
|
||
|
}
|
||
|
|
||
|
void blob_free(void *p)
|
||
|
{
|
||
|
u32 level;
|
||
|
if (!p)
|
||
|
return;
|
||
|
|
||
|
_CPU_ISR_Disable(level);
|
||
|
|
||
|
if (num_blobs == 0) {
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("blob_free with no blobs\n");
|
||
|
panic();
|
||
|
}
|
||
|
|
||
|
num_blobs--;
|
||
|
if (p != blobs[num_blobs].the_blob) {
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("mismatched blob_free (%p != %p)\n", p, blobs[num_blobs].the_blob);
|
||
|
panic();
|
||
|
}
|
||
|
if (SYS_GetArena2Hi() != p) {
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("someone else used MEM2 (%p != %p)\n", p, SYS_GetArena2Hi());
|
||
|
panic();
|
||
|
}
|
||
|
|
||
|
SYS_SetArena2Hi(blobs[num_blobs].old_arena2hi);
|
||
|
_CPU_ISR_Restore(level);
|
||
|
gprintf("freed blob size %d at %p\n", blobs[num_blobs].blob_size, p);
|
||
|
}
|
||
|
|