* Less structures in union in structure in union inception madness
We're using a less portable anonymous union, but gcc handles that
since maybe 15 years, so that should be cool.
* We can now determine from looking at it whether the block is busy or
free, without having to search in which list the block is.
That was useles to other usages of mmalloc, but this is very
interesting when comparing heaps.
Moreover, it comes for free: it has exactly the same (memory) cost
when the block is busy, and we have a plenty of place in the block
to store that this it free when it is actually free.
Please note that this information is not updated when the block is
freed yet. (splitting the commit just in case someone tries to read it
later: this one is almost automatic refactoring)
- type = mdp->heapinfo[block].busy.type;
+ type = mdp->heapinfo[block].type;
+ if (type<0)
+ THROWF(arg_error,0,"Asked to free a fragment in a block that is already free. I'm puzzled");
+
switch (type) {
case 0:
/* Find the free cluster previous to this one in the free list.
switch (type) {
case 0:
/* Find the free cluster previous to this one in the free list.
i = mdp->heapindex;
if (i > block) {
while (i > block) {
i = mdp->heapindex;
if (i > block) {
while (i > block) {
- i = mdp->heapinfo[i].free.prev;
+ i = mdp->heapinfo[i].free_block.prev;
- i = mdp->heapinfo[i].free.next;
+ i = mdp->heapinfo[i].free_block.next;
}
while ((i != 0) && (i < block));
}
while ((i != 0) && (i < block));
- i = mdp->heapinfo[i].free.prev;
+ i = mdp->heapinfo[i].free_block.prev;
}
/* Determine how to link this block into the free list. */
}
/* Determine how to link this block into the free list. */
- if (block == i + mdp->heapinfo[i].free.size) {
+ if (block == i + mdp->heapinfo[i].free_block.size) {
/* Coalesce this block with its predecessor. */
/* Coalesce this block with its predecessor. */
- mdp->heapinfo[i].free.size += mdp->heapinfo[block].busy.info.block.size;
+ mdp->heapinfo[i].free_block.size += mdp->heapinfo[block].busy_block.size;
block = i;
} else {
/* Really link this block back into the free list. */
block = i;
} else {
/* Really link this block back into the free list. */
- mdp->heapinfo[block].free.size = mdp->heapinfo[block].busy.info.block.size;
- mdp->heapinfo[block].free.next = mdp->heapinfo[i].free.next;
- mdp->heapinfo[block].free.prev = i;
- mdp->heapinfo[i].free.next = block;
- mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev = block;
+ mdp->heapinfo[block].free_block.size = mdp->heapinfo[block].busy_block.size;
+ mdp->heapinfo[block].free_block.next = mdp->heapinfo[i].free_block.next;
+ mdp->heapinfo[block].free_block.prev = i;
+ mdp->heapinfo[i].free_block.next = block;
+ mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block;
}
/* Now that the block is linked in, see if we can coalesce it
with its successor (by deleting its successor from the list
and adding in its size). */
}
/* Now that the block is linked in, see if we can coalesce it
with its successor (by deleting its successor from the list
and adding in its size). */
- if (block + mdp->heapinfo[block].free.size ==
- mdp->heapinfo[block].free.next) {
- mdp->heapinfo[block].free.size
- += mdp->heapinfo[mdp->heapinfo[block].free.next].free.size;
- mdp->heapinfo[block].free.next
- = mdp->heapinfo[mdp->heapinfo[block].free.next].free.next;
- mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev = block;
+ if (block + mdp->heapinfo[block].free_block.size ==
+ mdp->heapinfo[block].free_block.next) {
+ mdp->heapinfo[block].free_block.size
+ += mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.size;
+ mdp->heapinfo[block].free_block.next
+ = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.next;
+ mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block;
}
/* Now see if we can return stuff to the system. */
}
/* Now see if we can return stuff to the system. */
/* Get the address of the first free fragment in this block. */
prev = (struct list *)
((char *) ADDRESS(block) +
/* Get the address of the first free fragment in this block. */
prev = (struct list *)
((char *) ADDRESS(block) +
- (mdp->heapinfo[block].busy.info.frag.first << type));
+ (mdp->heapinfo[block].busy_frag.first << type));
- if (mdp->heapinfo[block].busy.info.frag.nfree ==
+ if (mdp->heapinfo[block].busy_frag.nfree ==
(BLOCKSIZE >> type) - 1) {
/* If all fragments of this block are free, remove them
from the fragment list and free the whole block. */
(BLOCKSIZE >> type) - 1) {
/* If all fragments of this block are free, remove them
from the fragment list and free the whole block. */
if (next != NULL) {
next->prev = prev->prev;
}
if (next != NULL) {
next->prev = prev->prev;
}
- mdp->heapinfo[block].busy.type = 0;
- mdp->heapinfo[block].busy.info.block.size = 1;
- mdp->heapinfo[block].busy.info.block.busy_size = 0;
+ mdp->heapinfo[block].type = 0;
+ mdp->heapinfo[block].busy_block.size = 1;
+ mdp->heapinfo[block].busy_block.busy_size = 0;
mfree((void *) mdp, (void *) ADDRESS(block));
mfree((void *) mdp, (void *) ADDRESS(block));
- } else if (mdp->heapinfo[block].busy.info.frag.nfree != 0) {
+ } else if (mdp->heapinfo[block].busy_frag.nfree != 0) {
/* If some fragments of this block are free, link this
fragment into the fragment list after the first free
fragment of this block. */
/* If some fragments of this block are free, link this
fragment into the fragment list after the first free
fragment of this block. */
if (next->next != NULL) {
next->next->prev = next;
}
if (next->next != NULL) {
next->next->prev = next;
}
- ++mdp->heapinfo[block].busy.info.frag.nfree;
+ ++mdp->heapinfo[block].busy_frag.nfree;
} else {
/* No fragments of this block are free, so link this
fragment into the fragment list and announce that
it is the first free fragment of this block. */
prev = (struct list *) ptr;
} else {
/* No fragments of this block are free, so link this
fragment into the fragment list and announce that
it is the first free fragment of this block. */
prev = (struct list *) ptr;
- mdp->heapinfo[block].busy.info.frag.nfree = 1;
- mdp->heapinfo[block].busy.info.frag.first =
+ mdp->heapinfo[block].busy_frag.nfree = 1;
+ mdp->heapinfo[block].busy_frag.first =
RESIDUAL(ptr, BLOCKSIZE) >> type;
prev->next = mdp->fraghead[type].next;
prev->prev = &mdp->fraghead[type];
RESIDUAL(ptr, BLOCKSIZE) >> type;
prev->next = mdp->fraghead[type].next;
prev->prev = &mdp->fraghead[type];
block_free1 = mdp1->heapindex;
block_free2 = mdp2->heapindex;
block_free1 = mdp1->heapindex;
block_free2 = mdp2->heapindex;
- while(mdp1->heapinfo[block_free1].free.prev != 0){
- block_free1 = mdp1->heapinfo[block_free1].free.prev;
+ while(mdp1->heapinfo[block_free1].free_block.prev != 0){
+ block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
- while(mdp2->heapinfo[block_free2].free.prev != 0){
- block_free2 = mdp1->heapinfo[block_free2].free.prev;
+ while(mdp2->heapinfo[block_free2].free_block.prev != 0){
+ block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
}
if(block_free1 != block_free2){
}
if(block_free1 != block_free2){
first_block_free = block_free1;
first_block_free = block_free1;
- if(mdp1->heapinfo[first_block_free].free.size != mdp2->heapinfo[first_block_free].free.size){
+ if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size (in blocks) of the first free cluster");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size (in blocks) of the first free cluster");
errors++;
/* Check busy blocks (circular checking)*/
/* Check busy blocks (circular checking)*/
- i = first_block_free + mdp1->heapinfo[first_block_free].free.size;
+ i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
- if(mdp1->heapinfo[first_block_free].free.next != mdp2->heapinfo[first_block_free].free.next){
+ if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different next block free");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different next block free");
errors++;
}
block_free = first_block_free;
}
block_free = first_block_free;
- next_block_free = mdp1->heapinfo[first_block_free].free.next;
+ next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
if(next_block_free == 0)
next_block_free = mdp1->heaplimit;
if(next_block_free == 0)
next_block_free = mdp1->heaplimit;
while(i<next_block_free){
while(i<next_block_free){
- if(mdp1->heapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){
+ if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different type of busy block");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different type of busy block");
errors++;
addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
- switch(mdp1->heapinfo[i].busy.type){
+ switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
- if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){
+ if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size of a large cluster");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size of a large cluster");
errors++;
- if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){
+ if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
- XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy.info.block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
+ XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy_block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
errors++;
}else{
return 1;
}
}
}
errors++;
}else{
return 1;
}
}
}
- i = i+mdp1->heapinfo[i].busy.info.block.size;
+ i = i+mdp1->heapinfo[i].busy_block.size;
- if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){
+ if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
errors++;
- if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){
+ if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different first free fragments in the block %zu", i);
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different first free fragments in the block %zu", i);
errors++;
- frag_size = pow(2,mdp1->heapinfo[i].busy.type);
+ frag_size = pow(2,mdp1->heapinfo[i].type);
for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
if( i != first_block_free){
if( i != first_block_free){
- if(mdp1->heapinfo[block_free].free.next != mdp2->heapinfo[block_free].free.next){
+ if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different next block free");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different next block free");
errors++;
- block_free = mdp1->heapinfo[block_free].free.next;
- next_block_free = mdp1->heapinfo[block_free].free.next;
+ block_free = mdp1->heapinfo[block_free].free_block.next;
+ next_block_free = mdp1->heapinfo[block_free].free_block.next;
- i = block_free + mdp1->heapinfo[block_free].free.size;
+ i = block_free + mdp1->heapinfo[block_free].free_block.size;
if((next_block_free == 0) && (i != mdp1->heaplimit)){
while(i < mdp1->heaplimit){
if((next_block_free == 0) && (i != mdp1->heaplimit)){
while(i < mdp1->heaplimit){
- if(mdp1->heapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){
+ if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different type of busy block");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different type of busy block");
errors++;
addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
- switch(mdp1->heapinfo[i].busy.type){
+ switch(mdp1->heapinfo[i].type){
- if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){
+ if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size of a large cluster");
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different size of a large cluster");
errors++;
- if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){
+ if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
errors++;
- i = i+mdp1->heapinfo[i].busy.info.block.size;
+ i = i+mdp1->heapinfo[i].busy_block.size;
- if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){
+ if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
errors++;
- if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){
+ if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different first free fragments in the block %zu", i);
errors++;
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
XBT_DEBUG("Different first free fragments in the block %zu", i);
errors++;
- frag_size = pow(2,mdp1->heapinfo[i].busy.type);
+ frag_size = pow(2,mdp1->heapinfo[i].type);
for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
return (0);
}
memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info));
return (0);
}
memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info));
- mdp->heapinfo[0].free.size = 0;
- mdp->heapinfo[0].free.next = mdp->heapinfo[0].free.prev = 0;
+ mdp->heapinfo[0].free_block.size = 0;
+ mdp->heapinfo[0].free_block.next = mdp->heapinfo[0].free_block.prev = 0;
mdp->heapindex = 0;
mdp->heapbase = (void *) mdp->heapinfo;
mdp->flags |= MMALLOC_INITIALIZED;
mdp->heapindex = 0;
mdp->heapbase = (void *) mdp->heapinfo;
mdp->flags |= MMALLOC_INITIALIZED;
/* mark the space previously occupied by the block info as free by first marking it
* as occupied in the regular way, and then freing it */
/* mark the space previously occupied by the block info as free by first marking it
* as occupied in the regular way, and then freing it */
- newinfo[BLOCK(oldinfo)].busy.type = 0;
- newinfo[BLOCK(oldinfo)].busy.info.block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info));
- newinfo[BLOCK(oldinfo)].busy.info.block.busy_size = size;
+ newinfo[BLOCK(oldinfo)].type = 0;
+ newinfo[BLOCK(oldinfo)].busy_block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info));
+ newinfo[BLOCK(oldinfo)].busy_block.busy_size = size;
__mmalloc_free(mdp, (void *) oldinfo);
mdp->heapsize = newsize;
}
__mmalloc_free(mdp, (void *) oldinfo);
mdp->heapsize = newsize;
}
next->next->prev = next->prev;
}
block = BLOCK(result);
next->next->prev = next->prev;
}
block = BLOCK(result);
- if (--mdp->heapinfo[block].busy.info.frag.nfree != 0) {
- mdp->heapinfo[block].busy.info.frag.first =
+ if (--mdp->heapinfo[block].busy_frag.nfree != 0) {
+ mdp->heapinfo[block].busy_frag.first =
RESIDUAL(next->next, BLOCKSIZE) >> log;
}
RESIDUAL(next->next, BLOCKSIZE) >> log;
}
/* Initialize the nfree and first counters for this block. */
block = BLOCK(result);
/* Initialize the nfree and first counters for this block. */
block = BLOCK(result);
- mdp->heapinfo[block].busy.type = log;
- mdp->heapinfo[block].busy.info.frag.nfree = i - 1;
- mdp->heapinfo[block].busy.info.frag.first = i - 1;
+ mdp->heapinfo[block].type = log;
+ mdp->heapinfo[block].busy_frag.nfree = i - 1;
+ mdp->heapinfo[block].busy_frag.first = i - 1;
}
} else {
/* Large allocation to receive one or more blocks.
}
} else {
/* Large allocation to receive one or more blocks.
space we will have to get more memory from the system. */
blocks = BLOCKIFY(size);
start = block = MALLOC_SEARCH_START;
space we will have to get more memory from the system. */
blocks = BLOCKIFY(size);
start = block = MALLOC_SEARCH_START;
- while (mdp->heapinfo[block].free.size < blocks) {
- block = mdp->heapinfo[block].free.next;
+ while (mdp->heapinfo[block].free_block.size < blocks) {
+ block = mdp->heapinfo[block].free_block.next;
if (block == start) {
/* Need to get more from the system. Check to see if
the new core will be contiguous with the final free
block; if so we don't need to get as much. */
if (block == start) {
/* Need to get more from the system. Check to see if
the new core will be contiguous with the final free
block; if so we don't need to get as much. */
- block = mdp->heapinfo[0].free.prev;
- lastblocks = mdp->heapinfo[block].free.size;
+ block = mdp->heapinfo[0].free_block.prev;
+ lastblocks = mdp->heapinfo[block].free_block.size;
if (mdp->heaplimit != 0 &&
block + lastblocks == mdp->heaplimit &&
mmorecore(mdp, 0) == ADDRESS(block + lastblocks) &&
if (mdp->heaplimit != 0 &&
block + lastblocks == mdp->heaplimit &&
mmorecore(mdp, 0) == ADDRESS(block + lastblocks) &&
/* Which block we are extending (the `final free
block' referred to above) might have changed, if
it got combined with a freed info table. */
/* Which block we are extending (the `final free
block' referred to above) might have changed, if
it got combined with a freed info table. */
- block = mdp->heapinfo[0].free.prev;
+ block = mdp->heapinfo[0].free_block.prev;
- mdp->heapinfo[block].free.size += (blocks - lastblocks);
+ mdp->heapinfo[block].free_block.size += (blocks - lastblocks);
continue;
}
result = register_morecore(mdp, blocks * BLOCKSIZE);
continue;
}
result = register_morecore(mdp, blocks * BLOCKSIZE);
return (NULL);
}
block = BLOCK(result);
return (NULL);
}
block = BLOCK(result);
- mdp->heapinfo[block].busy.type = 0;
- mdp->heapinfo[block].busy.info.block.size = blocks;
- mdp->heapinfo[block].busy.info.block.busy_size = size;
+ mdp->heapinfo[block].type = 0;
+ mdp->heapinfo[block].busy_block.size = blocks;
+ mdp->heapinfo[block].busy_block.busy_size = size;
/* At this point we have found a suitable free list entry.
Figure out how to remove what we need from the list. */
result = ADDRESS(block);
/* At this point we have found a suitable free list entry.
Figure out how to remove what we need from the list. */
result = ADDRESS(block);
- if (mdp->heapinfo[block].free.size > blocks) {
+ if (mdp->heapinfo[block].free_block.size > blocks) {
/* The block we found has a bit left over,
so relink the tail end back into the free list. */
/* The block we found has a bit left over,
so relink the tail end back into the free list. */
- mdp->heapinfo[block + blocks].free.size
- = mdp->heapinfo[block].free.size - blocks;
- mdp->heapinfo[block + blocks].free.next
- = mdp->heapinfo[block].free.next;
- mdp->heapinfo[block + blocks].free.prev
- = mdp->heapinfo[block].free.prev;
- mdp->heapinfo[mdp->heapinfo[block].free.prev].free.next
- = mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev
+ mdp->heapinfo[block + blocks].free_block.size
+ = mdp->heapinfo[block].free_block.size - blocks;
+ mdp->heapinfo[block + blocks].free_block.next
+ = mdp->heapinfo[block].free_block.next;
+ mdp->heapinfo[block + blocks].free_block.prev
+ = mdp->heapinfo[block].free_block.prev;
+ mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next
+ = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev
= mdp->heapindex = block + blocks;
} else {
/* The block exactly matches our requirements,
so just remove it from the list. */
= mdp->heapindex = block + blocks;
} else {
/* The block exactly matches our requirements,
so just remove it from the list. */
- mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev
- = mdp->heapinfo[block].free.prev;
- mdp->heapinfo[mdp->heapinfo[block].free.prev].free.next
- = mdp->heapindex = mdp->heapinfo[block].free.next;
+ mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev
+ = mdp->heapinfo[block].free_block.prev;
+ mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next
+ = mdp->heapindex = mdp->heapinfo[block].free_block.next;
- mdp->heapinfo[block].busy.type = 0;
- mdp->heapinfo[block].busy.info.block.size = blocks;
- mdp->heapinfo[block].busy.info.block.busy_size = size;
+ mdp->heapinfo[block].type = 0;
+ mdp->heapinfo[block].busy_block.size = blocks;
+ mdp->heapinfo[block].busy_block.busy_size = size;
}
//printf("(%s) Done mallocing. Result is %p\n",xbt_thread_self_name(),result);fflush(stdout);
return (result);
}
//printf("(%s) Done mallocing. Result is %p\n",xbt_thread_self_name(),result);fflush(stdout);
return (result);
#include <sys/mman.h>
#include "mmprivate.h"
#include <sys/mman.h>
#include "mmprivate.h"
/* Cache the pagesize for the current host machine. Note that if the host
does not readily provide a getpagesize() function, we need to emulate it
/* Cache the pagesize for the current host machine. Note that if the host
does not readily provide a getpagesize() function, we need to emulate it
#include "portable.h"
#include "xbt/xbt_os_thread.h"
#include "xbt/mmalloc.h"
#include "portable.h"
#include "xbt/xbt_os_thread.h"
#include "xbt/mmalloc.h"
#include <semaphore.h>
#ifdef HAVE_LIMITS_H
#include <semaphore.h>
#ifdef HAVE_LIMITS_H
* - add the same for each fragments
* - make room to store the backtrace of where the fragment were malloced, too.
*/
* - add the same for each fragments
* - make room to store the backtrace of where the fragment were malloced, too.
*/
+typedef struct {
+ int type; /* 0: busy large block
+ >0: busy fragmented (fragments of size 2^type bytes)
+ <0: free block */
+ union {
/* Heap information for a busy block. */
/* Heap information for a busy block. */
- struct {
- /* Zero for a large block, or positive giving the
- logarithm to the base two of the fragment size. */
- int type;
- union {
- struct {
- size_t nfree; /* Free fragments in a fragmented block. */
- size_t first; /* First free fragment of the block. */
- } frag;
- struct {
- size_t size; /* Size (in blocks) of a large cluster. */
- size_t busy_size;
- } block;
- } info;
- } busy;
- /* Heap information for a free block (that may be the first of
- a free cluster). */
- struct {
- size_t size; /* Size (in blocks) of a free cluster. */
- size_t next; /* Index of next free cluster. */
- size_t prev; /* Index of previous free cluster. */
- } free;
+ struct {
+ size_t nfree; /* Free fragments in a fragmented block. */
+ size_t first; /* First free fragment of the block. */
+ } busy_frag;
+ struct {
+ size_t size; /* Size (in blocks) of a large cluster. */
+ size_t busy_size;
+ } busy_block;
+ /* Heap information for a free block (that may be the first of a free cluster). */
+ struct {
+ size_t size; /* Size (in blocks) of a free cluster. */
+ size_t next; /* Index of next free cluster. */
+ size_t prev; /* Index of previous free cluster. */
+ } free_block;
+ };
} malloc_info;
/* Doubly linked lists of free fragments. */
} malloc_info;
/* Doubly linked lists of free fragments. */
- type = mdp->heapinfo[block].busy.type;
+ type = mdp->heapinfo[block].type;
+ if (type<0)
+ THROWF(arg_error,0,"Asked realloc a fragment comming from a *free* block. I'm puzzled.");
+
switch (type) {
case 0:
/* Maybe reallocate a large block to a small fragment. */
switch (type) {
case 0:
/* Maybe reallocate a large block to a small fragment. */
/* The new size is a large allocation as well;
see if we can hold it in place. */
blocks = BLOCKIFY(size);
/* The new size is a large allocation as well;
see if we can hold it in place. */
blocks = BLOCKIFY(size);
- if (blocks < mdp->heapinfo[block].busy.info.block.size) {
+ if (blocks < mdp->heapinfo[block].busy_block.size) {
/* The new size is smaller; return excess memory to the free list. */
//printf("(%s) return excess memory...",xbt_thread_self_name());
/* The new size is smaller; return excess memory to the free list. */
//printf("(%s) return excess memory...",xbt_thread_self_name());
- mdp->heapinfo[block + blocks].busy.type = 0;
- mdp->heapinfo[block + blocks].busy.info.block.size
- = mdp->heapinfo[block].busy.info.block.size - blocks;
- mdp->heapinfo[block].busy.info.block.size = blocks;
- mdp->heapinfo[block].busy.info.block.busy_size = size;
+ mdp->heapinfo[block + blocks].type = 0;
+ mdp->heapinfo[block + blocks].busy_block.size
+ = mdp->heapinfo[block].busy_block.size - blocks;
+ mdp->heapinfo[block].busy_block.size = blocks;
+ mdp->heapinfo[block].busy_block.busy_size = size;
mfree(mdp, ADDRESS(block + blocks));
result = ptr;
mfree(mdp, ADDRESS(block + blocks));
result = ptr;
- } else if (blocks == mdp->heapinfo[block].busy.info.block.size) {
+ } else if (blocks == mdp->heapinfo[block].busy_block.size) {
/* No size change necessary. */
result = ptr;
} else {
/* Won't fit, so allocate a new region that will.
Free the old region first in case there is sufficient
adjacent free space to grow without moving. */
/* No size change necessary. */
result = ptr;
} else {
/* Won't fit, so allocate a new region that will.
Free the old region first in case there is sufficient
adjacent free space to grow without moving. */
- blocks = mdp->heapinfo[block].busy.info.block.size;
+ blocks = mdp->heapinfo[block].busy_block.size;
/* Prevent free from actually returning memory to the system. */
oldlimit = mdp->heaplimit;
mdp->heaplimit = 0;
/* Prevent free from actually returning memory to the system. */
oldlimit = mdp->heaplimit;
mdp->heaplimit = 0;