Browse Source

Renamed macros to more sensible names

main
Titouan Rigoudy 11 years ago
parent
commit
45975d299c
3 changed files with 39 additions and 42 deletions
  1. +20
    -20
      ya_block.c
  2. +13
    -13
      ya_block.h
  3. +6
    -9
      yamalloc.c

+ 20
- 20
ya_block.c View File

@ -27,9 +27,9 @@ void block_print_range(intptr_t *start, intptr_t *end) {
intptr_t *block; intptr_t *block;
intptr_t block_size; intptr_t block_size;
for (block = start; block < end; block += block_size) { for (block = start; block < end; block += block_size) {
block_size = YA_SZ_BLK(block);
block_size = YA_BLK_SZ(block);
printf("Block at %p size = %ld alloc = %d\n", printf("Block at %p size = %ld alloc = %d\n",
block, block_size, YA_IS_ALLOC_BLK(block));
block, block_size, YA_BLK_IS_ALLOC(block));
} }
} }
#endif #endif
@ -42,14 +42,14 @@ void block_init(intptr_t *block, intptr_t size) {
/* Sets the allocated bit in the block's boundary tags. */ /* Sets the allocated bit in the block's boundary tags. */
void block_alloc(intptr_t *block) { void block_alloc(intptr_t *block) {
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
block[-1] |= 1; block[-1] |= 1;
block[block_size-2] |= 1; block[block_size-2] |= 1;
} }
/* Erases the allocated bit in the block's boundary tags. */ /* Erases the allocated bit in the block's boundary tags. */
void block_free(intptr_t *block) { void block_free(intptr_t *block) {
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
block[-1] &= -2; block[-1] &= -2;
block[block_size-2] &= -2; block[block_size-2] &= -2;
} }
@ -57,23 +57,23 @@ void block_free(intptr_t *block) {
/* Returns the size in words of the smallest block that can /* Returns the size in words of the smallest block that can
* store n_bytes bytes. Takes alignment and boundary tags into account */ * store n_bytes bytes. Takes alignment and boundary tags into account */
intptr_t block_fit(size_t n_bytes) { intptr_t block_fit(size_t n_bytes) {
intptr_t n_words = YA_ROUND_DIV(n_bytes, YA_SZ_WORD); // size in words
intptr_t n_words = YA_ROUND_DIV(n_bytes, YA_WORD_SZ); // size in words
// round to dword and make space for tags // round to dword and make space for tags
intptr_t size = 2 + YA_ROUND(n_words, 2); intptr_t size = 2 + YA_ROUND(n_words, 2);
ya_debug("block_fit: requested = %ld, allocating = %ld * %ld = %ld\n", ya_debug("block_fit: requested = %ld, allocating = %ld * %ld = %ld\n",
n_bytes, size, YA_SZ_WORD, size * YA_SZ_WORD);
n_bytes, size, YA_WORD_SZ, size * YA_WORD_SZ);
return size; return size;
} }
/* Tries to coalesce a block with its previous neighbor. /* Tries to coalesce a block with its previous neighbor.
* Returns a pointer to the coalesced block. */ * Returns a pointer to the coalesced block. */
intptr_t *block_join_prev(intptr_t *block) { intptr_t *block_join_prev(intptr_t *block) {
intptr_t prev_size = YA_SZ_TAG(block[-2]);
intptr_t prev_size = YA_TAG_SZ(block[-2]);
intptr_t *prev = block - prev_size; intptr_t *prev = block - prev_size;
if (prev <= heap_start || YA_IS_ALLOC_BLK(prev)) {
if (prev <= heap_start || YA_BLK_IS_ALLOC(prev)) {
return block; return block;
} }
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
block_init(prev, prev_size + block_size); block_init(prev, prev_size + block_size);
ya_debug("block_join_prev: joining %p:%ld and %p:%ld -> %p:%ld\n", ya_debug("block_join_prev: joining %p:%ld and %p:%ld -> %p:%ld\n",
block, block_size, prev, prev_size, prev, prev_size + block_size); block, block_size, prev, prev_size, prev, prev_size + block_size);
@ -83,12 +83,12 @@ intptr_t *block_join_prev(intptr_t *block) {
/* Tries to colesce a block with its next neighbor. /* Tries to colesce a block with its next neighbor.
* Returns the unchanged pointer to the block. */ * Returns the unchanged pointer to the block. */
intptr_t *block_join_next(intptr_t *block) { intptr_t *block_join_next(intptr_t *block) {
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
intptr_t *next = block + block_size; intptr_t *next = block + block_size;
if (next >= heap_end || YA_IS_ALLOC_BLK(next)) {
if (next >= heap_end || YA_BLK_IS_ALLOC(next)) {
return block; return block;
} }
intptr_t next_size = YA_SZ_BLK(next);
intptr_t next_size = YA_BLK_SZ(next);
block_init(block, block_size + next_size); block_init(block, block_size + next_size);
ya_debug("block_join_next: joining %p:%ld and %p:%ld -> %p:%ld\n", ya_debug("block_join_next: joining %p:%ld and %p:%ld -> %p:%ld\n",
block, block_size, next, next_size, block, block_size + next_size); block, block_size, next, next_size, block, block_size + next_size);
@ -107,8 +107,8 @@ intptr_t *block_join(intptr_t *block) {
/* Split the block [block_size] into [size, block_size - size] if possible /* Split the block [block_size] into [size, block_size - size] if possible
* Returns a pointer to the second block or NULL if no split occurred. */ * Returns a pointer to the second block or NULL if no split occurred. */
intptr_t *block_split(intptr_t *block, intptr_t size) { intptr_t *block_split(intptr_t *block, intptr_t size) {
intptr_t next_size = YA_SZ_BLK(block) - size;
if (next_size < YA_MIN_SZ_BLK) {
intptr_t next_size = YA_BLK_SZ(block) - size;
if (next_size < YA_BLK_MIN_SZ) {
return NULL; // not enough space to warrant a split return NULL; // not enough space to warrant a split
} }
block_init(block, size); block_init(block, size);
@ -123,8 +123,8 @@ intptr_t *block_find(intptr_t size) {
intptr_t *block; intptr_t *block;
intptr_t block_size; intptr_t block_size;
for (block = heap_start; block < heap_end; block += block_size) { for (block = heap_start; block < heap_end; block += block_size) {
block_size = YA_SZ_BLK(block);
if (!YA_IS_ALLOC_BLK(block) && size <= block_size) {
block_size = YA_BLK_SZ(block);
if (!YA_BLK_IS_ALLOC(block) && size <= block_size) {
return block; return block;
} }
} }
@ -136,8 +136,8 @@ intptr_t *block_find(intptr_t size) {
* Sets heap_start and heap_end to their appropriate values. * Sets heap_start and heap_end to their appropriate values.
* Returns the pointer to the start of the heap or NULL in case of failure. */ * Returns the pointer to the start of the heap or NULL in case of failure. */
intptr_t *heap_init() { intptr_t *heap_init() {
intptr_t size_w = YA_SZ_CHUNK / YA_SZ_WORD;
void *ptr = sbrk(YA_SZ_WORD * (size_w + 2));
intptr_t size_w = YA_CHUNK_SZ / YA_WORD_SZ;
void *ptr = sbrk(YA_WORD_SZ * (size_w + 2));
if (ptr == (void*) -1) { if (ptr == (void*) -1) {
heap_start = NULL; heap_start = NULL;
heap_end = NULL; heap_end = NULL;
@ -155,8 +155,8 @@ intptr_t *heap_init() {
/* Extends the heap by at least size_w words by calling sbrk. /* Extends the heap by at least size_w words by calling sbrk.
* Returns a pointer to the last (free) block or NULL in case of failure. */ * Returns a pointer to the last (free) block or NULL in case of failure. */
intptr_t *heap_extend(intptr_t size_w) { intptr_t *heap_extend(intptr_t size_w) {
intptr_t size = YA_ROUND(size_w * YA_SZ_WORD, YA_SZ_CHUNK);
size_w = size / YA_SZ_WORD;
intptr_t size = YA_ROUND(size_w * YA_WORD_SZ, YA_CHUNK_SZ);
size_w = size / YA_WORD_SZ;
ya_debug("heap_extend: size_w = %ld\n", size_w); ya_debug("heap_extend: size_w = %ld\n", size_w);
void *ptr = sbrk(size); void *ptr = sbrk(size);
if (ptr == (void *) - 1) { if (ptr == (void *) - 1) {


+ 13
- 13
ya_block.h View File

@ -3,8 +3,8 @@
* ya_block.h * ya_block.h
*/ */
#ifndef YA_BLOCK_H
#define YA_BLOCK_H
#ifndef BLOCK_H
#define BLOCK_H
/*----------*/ /*----------*/
/* Includes */ /* Includes */
@ -17,24 +17,24 @@
/* Constants */ /* Constants */
/*-----------*/ /*-----------*/
#define YA_SZ_WORD (sizeof(intptr_t)) // big enough to hold a pointer
#define YA_SZ_DWORD (2 * YA_SZ_WORD) // storage is aligned to a dword
#define YA_SZ_CHUNK 8192 // request memory 8k by 8k from OS
#define YA_WORD_SZ (sizeof(intptr_t)) // big enough to hold a pointer
#define YA_DWORD_SZ (2 * YA_WORD_SZ) // storage is aligned to a dword
#define YA_CHUNK_SZ 8192 // request memory 8k by 8k from OS
#define YA_MIN_SZ_BLK 4 // smallest block: dword-aligned with two boundary tags
#define YA_BLK_MIN_SZ 4 // smallest block: dword-aligned with two boundary tags
/*--------*/ /*--------*/
/* Macros */ /* Macros */
/*--------*/ /*--------*/
#define YA_IS_ALLOC_TAG(tag) ((tag) & 1)
#define YA_SZ_TAG(tag) ((tag) & -2)
#define YA_TAG_IS_ALLOC(tag) ((tag) & 1)
#define YA_TAG_SZ(tag) ((tag) & -2)
#define YA_IS_ALLOC_BLK(block) YA_IS_ALLOC_TAG((block)[-1])
#define YA_SZ_BLK(block) YA_SZ_TAG((block)[-1])
#define YA_BLK_IS_ALLOC(block) YA_TAG_IS_ALLOC((block)[-1])
#define YA_BLK_SZ(block) YA_TAG_SZ((block)[-1])
#define YA_IS_ALLOC_END(b_end) YA_IS_ALLOC_TAG((b_end)[0])
#define YA_SZ_END(b_end) YA_SZ_TAG((b_end)[0])
#define YA_END_IS_ALLOC(b_end) YA_TAG_IS_ALLOC((b_end)[0])
#define YA_END_SZ(b_end) YA_TAG_SZ((b_end)[0])
#define YA_ROUND_DIV(n, m) (((n) + ((m)-1)) / (m)) #define YA_ROUND_DIV(n, m) (((n) + ((m)-1)) / (m))
#define YA_ROUND(n, m) (YA_ROUND_DIV(n,m) * (m)) #define YA_ROUND(n, m) (YA_ROUND_DIV(n,m) * (m))
@ -59,7 +59,7 @@ intptr_t *heap_init();
* Returns a pointer to the last (free) block or NULL in case of failure. */ * Returns a pointer to the last (free) block or NULL in case of failure. */
intptr_t *heap_extend(intptr_t size_w); intptr_t *heap_extend(intptr_t size_w);
#ifdef YA_DEBUG
#ifdef DEBUG
/* Prints each block in the range from the block at start to the one at end */ /* Prints each block in the range from the block at start to the one at end */
void block_print_range(intptr_t *start, intptr_t *end); void block_print_range(intptr_t *start, intptr_t *end);
#endif #endif


+ 6
- 9
yamalloc.c View File

@ -35,8 +35,6 @@
/* Local declarations */ /* Local declarations */
/*--------------------*/ /*--------------------*/
intptr_t *heap_init();
intptr_t *heap_extend(intptr_t size);
/*----------------------*/ /*----------------------*/
/* Function definitions */ /* Function definitions */
@ -49,7 +47,6 @@ void ya_print_blocks() {
} }
#endif #endif
/* Allocates enough memory to store at least size bytes. /* Allocates enough memory to store at least size bytes.
* Returns a dword-aligned pointer to the memory or NULL in case of failure. */ * Returns a dword-aligned pointer to the memory or NULL in case of failure. */
void *malloc(size_t size) { void *malloc(size_t size) {
@ -63,7 +60,7 @@ void *malloc(size_t size) {
} }
intptr_t size_w = block_fit(size); intptr_t size_w = block_fit(size);
intptr_t *block = block_find(size_w); intptr_t *block = block_find(size_w);
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
if (size_w < block_size) { if (size_w < block_size) {
block_split(block, size_w); block_split(block, size_w);
} }
@ -76,7 +73,7 @@ void *malloc(size_t size) {
* behavior occurs. */ * behavior occurs. */
void free(void *ptr) { void free(void *ptr) {
intptr_t *block = ptr; intptr_t *block = ptr;
if (block < heap_start || block > heap_end || !YA_IS_ALLOC_BLK(block)) {
if (block < heap_start || block > heap_end || !YA_BLK_IS_ALLOC(block)) {
return; // TODO: provoke segfault return; // TODO: provoke segfault
} }
block_free(block); block_free(block);
@ -88,7 +85,7 @@ void free(void *ptr) {
* Returns the pointer to the allocated memory or NULL in case of failure. */ * Returns the pointer to the allocated memory or NULL in case of failure. */
void *calloc(size_t nmemb, size_t size) { void *calloc(size_t nmemb, size_t size) {
intptr_t *block = malloc(size * nmemb); intptr_t *block = malloc(size * nmemb);
intptr_t block_size = YA_SZ_BLK(block);
intptr_t block_size = YA_BLK_SZ(block);
for (int i = 0; i < block_size - 2; i++) { for (int i = 0; i < block_size - 2; i++) {
block[i] = 0; block[i] = 0;
} }
@ -113,7 +110,7 @@ void *realloc(void *ptr, size_t size) {
return NULL; // TODO: provoke segfault return NULL; // TODO: provoke segfault
} }
intptr_t size_w = block_fit(size); intptr_t size_w = block_fit(size);
intptr_t block_size = YA_SZ_BLK(block); // segfault if ptr after heap end
intptr_t block_size = YA_BLK_SZ(block); // segfault if ptr after heap end
if (size_w <= block_size) { if (size_w <= block_size) {
intptr_t *next = block_split(block, size_w); intptr_t *next = block_split(block, size_w);
if (next) { if (next) {
@ -125,8 +122,8 @@ void *realloc(void *ptr, size_t size) {
intptr_t *next = block + block_size; intptr_t *next = block + block_size;
// try to use next free block // try to use next free block
if (next < heap_end) { if (next < heap_end) {
intptr_t next_size = YA_SZ_BLK(next);
if (!YA_IS_ALLOC_BLK(next) && size_w <= block_size + next_size) {
intptr_t next_size = YA_BLK_SZ(next);
if (!YA_BLK_IS_ALLOC(next) && size_w <= block_size + next_size) {
block_join_next(block); // coalesce block_join_next(block); // coalesce
block_split(block, size_w); // split if possible block_split(block, size_w); // split if possible
// no need to coalesce // no need to coalesce


Loading…
Cancel
Save