Tentative fix for bug 2952961.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1619 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2010-02-16 19:21:42 +00:00
parent b8e3f8794e
commit 0c85d79066
6 changed files with 63 additions and 59 deletions

View File

@ -46,12 +46,15 @@ typedef struct memory_heap MemoryHeap;
/** /**
* @brief Memory heap block header. * @brief Memory heap block header.
*/ */
struct heap_header { union heap_header {
stkalign_t align;
struct {
union { union {
struct heap_header *next; /**< @brief Next block in free list. */ union heap_header *next; /**< @brief Next block in free list. */
MemoryHeap *heap; /**< @brief Block owner heap. */ MemoryHeap *heap; /**< @brief Block owner heap. */
} h_u; /**< @brief Overlapped fields. */ } u; /**< @brief Overlapped fields. */
size_t h_size; /**< @brief Size of the memory block. */ size_t size; /**< @brief Size of the memory block. */
} h;
}; };
/** /**
@ -60,7 +63,7 @@ struct heap_header {
struct memory_heap { struct memory_heap {
memgetfunc_t h_provider; /**< @brief Memory blocks provider for memgetfunc_t h_provider; /**< @brief Memory blocks provider for
this heap. */ this heap. */
struct heap_header h_free; /**< @brief Free blocks list header. */ union heap_header h_free; /**< @brief Free blocks list header. */
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
Mutex h_mtx; /**< @brief Heap access mutex. */ Mutex h_mtx; /**< @brief Heap access mutex. */
#else #else

View File

@ -28,11 +28,6 @@
#ifndef _MEMCORE_H_ #ifndef _MEMCORE_H_
#define _MEMCORE_H_ #define _MEMCORE_H_
/**
* @brief Memory alignment type.
*/
typedef void *align_t;
/** /**
* @brief Memory get function. * @brief Memory get function.
* @note This type must be assignment compatible with the @p chMemAlloc() * @note This type must be assignment compatible with the @p chMemAlloc()
@ -43,7 +38,7 @@ typedef void *(*memgetfunc_t)(size_t size);
/** /**
* @brief Alignment mask constant. * @brief Alignment mask constant.
*/ */
#define MEM_ALIGN_MASK (sizeof(align_t) - 1) #define MEM_ALIGN_MASK (sizeof(stkalign_t) - 1)
/** /**
* @brief Alignment helper macro. * @brief Alignment helper macro.

View File

@ -53,8 +53,8 @@ static MemoryHeap default_heap;
*/ */
void heap_init(void) { void heap_init(void) {
default_heap.h_provider = chCoreAlloc; default_heap.h_provider = chCoreAlloc;
default_heap.h_free.h_u.next = (struct heap_header *)NULL; default_heap.h_free.h.u.next = (union heap_header *)NULL;
default_heap.h_free.h_size = 0; default_heap.h_free.h.size = 0;
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
chMtxInit(&default_heap.h_mtx); chMtxInit(&default_heap.h_mtx);
#else #else
@ -72,15 +72,15 @@ void heap_init(void) {
* @param[in] size heap size * @param[in] size heap size
*/ */
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
struct heap_header *hp; union heap_header *hp;
chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit"); chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit");
heapp->h_provider = (memgetfunc_t)NULL; heapp->h_provider = (memgetfunc_t)NULL;
heapp->h_free.h_u.next = hp = buf; heapp->h_free.h.u.next = hp = buf;
heapp->h_free.h_size = 0; heapp->h_free.h.size = 0;
hp->h_u.next = NULL; hp->h.u.next = NULL;
hp->h_size = size - sizeof(struct heap_header); hp->h.size = size - sizeof(union heap_header);
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
chMtxInit(&heapp->h_mtx); chMtxInit(&heapp->h_mtx);
#else #else
@ -103,7 +103,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
* @retval NULL if the block cannot be allocated. * @retval NULL if the block cannot be allocated.
*/ */
void *chHeapAlloc(MemoryHeap *heapp, size_t size) { void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
struct heap_header *qp, *hp, *fp; union heap_header *qp, *hp, *fp;
if (heapp == NULL) if (heapp == NULL)
heapp = &default_heap; heapp = &default_heap;
@ -112,24 +112,24 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
qp = &heapp->h_free; qp = &heapp->h_free;
H_LOCK(heapp); H_LOCK(heapp);
while (qp->h_u.next != NULL) { while (qp->h.u.next != NULL) {
hp = qp->h_u.next; hp = qp->h.u.next;
if (hp->h_size >= size) { if (hp->h.size >= size) {
if (hp->h_size < size + sizeof(struct heap_header)) { if (hp->h.size < size + sizeof(union heap_header)) {
/* Gets the whole block even if it is slightly bigger than the /* Gets the whole block even if it is slightly bigger than the
requested size because the fragment would be too small to be requested size because the fragment would be too small to be
useful.*/ useful.*/
qp->h_u.next = hp->h_u.next; qp->h.u.next = hp->h.u.next;
} }
else { else {
/* Block bigger enough, must split it.*/ /* Block bigger enough, must split it.*/
fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); fp = (void *)((uint8_t *)(hp) + sizeof(union heap_header) + size);
fp->h_u.next = hp->h_u.next; fp->h.u.next = hp->h.u.next;
fp->h_size = hp->h_size - sizeof(struct heap_header) - size; fp->h.size = hp->h.size - sizeof(union heap_header) - size;
qp->h_u.next = fp; qp->h.u.next = fp;
hp->h_size = size; hp->h.size = size;
} }
hp->h_u.heap = heapp; hp->h.u.heap = heapp;
H_UNLOCK(heapp); H_UNLOCK(heapp);
return (void *)(hp + 1); return (void *)(hp + 1);
@ -142,10 +142,10 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
/* More memory is required, tries to get it from the associated provider /* More memory is required, tries to get it from the associated provider
else fails.*/ else fails.*/
if (heapp->h_provider) { if (heapp->h_provider) {
hp = heapp->h_provider(size + sizeof(struct heap_header)); hp = heapp->h_provider(size + sizeof(union heap_header));
if (hp != NULL) { if (hp != NULL) {
hp->h_u.heap = heapp; hp->h.u.heap = heapp;
hp->h_size = size; hp->h.size = size;
hp++; hp++;
return (void *)hp; return (void *)hp;
} }
@ -153,9 +153,9 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
return NULL; return NULL;
} }
#define LIMIT(p) (struct heap_header *)((uint8_t *)(p) + \ #define LIMIT(p) (union heap_header *)((uint8_t *)(p) + \
sizeof(struct heap_header) + \ sizeof(union heap_header) + \
(p)->h_size) (p)->h.size)
/** /**
* @brief Frees a previously allocated memory block. * @brief Frees a previously allocated memory block.
@ -163,13 +163,13 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
* @param[in] p pointer to the memory block to be freed * @param[in] p pointer to the memory block to be freed
*/ */
void chHeapFree(void *p) { void chHeapFree(void *p) {
struct heap_header *qp, *hp; union heap_header *qp, *hp;
MemoryHeap *heapp; MemoryHeap *heapp;
chDbgCheck(p != NULL, "chHeapFree"); chDbgCheck(p != NULL, "chHeapFree");
hp = (struct heap_header *)p - 1; hp = (union heap_header *)p - 1;
heapp = hp->h_u.heap; heapp = hp->h.u.heap;
qp = &heapp->h_free; qp = &heapp->h_free;
H_LOCK(heapp); H_LOCK(heapp);
@ -179,24 +179,24 @@ void chHeapFree(void *p) {
"within free block"); "within free block");
if (((qp == &heapp->h_free) || (hp > qp)) && if (((qp == &heapp->h_free) || (hp > qp)) &&
((qp->h_u.next == NULL) || (hp < qp->h_u.next))) { ((qp->h.u.next == NULL) || (hp < qp->h.u.next))) {
/* Insertion after qp.*/ /* Insertion after qp.*/
hp->h_u.next = qp->h_u.next; hp->h.u.next = qp->h.u.next;
qp->h_u.next = hp; qp->h.u.next = hp;
/* Verifies if the newly inserted block should be merged.*/ /* Verifies if the newly inserted block should be merged.*/
if (LIMIT(hp) == hp->h_u.next) { if (LIMIT(hp) == hp->h.u.next) {
/* Merge with the next block.*/ /* Merge with the next block.*/
hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header); hp->h.size += hp->h.u.next->h.size + sizeof(union heap_header);
hp->h_u.next = hp->h_u.next->h_u.next; hp->h.u.next = hp->h.u.next->h.u.next;
} }
if ((LIMIT(qp) == hp)) { if ((LIMIT(qp) == hp)) {
/* Merge with the previous block.*/ /* Merge with the previous block.*/
qp->h_size += hp->h_size + sizeof(struct heap_header); qp->h.size += hp->h.size + sizeof(union heap_header);
qp->h_u.next = hp->h_u.next; qp->h.u.next = hp->h.u.next;
} }
break; break;
} }
qp = qp->h_u.next; qp = qp->h.u.next;
} }
H_UNLOCK(heapp); H_UNLOCK(heapp);
@ -217,7 +217,7 @@ void chHeapFree(void *p) {
* @return The number of fragments in the heap. * @return The number of fragments in the heap.
*/ */
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
struct heap_header *qp; union heap_header *qp;
size_t n, sz; size_t n, sz;
if (heapp == NULL) if (heapp == NULL)
@ -226,8 +226,8 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
H_LOCK(heapp); H_LOCK(heapp);
sz = 0; sz = 0;
for (n = 0, qp = &heapp->h_free; qp->h_u.next; n++, qp = qp->h_u.next) for (n = 0, qp = &heapp->h_free; qp->h.u.next; n++, qp = qp->h.u.next)
sz += qp->h_u.next->h_size; sz += qp->h.u.next->h.size;
if (sizep) if (sizep)
*sizep = sz; *sizep = sz;

View File

@ -43,17 +43,19 @@ void core_init(void) {
nextmem = &__heap_base__; nextmem = &__heap_base__;
endmem = &__heap_end__; endmem = &__heap_end__;
#else #else
static align_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; static stkalign_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) /
sizeof(stkalign_t)];
nextmem = (uint8_t *)&buffer[0]; nextmem = (uint8_t *)&buffer[0];
endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) /
sizeof(stkalign_t)];
#endif #endif
} }
/** /**
* @brief Allocates a memory block. * @brief Allocates a memory block.
* @details The size of the returned block is aligned to the alignment * @details The size of the returned block is aligned to the alignment
* type @p align_t so it is not possible to allocate less than * type @p stkalign_t so it is not possible to allocate less
* <code>sizeof(align_t)</code>. * than <code>sizeof(stkalign_t)</code>.
* *
* *
* @param[in] size the size of the block to be allocated * @param[in] size the size of the block to be allocated

View File

@ -36,9 +36,11 @@
#define CH_ARCHITECTURE_NAME "x86 Simulator" #define CH_ARCHITECTURE_NAME "x86 Simulator"
/** /**
* 32 bit stack alignment. * 16 bytes stack alignment.
*/ */
typedef uint32_t stkalign_t; typedef struct {
uint8_t a[16];
} stkalign_t __attribute__((aligned(16)));
/** /**
* Generic x86 register. * Generic x86 register.

View File

@ -52,6 +52,8 @@
***************************************************************************** *****************************************************************************
*** 1.5.2 *** *** 1.5.2 ***
- FIX: Impossible to enforce alignment greater of a pointer size for heap/core
objects (bug 2952961)(backported in 1.4.1).
- FIX: Wrong prototype in template file chcore.c (bug 2951529)(backported - FIX: Wrong prototype in template file chcore.c (bug 2951529)(backported
in 1.4.1). in 1.4.1).
- NEW: Added BOARD_NAME macro to the various board.h files. - NEW: Added BOARD_NAME macro to the various board.h files.