Update the Raw32 heap allocator to remove a memory merging bug.
The new code has less allocation overhead but memory blocks are now not tracked while allocated.
This commit is contained in:
parent
bc7a2b05c1
commit
f495b49f53
@ -29,6 +29,8 @@ FEATURE: Added the ability to display the detected compiler
|
||||
FIX: Fixed an illegal instruction in the Cortex M0 task switcher
|
||||
FEATURE: Added RAW32 task switching functions which work with ARMCC (the compiler used by Keil) for Cortex M0,M1,M3,M4 and M7
|
||||
FEATURE: Added gdispGDrawThickArc()
|
||||
FIX: Fix a memory merging issue with the RAW32 memory allocator
|
||||
FIX: Update RAW32 CLIB threads support for more recent versions of the MINGW compiler
|
||||
|
||||
|
||||
*** Release 2.6 ***
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
// Slot structure - user memory follows
|
||||
typedef struct memslot {
|
||||
struct memslot *next; // The next memslot
|
||||
size_t sz; // Includes the size of this memslot.
|
||||
} memslot;
|
||||
|
||||
@ -48,13 +47,10 @@
|
||||
#define Ptr2Slot(p) ((memslot *)(p) - 1)
|
||||
#define Slot2Ptr(pslot) ((pslot)+1)
|
||||
|
||||
static memslot * firstSlot;
|
||||
static memslot * lastSlot;
|
||||
static memslot * freeSlots;
|
||||
static char heap[GFX_OS_HEAP_SIZE];
|
||||
|
||||
void _gosHeapInit(void) {
|
||||
lastSlot = 0;
|
||||
gfxAddHeapBlock(heap, GFX_OS_HEAP_SIZE);
|
||||
}
|
||||
|
||||
@ -62,18 +58,12 @@
|
||||
if (sz < sizeof(memslot)+sizeof(freeslot))
|
||||
return;
|
||||
|
||||
if (lastSlot)
|
||||
lastSlot->next = (memslot *)ptr;
|
||||
else
|
||||
firstSlot = lastSlot = freeSlots = (memslot *)ptr;
|
||||
|
||||
lastSlot->next = 0;
|
||||
lastSlot->sz = sz;
|
||||
NextFree(lastSlot) = 0;
|
||||
((memslot *)ptr)->sz = sz;
|
||||
gfxFree(Slot2Ptr((memslot *)ptr));
|
||||
}
|
||||
|
||||
void *gfxAlloc(size_t sz) {
|
||||
register memslot *prev, *p, *new;
|
||||
register memslot *prev, *p, *pnew;
|
||||
|
||||
if (!sz) return 0;
|
||||
sz = GetSlotSize(sz);
|
||||
@ -81,23 +71,22 @@
|
||||
// Loop till we have a block big enough
|
||||
if (p->sz < sz)
|
||||
continue;
|
||||
|
||||
// Can we save some memory by splitting this block?
|
||||
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
||||
new = (memslot *)((char *)p + sz);
|
||||
new->next = p->next;
|
||||
p->next = new;
|
||||
new->sz = p->sz - sz;
|
||||
pnew = (memslot *)((char *)p + sz);
|
||||
pnew->sz = p->sz - sz;
|
||||
p->sz = sz;
|
||||
if (lastSlot == p)
|
||||
lastSlot = new;
|
||||
NextFree(new) = NextFree(p);
|
||||
NextFree(p) = new;
|
||||
NextFree(pnew) = NextFree(p);
|
||||
NextFree(p) = pnew;
|
||||
}
|
||||
|
||||
// Remove it from the free list
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(p);
|
||||
else
|
||||
freeSlots = NextFree(p);
|
||||
|
||||
// Return the result found
|
||||
return Slot2Ptr(p);
|
||||
}
|
||||
@ -106,7 +95,7 @@
|
||||
}
|
||||
|
||||
void *gfxRealloc(void *ptr, size_t oldsz, size_t sz) {
|
||||
register memslot *prev, *p, *new;
|
||||
register memslot *prev, *p, *pfree;
|
||||
(void) oldsz;
|
||||
|
||||
if (!ptr)
|
||||
@ -120,71 +109,70 @@
|
||||
sz = GetSlotSize(sz);
|
||||
|
||||
// If the next slot is free (and contiguous) merge it into this one
|
||||
if ((char *)p + p->sz == (char *)p->next) {
|
||||
for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) {
|
||||
if (new == p->next) {
|
||||
p->next = new->next;
|
||||
p->sz += new->sz;
|
||||
for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) {
|
||||
if (pfree == (memslot *)((char *)p + p->sz)) {
|
||||
p->sz += pfree->sz;
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(new);
|
||||
NextFree(prev) = NextFree(pfree);
|
||||
else
|
||||
freeSlots = NextFree(new);
|
||||
if (lastSlot == new)
|
||||
lastSlot = p;
|
||||
freeSlots = NextFree(pfree);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this block is large enough we are nearly done
|
||||
if (sz < p->sz) {
|
||||
// Can we save some memory by splitting this block?
|
||||
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
||||
new = (memslot *)((char *)p + sz);
|
||||
new->next = p->next;
|
||||
p->next = new;
|
||||
new->sz = p->sz - sz;
|
||||
pfree = (memslot *)((char *)p + sz);
|
||||
pfree->sz = p->sz - sz;
|
||||
p->sz = sz;
|
||||
if (lastSlot == p)
|
||||
lastSlot = new;
|
||||
NextFree(new) = freeSlots;
|
||||
freeSlots = new;
|
||||
NextFree(pfree) = freeSlots;
|
||||
freeSlots = pfree;
|
||||
}
|
||||
return Slot2Ptr(p);
|
||||
}
|
||||
|
||||
// We need to do this the hard way
|
||||
new = gfxAlloc(sz);
|
||||
if (new)
|
||||
pfree = gfxAlloc(sz);
|
||||
if (pfree)
|
||||
return 0;
|
||||
memcpy(new, ptr, p->sz - sizeof(memslot));
|
||||
memcpy(pfree, ptr, p->sz - sizeof(memslot));
|
||||
gfxFree(ptr);
|
||||
return new;
|
||||
return pfree;
|
||||
}
|
||||
|
||||
void gfxFree(void *ptr) {
|
||||
register memslot *prev, *p, *new;
|
||||
register memslot *prev, *p, *pfree;
|
||||
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
p = Ptr2Slot(ptr);
|
||||
|
||||
// If the next slot is free (and contiguous) merge it into this one
|
||||
if ((char *)p + p->sz == (char *)p->next) {
|
||||
for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) {
|
||||
if (new == p->next) {
|
||||
p->next = new->next;
|
||||
p->sz += new->sz;
|
||||
// Find a free slot that is contiguous precceding and merge it into us
|
||||
for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) {
|
||||
if (p == (memslot *)((char *)pfree + pfree->sz)) {
|
||||
pfree->sz += p->sz;
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(new);
|
||||
NextFree(prev) = NextFree(pfree);
|
||||
else
|
||||
freeSlots = NextFree(new);
|
||||
if (lastSlot == new)
|
||||
lastSlot = p;
|
||||
freeSlots = NextFree(pfree);
|
||||
p = pfree;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a free slot that is contiguous after and merge it into this one
|
||||
for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) {
|
||||
if (pfree == (memslot *)((char *)p + p->sz)) {
|
||||
p->sz += pfree->sz;
|
||||
if (prev)
|
||||
NextFree(prev) = NextFree(pfree);
|
||||
else
|
||||
freeSlots = NextFree(pfree);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add it into the free chain
|
||||
|
Loading…
Reference in New Issue
Block a user