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
|
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 RAW32 task switching functions which work with ARMCC (the compiler used by Keil) for Cortex M0,M1,M3,M4 and M7
|
||||||
FEATURE: Added gdispGDrawThickArc()
|
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 ***
|
*** Release 2.6 ***
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
// Slot structure - user memory follows
|
// Slot structure - user memory follows
|
||||||
typedef struct memslot {
|
typedef struct memslot {
|
||||||
struct memslot *next; // The next memslot
|
|
||||||
size_t sz; // Includes the size of this memslot.
|
size_t sz; // Includes the size of this memslot.
|
||||||
} memslot;
|
} memslot;
|
||||||
|
|
||||||
@ -48,13 +47,10 @@
|
|||||||
#define Ptr2Slot(p) ((memslot *)(p) - 1)
|
#define Ptr2Slot(p) ((memslot *)(p) - 1)
|
||||||
#define Slot2Ptr(pslot) ((pslot)+1)
|
#define Slot2Ptr(pslot) ((pslot)+1)
|
||||||
|
|
||||||
static memslot * firstSlot;
|
|
||||||
static memslot * lastSlot;
|
|
||||||
static memslot * freeSlots;
|
static memslot * freeSlots;
|
||||||
static char heap[GFX_OS_HEAP_SIZE];
|
static char heap[GFX_OS_HEAP_SIZE];
|
||||||
|
|
||||||
void _gosHeapInit(void) {
|
void _gosHeapInit(void) {
|
||||||
lastSlot = 0;
|
|
||||||
gfxAddHeapBlock(heap, GFX_OS_HEAP_SIZE);
|
gfxAddHeapBlock(heap, GFX_OS_HEAP_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,18 +58,12 @@
|
|||||||
if (sz < sizeof(memslot)+sizeof(freeslot))
|
if (sz < sizeof(memslot)+sizeof(freeslot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lastSlot)
|
((memslot *)ptr)->sz = sz;
|
||||||
lastSlot->next = (memslot *)ptr;
|
gfxFree(Slot2Ptr((memslot *)ptr));
|
||||||
else
|
|
||||||
firstSlot = lastSlot = freeSlots = (memslot *)ptr;
|
|
||||||
|
|
||||||
lastSlot->next = 0;
|
|
||||||
lastSlot->sz = sz;
|
|
||||||
NextFree(lastSlot) = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *gfxAlloc(size_t sz) {
|
void *gfxAlloc(size_t sz) {
|
||||||
register memslot *prev, *p, *new;
|
register memslot *prev, *p, *pnew;
|
||||||
|
|
||||||
if (!sz) return 0;
|
if (!sz) return 0;
|
||||||
sz = GetSlotSize(sz);
|
sz = GetSlotSize(sz);
|
||||||
@ -81,23 +71,22 @@
|
|||||||
// Loop till we have a block big enough
|
// Loop till we have a block big enough
|
||||||
if (p->sz < sz)
|
if (p->sz < sz)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Can we save some memory by splitting this block?
|
// Can we save some memory by splitting this block?
|
||||||
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
||||||
new = (memslot *)((char *)p + sz);
|
pnew = (memslot *)((char *)p + sz);
|
||||||
new->next = p->next;
|
pnew->sz = p->sz - sz;
|
||||||
p->next = new;
|
|
||||||
new->sz = p->sz - sz;
|
|
||||||
p->sz = sz;
|
p->sz = sz;
|
||||||
if (lastSlot == p)
|
NextFree(pnew) = NextFree(p);
|
||||||
lastSlot = new;
|
NextFree(p) = pnew;
|
||||||
NextFree(new) = NextFree(p);
|
|
||||||
NextFree(p) = new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove it from the free list
|
// Remove it from the free list
|
||||||
if (prev)
|
if (prev)
|
||||||
NextFree(prev) = NextFree(p);
|
NextFree(prev) = NextFree(p);
|
||||||
else
|
else
|
||||||
freeSlots = NextFree(p);
|
freeSlots = NextFree(p);
|
||||||
|
|
||||||
// Return the result found
|
// Return the result found
|
||||||
return Slot2Ptr(p);
|
return Slot2Ptr(p);
|
||||||
}
|
}
|
||||||
@ -106,7 +95,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gfxRealloc(void *ptr, size_t oldsz, size_t sz) {
|
void *gfxRealloc(void *ptr, size_t oldsz, size_t sz) {
|
||||||
register memslot *prev, *p, *new;
|
register memslot *prev, *p, *pfree;
|
||||||
(void) oldsz;
|
(void) oldsz;
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
@ -120,19 +109,14 @@
|
|||||||
sz = GetSlotSize(sz);
|
sz = GetSlotSize(sz);
|
||||||
|
|
||||||
// If the next slot is free (and contiguous) merge it into this one
|
// If the next slot is free (and contiguous) merge it into this one
|
||||||
if ((char *)p + p->sz == (char *)p->next) {
|
for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) {
|
||||||
for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) {
|
if (pfree == (memslot *)((char *)p + p->sz)) {
|
||||||
if (new == p->next) {
|
p->sz += pfree->sz;
|
||||||
p->next = new->next;
|
if (prev)
|
||||||
p->sz += new->sz;
|
NextFree(prev) = NextFree(pfree);
|
||||||
if (prev)
|
else
|
||||||
NextFree(prev) = NextFree(new);
|
freeSlots = NextFree(pfree);
|
||||||
else
|
break;
|
||||||
freeSlots = NextFree(new);
|
|
||||||
if (lastSlot == new)
|
|
||||||
lastSlot = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,50 +124,54 @@
|
|||||||
if (sz < p->sz) {
|
if (sz < p->sz) {
|
||||||
// Can we save some memory by splitting this block?
|
// Can we save some memory by splitting this block?
|
||||||
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) {
|
||||||
new = (memslot *)((char *)p + sz);
|
pfree = (memslot *)((char *)p + sz);
|
||||||
new->next = p->next;
|
pfree->sz = p->sz - sz;
|
||||||
p->next = new;
|
|
||||||
new->sz = p->sz - sz;
|
|
||||||
p->sz = sz;
|
p->sz = sz;
|
||||||
if (lastSlot == p)
|
NextFree(pfree) = freeSlots;
|
||||||
lastSlot = new;
|
freeSlots = pfree;
|
||||||
NextFree(new) = freeSlots;
|
|
||||||
freeSlots = new;
|
|
||||||
}
|
}
|
||||||
return Slot2Ptr(p);
|
return Slot2Ptr(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to do this the hard way
|
// We need to do this the hard way
|
||||||
new = gfxAlloc(sz);
|
pfree = gfxAlloc(sz);
|
||||||
if (new)
|
if (pfree)
|
||||||
return 0;
|
return 0;
|
||||||
memcpy(new, ptr, p->sz - sizeof(memslot));
|
memcpy(pfree, ptr, p->sz - sizeof(memslot));
|
||||||
gfxFree(ptr);
|
gfxFree(ptr);
|
||||||
return new;
|
return pfree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxFree(void *ptr) {
|
void gfxFree(void *ptr) {
|
||||||
register memslot *prev, *p, *new;
|
register memslot *prev, *p, *pfree;
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = Ptr2Slot(ptr);
|
p = Ptr2Slot(ptr);
|
||||||
|
|
||||||
// If the next slot is free (and contiguous) merge it into this one
|
// Find a free slot that is contiguous precceding and merge it into us
|
||||||
if ((char *)p + p->sz == (char *)p->next) {
|
for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) {
|
||||||
for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) {
|
if (p == (memslot *)((char *)pfree + pfree->sz)) {
|
||||||
if (new == p->next) {
|
pfree->sz += p->sz;
|
||||||
p->next = new->next;
|
if (prev)
|
||||||
p->sz += new->sz;
|
NextFree(prev) = NextFree(pfree);
|
||||||
if (prev)
|
else
|
||||||
NextFree(prev) = NextFree(new);
|
freeSlots = NextFree(pfree);
|
||||||
else
|
p = pfree;
|
||||||
freeSlots = NextFree(new);
|
break;
|
||||||
if (lastSlot == new)
|
}
|
||||||
lastSlot = p;
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user