diff --git a/include/villas/memory.h b/include/villas/memory.h index 99993457f..25f683e20 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -34,20 +34,20 @@ struct memtype { memzone_allocator_t alloc; memzone_deallocator_t free; - void *_vd; /**_vd; - struct memblock *block; - for (block = first; block != NULL; block = block->next) { - if (block->flags & MEMBLOCK_USED) - continue; - char* cptr = (char*) block + sizeof(struct memblock); - size_t avail = block->len; - uintptr_t uptr = (uintptr_t) cptr; - /* check alignment first; leave a gap at start of block to assure - * alignment if necessary */ - uintptr_t rem = uptr % alignment; - uintptr_t gap = 0; - if (rem != 0) { - gap = alignment - rem; - if (gap > avail) - /* next aligned address isn't in this block anymore */ - continue; - cptr += gap; - avail -= gap; - } - if (avail >= len) { - if (gap > sizeof(struct memblock)) { - /* The alignment gap is big enough to fit another block. - * The original block descriptor is already at the correct - * position, so we just change its len and create a new block - * descriptor for the actual block we're handling. */ - block->len = gap - sizeof(struct memblock); - struct memblock *newblock = (struct memblock*) (cptr - sizeof(struct memblock)); - newblock->prev = block; - newblock->next = block->next; - block->next = newblock; - newblock->flags = 0; - newblock->len = len; - block = newblock; - } else { - /* The gap is too small to fit another block descriptor, so we - * must account for the gap length in the block length. */ - block->len = len + gap; - } - if (avail > len + sizeof(struct memblock)) { - /* imperfect fit, so create another block for the remaining part */ - struct memblock *newblock = (struct memblock*) (cptr + len); - newblock->prev = block; - newblock->next = block->next; - block->next = newblock; - if (newblock->next) - newblock->next->prev = newblock; - newblock->flags = 0; - newblock->len = avail - len - sizeof(struct memblock); - } else { - /* if this block was larger than the requested length, but only - * by less than sizeof(struct memblock), we may have wasted - * memory by previous assignments to block->len. */ - block->len = avail; - } - block->flags |= MEMBLOCK_USED; - return (void*) cptr; - } - } - /* no suitable block found */ - return NULL; + struct memblock *first = (struct memblock*) m->_vd; + struct memblock *block; + for (block = first; block != NULL; block = block->next) { + if (block->flags & MEMBLOCK_USED) + continue; + char* cptr = (char*) block + sizeof(struct memblock); + size_t avail = block->len; + uintptr_t uptr = (uintptr_t) cptr; + /* check alignment first; leave a gap at start of block to assure + * alignment if necessary */ + uintptr_t rem = uptr % alignment; + uintptr_t gap = 0; + if (rem != 0) { + gap = alignment - rem; + if (gap > avail) + /* next aligned address isn't in this block anymore */ + continue; + cptr += gap; + avail -= gap; + } + if (avail >= len) { + if (gap > sizeof(struct memblock)) { + /* The alignment gap is big enough to fit another block. + * The original block descriptor is already at the correct + * position, so we just change its len and create a new block + * descriptor for the actual block we're handling. */ + block->len = gap - sizeof(struct memblock); + struct memblock *newblock = (struct memblock*) (cptr - sizeof(struct memblock)); + newblock->prev = block; + newblock->next = block->next; + block->next = newblock; + newblock->flags = 0; + newblock->len = len; + block = newblock; + } else { + /* The gap is too small to fit another block descriptor, so we + * must account for the gap length in the block length. */ + block->len = len + gap; + } + if (avail > len + sizeof(struct memblock)) { + /* imperfect fit, so create another block for the remaining part */ + struct memblock *newblock = (struct memblock*) (cptr + len); + newblock->prev = block; + newblock->next = block->next; + block->next = newblock; + if (newblock->next) + newblock->next->prev = newblock; + newblock->flags = 0; + newblock->len = avail - len - sizeof(struct memblock); + } else { + /* if this block was larger than the requested length, but only + * by less than sizeof(struct memblock), we may have wasted + * memory by previous assignments to block->len. */ + block->len = avail; + } + block->flags |= MEMBLOCK_USED; + return (void*) cptr; + } + } + /* no suitable block found */ + return NULL; } int memory_managed_free(struct memtype *m, void *ptr, size_t len) { - struct memblock *first = m->_vd; - struct memblock *block; - char* cptr = (char*) ptr; - for (block = first; block != NULL; block = block->next) { - if (!(block->flags & MEMBLOCK_USED)) - continue; - /* since we may waste some memory at the start of a block to ensure - * alignment, ptr may not actually be the start of the block */ - if ((char*) block + sizeof(struct memblock) <= cptr && - cptr < (char*) block + sizeof(struct memblock) + block->len) { - /* try to merge it with neighbouring free blocks */ - if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && - block->next && !(block->next->flags & MEMBLOCK_USED)) { - /* special case first: both previous and next block are unused */ - block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); - block->prev->next = block->next->next; - if (block->next->next) - block->next->next->prev = block->prev; - } else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { - block->prev->len += block->len + sizeof(struct memblock); - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } else if (block->next && !(block->next->flags & MEMBLOCK_USED)) { - block->len += block->next->len + sizeof(struct memblock); - block->next = block->next->next; - if (block->next) - block->next->prev = block; - } else { - /* no neighbouring free block, so just mark it as free */ - block->flags &= (~MEMBLOCK_USED); - } - return 0; - } - } - return -1; + struct memblock *first = m->_vd; + struct memblock *block; + char* cptr = (char*) ptr; + for (block = first; block != NULL; block = block->next) { + if (!(block->flags & MEMBLOCK_USED)) + continue; + /* since we may waste some memory at the start of a block to ensure + * alignment, ptr may not actually be the start of the block */ + if ((char*) block + sizeof(struct memblock) <= cptr && + cptr < (char*) block + sizeof(struct memblock) + block->len) { + /* try to merge it with neighbouring free blocks */ + if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && + block->next && !(block->next->flags & MEMBLOCK_USED)) { + /* special case first: both previous and next block are unused */ + block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); + block->prev->next = block->next->next; + if (block->next->next) + block->next->next->prev = block->prev; + } else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { + block->prev->len += block->len + sizeof(struct memblock); + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } else if (block->next && !(block->next->flags & MEMBLOCK_USED)) { + block->len += block->next->len + sizeof(struct memblock); + block->next = block->next->next; + if (block->next) + block->next->prev = block; + } else { + /* no neighbouring free block, so just mark it as free */ + block->flags &= (~MEMBLOCK_USED); + } + return 0; + } + } + return -1; } struct memtype* memtype_managed_init(void *ptr, size_t len) { - if (len < sizeof(struct memtype) + sizeof(struct memblock)) { - info("memtype_managed_init: passed region too small"); - return NULL; - } - struct memtype *mt = (struct memtype*) ptr; - mt->name = "managed"; - mt->flags = 0; - mt->alloc = memory_managed_alloc; - mt->free = memory_managed_free; - mt->alignment = 1; + if (len < sizeof(struct memtype) + sizeof(struct memblock)) { + info("memtype_managed_init: passed region too small"); + return NULL; + } + struct memtype *mt = (struct memtype*) ptr; + mt->name = "managed"; + mt->flags = 0; + mt->alloc = memory_managed_alloc; + mt->free = memory_managed_free; + mt->alignment = 1; - char *cptr = (char*) ptr; - cptr += ALIGN(sizeof(struct memtype), sizeof(void*)); - struct memblock *first = (struct memblock*) ((void*) cptr); - first->prev = NULL; - first->next = NULL; - cptr += ALIGN(sizeof(struct memblock), sizeof(void*)); - first->len = len - (cptr - (char*) ptr); - first->flags = 0; - mt->_vd = (void*) first; + char *cptr = (char*) ptr; + cptr += ALIGN(sizeof(struct memtype), sizeof(void*)); + struct memblock *first = (struct memblock*) ((void*) cptr); + first->prev = NULL; + first->next = NULL; + cptr += ALIGN(sizeof(struct memblock), sizeof(void*)); + first->len = len - (cptr - (char*) ptr); + first->flags = 0; + mt->_vd = (void*) first; - return mt; + return mt; } /* List of available memory types */ @@ -242,7 +242,7 @@ struct memtype memtype_heap = { .alloc = memory_heap_alloc, .free = memory_heap_free, .alignment = 1, - ._vd = NULL, + ._vd = NULL, }; struct memtype memtype_hugepage = {