Tentative fix for bug 2952961.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1619 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
b8e3f8794e
commit
0c85d79066
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue