63 lines
1.7 KiB
C
63 lines
1.7 KiB
C
#include "chunk.h"
|
|
#include "align.h"
|
|
#include "raw_chunk_manager.h"
|
|
#include "print.h"
|
|
#include "block.h"
|
|
|
|
#include <unistd.h>
|
|
|
|
void chunk_merge(chunk_t *first, chunk_t *second)
|
|
{
|
|
#ifndef DEBUG
|
|
if (first->block_id != second->block_id)
|
|
putstr("Attempt merge two chunk on different block\n");
|
|
#endif
|
|
first->size = second->data_start - first->data_start + second->size;
|
|
first->next = second->next;
|
|
|
|
chunk_write(first);
|
|
}
|
|
|
|
int chunk_split(chunk_t *chunk, size_t new_size)
|
|
{
|
|
chunk_t new_chunk;
|
|
|
|
#ifndef DEBUG
|
|
// NOT ENOUGH SIZE TO BE SPLITTED
|
|
if (chunk->size + 1 < new_size + HEADER_SIZE + get_align_increment(chunk->current + HEADER_SIZE))
|
|
write(2, "chunk too small to be splitted\n", 31);
|
|
#endif
|
|
|
|
void* new_chunk_pos = chunk->data_start + new_size;
|
|
|
|
chunk_init(&new_chunk, chunk->size - new_size - HEADER_SIZE - get_align_increment(new_chunk_pos + HEADER_SIZE), chunk->block_id, chunk->current, new_chunk_pos, chunk->next, false);
|
|
chunk_init(chunk, new_size, chunk->block_id, chunk->prev, chunk->current, new_chunk.current, true);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void chunk_iter(chunk_t *root, void (*f)(chunk_t*))
|
|
{
|
|
chunk_t *current = root;
|
|
|
|
while (current)
|
|
{
|
|
f(current);
|
|
if (current->next == NULL)
|
|
break;
|
|
chunk_read(current->next, current);
|
|
}
|
|
}
|
|
|
|
int get_append_unused_chunk(void *root, size_t size, chunk_t *result, size_t new_block_size)
|
|
{
|
|
if (get_unused_chunk_raw(root, size, result))
|
|
{
|
|
if (add_new_block(result, new_block_size, raw_get_last_chunk(root), false))
|
|
return 1;
|
|
if (result->size + 1 < size + HEADER_SIZE + get_align_increment(result->current + HEADER_SIZE))
|
|
return 0;
|
|
chunk_split(result, size);
|
|
}
|
|
return 0;
|
|
} |