libc.obj: update comments
This commit is contained in:
@@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
if(status && status != 128) // return error and this is not abort
|
// return error and this is not abort
|
||||||
{
|
if (status && status != 128) {
|
||||||
printf("exit code: %d\n", status);
|
printf("exit code: %d\n", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__con_is_load) {
|
if (__con_is_load) {
|
||||||
con_exit(0); // пусть удерживается, так даже лучше, можно вывод упесть проанализировать
|
con_exit(0);
|
||||||
}
|
}
|
||||||
_ksys_exit();
|
_ksys_exit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,40 +4,41 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct mem_node {
|
struct mem_node {
|
||||||
// сколько свободно
|
size_t free; // Amount of free space in this node. When equal to size, the entire node is free.
|
||||||
size_t free;
|
|
||||||
|
|
||||||
// Размер блока
|
size_t size; // Total size of this memory node.
|
||||||
size_t size;
|
|
||||||
|
|
||||||
struct mem_node* last;
|
struct mem_node* last; // Pointer to the previous memory node in the linked list.
|
||||||
struct mem_node* next;
|
struct mem_node* next; // Pointer to the next memory node in the linked list.
|
||||||
};
|
};
|
||||||
|
|
||||||
// блок выделенной памяти
|
|
||||||
struct mem_block {
|
struct mem_block {
|
||||||
size_t size; // сколько было полученно памяти
|
size_t size; // Size of the allocated memory block.
|
||||||
};
|
};
|
||||||
|
|
||||||
// получить указатель на данные ноды
|
// Macro to get a pointer to the user data area from a mem_node pointer.
|
||||||
|
// This is done by adding the size of the mem_node structure to the mem_node pointer.
|
||||||
#define GET_MEM_NODE_PTR(node) (char*)((char*)(node) + sizeof(struct mem_node))
|
#define GET_MEM_NODE_PTR(node) (char*)((char*)(node) + sizeof(struct mem_node))
|
||||||
|
|
||||||
// Является ли блок сейчас пустым
|
// Macro to check if a memory node is completely free.
|
||||||
#define MEM_NODE_IS_FREE(node) (node->free == node->size)
|
#define MEM_NODE_IS_FREE(node) (node->free == node->size)
|
||||||
|
|
||||||
// Поулчить кол-во занятой памяти в ноде
|
// Macro to get the amount of used memory in a memory node.
|
||||||
#define GET_MEM_NODE_USED_MEM(node) (node->size - node->free)
|
#define GET_MEM_NODE_USED_MEM(node) (node->size - node->free)
|
||||||
|
|
||||||
// получить заголовок из указателя на данные
|
// Macro to get a pointer to the mem_node structure from a user data pointer.
|
||||||
|
// This is done by subtracting the size of the mem_node structure from the user data pointer.
|
||||||
#define GET_MEM_NODE_HEADER(ptr) ((struct mem_node*)((char*)ptr - sizeof(struct mem_node)))
|
#define GET_MEM_NODE_HEADER(ptr) ((struct mem_node*)((char*)ptr - sizeof(struct mem_node)))
|
||||||
|
|
||||||
// проверить находятся ли ноды в одном блоке.
|
// Macro to check if two adjacent memory nodes are in the same block.
|
||||||
// Если они в одном блоке, то получаестя они должны идти друг за другом
|
// Checks if the end of the left node's allocated space is the start of the right node.
|
||||||
#define MEM_NODES_ARE_IN_ONE_BLOCK(left, right) (GET_MEM_NODE_PTR(left) + left->size == (char*)right)
|
#define MEM_NODES_ARE_IN_ONE_BLOCK(left, right) (GET_MEM_NODE_PTR(left) + left->size == (char*)right)
|
||||||
|
|
||||||
// Размер блока
|
// Size of the blocks allocated at a time.
|
||||||
#define ALLOC_BLOCK_SIZE 4096
|
#define ALLOC_BLOCK_SIZE 4096
|
||||||
|
|
||||||
|
// Static pointer to the first memory node in the linked list.
|
||||||
|
// This acts as the head of the memory pool.
|
||||||
static struct mem_node* __mem_node = NULL;
|
static struct mem_node* __mem_node = NULL;
|
||||||
|
|
||||||
#endif // _LIBC_STDLIB_MEM_
|
#endif // _LIBC_STDLIB_MEM_
|
||||||
|
|||||||
@@ -6,20 +6,13 @@
|
|||||||
|
|
||||||
static void __close_all()
|
static void __close_all()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __delete_all_tmp()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __free_all_mem()
|
static void __free_all_mem()
|
||||||
{
|
{
|
||||||
struct mem_node* current_node = __mem_node;
|
struct mem_node* current_node = __mem_node;
|
||||||
|
|
||||||
while (current_node != NULL)
|
while (current_node != NULL) {
|
||||||
{
|
|
||||||
struct mem_node* tmp = current_node;
|
struct mem_node* tmp = current_node;
|
||||||
current_node = current_node->next;
|
current_node = current_node->next;
|
||||||
|
|
||||||
@@ -29,12 +22,9 @@ static void __free_all_mem()
|
|||||||
|
|
||||||
void exit(int status)
|
void exit(int status)
|
||||||
{
|
{
|
||||||
_ksys_debug_puts("exit\n");
|
|
||||||
__run_atexit();
|
__run_atexit();
|
||||||
__close_all();
|
__close_all();
|
||||||
__delete_all_tmp();
|
|
||||||
__free_all_mem();
|
__free_all_mem();
|
||||||
|
|
||||||
|
|
||||||
_exit(status);
|
_exit(status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
#include "_mem.h"
|
#include "_mem.h"
|
||||||
|
|
||||||
// Объеденить два блока (срабоает только для блоков в одном куске памяти)
|
// Macro to merge two adjacent memory nodes.
|
||||||
// добавление обязательно должно быть справа
|
#define CHECK_SIDE_IN_OTHER_BLOCK(node, side) (side == NULL || ((side != NULL) && !MEM_NODES_ARE_IN_ONE_BLOCK(node, side)))
|
||||||
|
|
||||||
inline void __mem_MERGE_MEM_NODES(struct mem_node* base, struct mem_node* addition)
|
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)) {
|
if (MEM_NODE_IS_FREE(addition) && MEM_NODES_ARE_IN_ONE_BLOCK(base, addition)) {
|
||||||
// просто тупо увеличиается размер ибо пофиг на данные что там были
|
// just change size
|
||||||
const size_t s = addition->size + sizeof(struct mem_node);
|
const size_t s = addition->size + sizeof(struct mem_node);
|
||||||
base->size += s;
|
base->size += s;
|
||||||
base->free = base->size;
|
base->free = base->size;
|
||||||
|
|
||||||
|
// and delete addition from list
|
||||||
if (addition->next != NULL) {
|
if (addition->next != NULL) {
|
||||||
addition->next->last = base;
|
addition->next->last = base;
|
||||||
base->next = addition->next;
|
base->next = addition->next;
|
||||||
@@ -22,41 +24,45 @@ inline void __mem_MERGE_MEM_NODES(struct mem_node* base, struct mem_node* additi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_SIDE_IN_OTHER_BLOCK(node, side) (side == NULL || ((side != NULL) && !mem_nodeS_ARE_IN_ONE_BLOCK(, node)))
|
|
||||||
|
|
||||||
void free(void* ptr)
|
void free(void* ptr)
|
||||||
{
|
{
|
||||||
|
// Handle NULL pointer.
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Get a pointer to the mem_node header from the user data pointer.
|
||||||
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
|
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
|
||||||
|
|
||||||
// падает сдесь
|
// Mark the memory node as free.
|
||||||
node->free = node->size; // помечен как свободный
|
node->free = node->size;
|
||||||
|
|
||||||
// и сливается с соседними блоками
|
|
||||||
|
|
||||||
|
// Merge with the next node if possible.
|
||||||
if (node->next != NULL)
|
if (node->next != NULL)
|
||||||
__mem_MERGE_MEM_NODES(node, node->next);
|
__mem_MERGE_MEM_NODES(node, node->next);
|
||||||
|
|
||||||
|
// Merge with the previous node if possible.
|
||||||
if (node->last != NULL)
|
if (node->last != NULL)
|
||||||
__mem_MERGE_MEM_NODES(node->last, node);
|
__mem_MERGE_MEM_NODES(node->last, node);
|
||||||
|
|
||||||
// если нода единственная в блоке, т.к. соседние ноды находятся в других нодах или отсутвуют
|
// If the current node is not adjacent to either the next or previous node,
|
||||||
|
// it might be a separate block that can be freed.
|
||||||
if ((node->next == NULL || ((node->next != NULL) && !MEM_NODES_ARE_IN_ONE_BLOCK(node, node->next)))
|
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)))) {
|
&& (node->last == NULL || ((node->last != NULL) && !MEM_NODES_ARE_IN_ONE_BLOCK(node->last, node)))) {
|
||||||
|
|
||||||
|
// Get a pointer to the mem_block header from the mem_node header.
|
||||||
struct mem_block* block = (struct mem_block*)(((char*)node) - sizeof(struct mem_block));
|
struct mem_block* block = (struct mem_block*)(((char*)node) - sizeof(struct mem_block));
|
||||||
// размер блока совпадает с размером ноды (т.е. проверка, что нода ТОЧНО одна в блоке)
|
|
||||||
// если размер ноды меньше, то значит где-то в переди есть занятые ноды,
|
// Check if the block size matches the node size.
|
||||||
// когда они освободятся то блок освободится
|
|
||||||
if (block->size == node->size + sizeof(struct mem_block) + sizeof(struct mem_node)) {
|
if (block->size == node->size + sizeof(struct mem_block) + sizeof(struct mem_node)) {
|
||||||
|
|
||||||
// востановление списка
|
// Update the linked list pointers to remove the current node.
|
||||||
if (node->last != NULL)
|
if (node->last != NULL)
|
||||||
node->last->next = node->next;
|
node->last->next = node->next;
|
||||||
|
|
||||||
if (node->next != NULL)
|
if (node->next != NULL)
|
||||||
node->next->last = node->last;
|
node->next->last = node->last;
|
||||||
|
|
||||||
|
// Update the head of the linked list if necessary.
|
||||||
if (__mem_node == node) {
|
if (__mem_node == node) {
|
||||||
if (node->last != NULL) {
|
if (node->last != NULL) {
|
||||||
__mem_node = node->last;
|
__mem_node = node->last;
|
||||||
@@ -66,9 +72,9 @@ void free(void* ptr)
|
|||||||
__mem_node = NULL;
|
__mem_node = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the memory block using the ksys_free function.
|
||||||
_ksys_free(block);
|
_ksys_free(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CHECK_SIDE_IN_OTHER_BLOCK
|
|
||||||
|
|||||||
@@ -4,74 +4,96 @@
|
|||||||
#include <sys/ksys.h>
|
#include <sys/ksys.h>
|
||||||
#include "_mem.h"
|
#include "_mem.h"
|
||||||
|
|
||||||
|
// Macro to align a value to a specified alignment.
|
||||||
|
// Ensures that the allocated memory is aligned to a certain boundary (e.g., 16 bytes).
|
||||||
#define __mem_align(value, align) ((value + align - 1) & ~(align - 1))
|
#define __mem_align(value, align) ((value + align - 1) & ~(align - 1))
|
||||||
|
|
||||||
void* malloc(size_t size)
|
void* malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
// Handle zero-size allocation.
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mem_node* current_node = __mem_node;
|
// Align the size to 16 bytes.
|
||||||
struct mem_node* new_node = NULL;
|
size = __mem_align(size, 16);
|
||||||
|
|
||||||
size = __mem_align(size, 16); // выравнивание
|
struct mem_node* current_node = __mem_node; // Start at the head of the linked list.
|
||||||
|
struct mem_node* new_node = NULL; // Pointer to the new node that will be created.
|
||||||
|
|
||||||
// поиск ноды в которой есть достаточно всободного места
|
// Iterate through the linked list of memory nodes.
|
||||||
while (current_node != NULL) { // зависает на поиске
|
while (current_node != NULL) {
|
||||||
|
// Check if the current node has enough free space for the requested size.
|
||||||
if (size + sizeof(struct mem_node) <= current_node->free) {
|
if (size + sizeof(struct mem_node) <= current_node->free) {
|
||||||
|
|
||||||
|
// Calculate the used memory in current node
|
||||||
const size_t s = GET_MEM_NODE_USED_MEM(current_node);
|
const size_t s = GET_MEM_NODE_USED_MEM(current_node);
|
||||||
|
|
||||||
|
// Create a new memory node after the current node's used space.
|
||||||
new_node = (struct mem_node*)(GET_MEM_NODE_PTR(current_node) + s);
|
new_node = (struct mem_node*)(GET_MEM_NODE_PTR(current_node) + s);
|
||||||
|
|
||||||
|
// Set the size of the new node.
|
||||||
new_node->size = current_node->free - sizeof(struct mem_node);
|
new_node->size = current_node->free - sizeof(struct mem_node);
|
||||||
|
|
||||||
current_node->size = s; // т.к. новая нода идёт сразу после занятых данных
|
// Update current node's size
|
||||||
current_node->free = 0; // поэтому под новую ноду выдлятся всё доступное пространство
|
current_node->size = s;
|
||||||
|
|
||||||
break;
|
// Mark current node as used.
|
||||||
|
current_node->free = 0;
|
||||||
|
|
||||||
|
break; // Found a suitable node, exit the loop.
|
||||||
}
|
}
|
||||||
current_node = current_node->next;
|
current_node = current_node->next; // Move to the next node in the list.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_node == NULL) // ну не получилось найти подходящий блок, в который удалось втиснуть
|
// If no suitable node was found in the existing list:
|
||||||
{
|
if (new_node == NULL) {
|
||||||
|
// Calculate the size of the new block, including the mem_block header, mem_node header and alignment.
|
||||||
const size_t s = __mem_align(size + sizeof(struct mem_block) + sizeof(struct mem_node), ALLOC_BLOCK_SIZE);
|
const size_t s = __mem_align(size + sizeof(struct mem_block) + sizeof(struct mem_node), ALLOC_BLOCK_SIZE);
|
||||||
|
|
||||||
// заголовок блока в начале памяти, после идёт нода
|
// Allocate a new block of memory using the ksys_alloc function (presumably a kernel-level allocation function).
|
||||||
struct mem_block* block = (struct mem_block*)_ksys_alloc(s);
|
struct mem_block* block = (struct mem_block*)_ksys_alloc(s);
|
||||||
|
|
||||||
|
// Check if the allocation was successful.
|
||||||
if (block == NULL) {
|
if (block == NULL) {
|
||||||
__errno = ENOMEM;
|
__errno = ENOMEM; // Set the error number to indicate memory allocation failure.
|
||||||
return NULL;
|
return NULL; // Return NULL to indicate allocation failure.
|
||||||
}
|
}
|
||||||
|
|
||||||
// нода идёт сразу после заглоловка блока
|
// Create a new memory node after the mem_block header.
|
||||||
new_node = (struct mem_node*)(block + sizeof(struct mem_block));
|
new_node = (struct mem_node*)(block + sizeof(struct mem_block));
|
||||||
|
|
||||||
// и под ноду выделяется всё доступное место блока
|
// Set the size of the new node.
|
||||||
new_node->size = s - sizeof(struct mem_block) - sizeof(struct mem_node);
|
new_node->size = s - sizeof(struct mem_block) - sizeof(struct mem_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_node->free = new_node->size - size; // сразу выделяется под используемые данные
|
// Set the free space in the new node.
|
||||||
|
new_node->free = new_node->size - size;
|
||||||
|
|
||||||
|
// Set the last pointer of the new node to the current node.
|
||||||
new_node->last = current_node;
|
new_node->last = current_node;
|
||||||
|
|
||||||
|
// Link the new node into the linked list.
|
||||||
if (current_node != NULL) {
|
if (current_node != NULL) {
|
||||||
|
// Set the next pointer of the current node to the new node.
|
||||||
new_node->next = current_node->next;
|
new_node->next = current_node->next;
|
||||||
|
|
||||||
|
// Update the last pointer of the next node, if it exists.
|
||||||
if (current_node->next != NULL) {
|
if (current_node->next != NULL) {
|
||||||
current_node->next->last = new_node;
|
current_node->next->last = new_node;
|
||||||
}
|
}
|
||||||
current_node->next = new_node;
|
current_node->next = new_node;
|
||||||
} else {
|
} else {
|
||||||
|
// If the current node is NULL, the new node is the first node in the list.
|
||||||
new_node->next = NULL;
|
new_node->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the linked list was empty, set the head to the new node.
|
||||||
if (__mem_node == NULL) {
|
if (__mem_node == NULL) {
|
||||||
__mem_node = new_node;
|
__mem_node = new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return a pointer to the user data area of the new node.
|
||||||
return GET_MEM_NODE_PTR(new_node);
|
return GET_MEM_NODE_PTR(new_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,23 +5,33 @@
|
|||||||
|
|
||||||
void* realloc(void* ptr, size_t newsize)
|
void* realloc(void* ptr, size_t newsize)
|
||||||
{
|
{
|
||||||
|
// Handle NULL pointer.
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// Get a pointer to the mem_node header from the user data pointer.
|
||||||
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
|
struct mem_node* node = GET_MEM_NODE_HEADER(ptr);
|
||||||
void* new_ptr;
|
void* new_ptr;
|
||||||
|
|
||||||
if (node->size >= newsize) { // если новый размер влезает в ноду
|
// If the new size is smaller than or equal to the current size:
|
||||||
|
if (node->size >= newsize) {
|
||||||
|
// Update the free space in the current node.
|
||||||
node->free = node->size - newsize;
|
node->free = node->size - newsize;
|
||||||
|
// Return the original pointer.
|
||||||
new_ptr = ptr;
|
new_ptr = ptr;
|
||||||
} else { // если не влезает, то трушно выделятся память
|
} else {
|
||||||
|
// Allocate a new block of memory with the new size.
|
||||||
new_ptr = malloc(newsize);
|
new_ptr = malloc(newsize);
|
||||||
|
|
||||||
|
// If both the old pointer and the new pointer are not NULL:
|
||||||
if (ptr != NULL && new_ptr != NULL) {
|
if (ptr != NULL && new_ptr != NULL) {
|
||||||
|
// Copy the data from the old block to the new block.
|
||||||
memcpy(new_ptr, ptr, min(newsize, node->size));
|
memcpy(new_ptr, ptr, min(newsize, node->size));
|
||||||
|
// Free the old block.
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the new pointer.
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user