Files
kolibrios/programs/develop/ktcc/trunk/libc.obj/source/stdlib/free.c
Egor00f bb59eac8d6 libc.obj: update malloc/free/realloc
гавно говна, нужно доработать
2026-01-14 00:03:55 +05:00

75 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ksys.h>
#include "_mem.h"
// Объеденить два блока (срабоает только для блоков в одном куске памяти)
// добавление обязательно должно быть справа
inline void __mem_MERGE_MEM_NODES(struct mem_node* base, struct mem_node* addition)
{ // проверка что они оба не NULL Проверка, что base находится слева от addition проверка, что они оба свободные
if (MEM_NODE_IS_FREE(addition) && mem_nodeS_ARE_IN_ONE_BLOCK(base, addition)) {
// просто тупо увеличиается размер ибо пофиг на данные что там были
const size_t s = addition->size + sizeof(struct mem_node);
base->size += s;
base->free = base->size;
if (addition->next != NULL) {
addition->next->last = base;
base->next = addition->next;
} else {
base->next = NULL;
}
}
}
#define CHECK_SIDE_IN_OTHER_BLOCK(node, side) (side == NULL || ((side != NULL) && !mem_nodeS_ARE_IN_ONE_BLOCK(, node)))
void free(void* ptr)
{
if (ptr == NULL)
return;
struct mem_node* node = GET_mem_node_HEADER(ptr);
// падает сдесь
node->free = node->size; // помечен как свободный
// и сливается с соседними блоками
if (node->next != NULL)
__mem_MERGE_MEM_NODES(node, node->next);
if (node->last != NULL)
__mem_MERGE_MEM_NODES(node->last, node);
// если нода единственная в блоке, т.к. соседние ноды находятся в других нодах или отсутвуют
if ((node->next == NULL || ((node->next != NULL) && !mem_nodeS_ARE_IN_ONE_BLOCK(node, node->next)))
&& (node->last == NULL || ((node->last != NULL) && !mem_nodeS_ARE_IN_ONE_BLOCK(node->last, node)))) {
struct mem_block* block = (struct mem_block*)(((char*)node) - sizeof(struct mem_block));
// размер блока совпадает с размером ноды (т.е. проверка, что нода ТОЧНО одна в блоке)
// если размер ноды меньше, то значит где-то в переди есть занятые ноды,
// когда они освободятся то блок освободится
if (block->size == node->size + sizeof(struct mem_block) + sizeof(struct mem_node)) {
// востановление списка
if (node->last != NULL)
node->last->next = node->next;
if (node->next != NULL)
node->next->last = node->last;
if (__mem_node == node) {
if (node->last != NULL) {
__mem_node = node->last;
} else if (node->next != NULL) {
__mem_node = node->next;
} else {
__mem_node = NULL;
}
}
_ksys_debug_puts("free block");
_ksys_free(block);
}
}
}