Should work
This commit is contained in:
parent
ed33e08dae
commit
cc45900748
1 changed files with 148 additions and 50 deletions
190
mem_man.c
190
mem_man.c
|
|
@ -28,68 +28,166 @@
|
|||
* shall be maintained in a linked list.
|
||||
*/
|
||||
|
||||
#define MEMORY_BLOCK_CNT 1024;
|
||||
#define MEMORY_BLOCK_CNT 1024
|
||||
#define BYTES_PER_BLOCK 4
|
||||
|
||||
static int memory[MEMORY_BLOCK_CNT];
|
||||
static size_t allocatedBlocks = 0;
|
||||
static size_t freeBlocks = MEMORY_BLOCK_CNT;
|
||||
|
||||
static void init_memory() {
|
||||
static int initialized = 0;
|
||||
if (!initialized) {
|
||||
for (size_t i = 0; i < MEMORY_BLOCK_CNT; i++) {
|
||||
memory[i] = 0xAFFEBAFF;
|
||||
}
|
||||
initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a memory block of the given size in bytes
|
||||
* in a similar way as `malloc(size)`.
|
||||
*
|
||||
* @param size The number of bytes to allocate.
|
||||
* @return The pointer to the allocated memory block or 0,
|
||||
* if no memory could be allocated.
|
||||
*/
|
||||
void *my_alloc(size_t size) {
|
||||
return 0;
|
||||
init_memory();
|
||||
|
||||
if (size == 0) {
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
size_t start = MEMORY_BLOCK_CNT;
|
||||
size_t freePlaces = 0;
|
||||
size_t blocks_needed = (size + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK;
|
||||
|
||||
while (i < MEMORY_BLOCK_CNT) {
|
||||
if (memory[i] == 0xAFFEBAFF) {
|
||||
if (freePlaces == 0) {
|
||||
start = i;
|
||||
}
|
||||
freePlaces++;
|
||||
|
||||
if (freePlaces == blocks_needed) {
|
||||
for (size_t j = 0; j < blocks_needed; j++) {
|
||||
memory[start + j] = 0xDEADBEEF;
|
||||
}
|
||||
freeBlocks -= blocks_needed;
|
||||
allocatedBlocks += blocks_needed;
|
||||
return &memory[start];
|
||||
}
|
||||
} else {
|
||||
freePlaces = 0;
|
||||
start = MEMORY_BLOCK_CNT;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the addressed memory block that was allocated via function `my_alloc(...)`.
|
||||
* If the addressed memory is not allocated, a warning is printed.
|
||||
*
|
||||
* @param p The pointer to the memory to free.
|
||||
*/
|
||||
void my_free(void *p) {
|
||||
int start = get_unit_index(p);
|
||||
if (start == -1) {
|
||||
printf("Memory is not allocated\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a brief statistic report about memory that reveals the following key values:
|
||||
* # total available memory in bytes.
|
||||
* # free (not allocated) memory in bytes.
|
||||
* # used (allocated) memory in bytes
|
||||
* # free memory in percentage (0 % to 100%)
|
||||
* # number of allocated units (continuously allocated portions of the memory, not memory blocks)
|
||||
* # largest free continuous memory unit in bytes.
|
||||
*/
|
||||
size_t freed_blocks = 0;
|
||||
size_t i = start;
|
||||
|
||||
while (i < MEMORY_BLOCK_CNT && memory[i] == 0xDEADBEEF) {
|
||||
memory[i] = 0xAFFEBAFF;
|
||||
freed_blocks++;
|
||||
i++;
|
||||
}
|
||||
|
||||
freeBlocks += freed_blocks;
|
||||
allocatedBlocks -= freed_blocks;
|
||||
}
|
||||
|
||||
MemStat mem_get_statistics() {
|
||||
return (MemStat){0, 0, 0, 0, 0, 0};
|
||||
init_memory();
|
||||
|
||||
MemStat stat;
|
||||
stat.total_bytes = MEMORY_BLOCK_CNT * BYTES_PER_BLOCK;
|
||||
stat.free_bytes = freeBlocks * BYTES_PER_BLOCK;
|
||||
stat.used_bytes = allocatedBlocks * BYTES_PER_BLOCK;
|
||||
stat.free_percentage = (double)stat.free_bytes / (double)stat.total_bytes * 100;
|
||||
|
||||
size_t units_count = 0;
|
||||
size_t i = 0;
|
||||
|
||||
while (i < MEMORY_BLOCK_CNT) {
|
||||
if (memory[i] == 0xDEADBEEF) {
|
||||
units_count++;
|
||||
while (i < MEMORY_BLOCK_CNT && memory[i] == 0xDEADBEEF) {
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
stat.allocated_units_count = units_count;
|
||||
|
||||
size_t largest_free_unit = 0;
|
||||
size_t current_free_unit = 0;
|
||||
|
||||
for (i = 0; i < MEMORY_BLOCK_CNT; i++) {
|
||||
if (memory[i] == 0xAFFEBAFF) {
|
||||
current_free_unit++;
|
||||
} else {
|
||||
if (current_free_unit > largest_free_unit) {
|
||||
largest_free_unit = current_free_unit;
|
||||
}
|
||||
current_free_unit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_free_unit > largest_free_unit) {
|
||||
largest_free_unit = current_free_unit;
|
||||
}
|
||||
|
||||
stat.larger_free_unit_bytes = largest_free_unit * BYTES_PER_BLOCK;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the allocated units (continuously allocated portions of the memory, not memory blocks)
|
||||
* including their start address within the managed memory as well as their size
|
||||
* ordered by their start address.
|
||||
*/
|
||||
void mem_print_units() {
|
||||
return;
|
||||
init_memory();
|
||||
|
||||
size_t i = 0;
|
||||
while (i < MEMORY_BLOCK_CNT) {
|
||||
if (memory[i] == 0xDEADBEEF) {
|
||||
size_t start = i;
|
||||
size_t size = 0;
|
||||
while (i < MEMORY_BLOCK_CNT && memory[i] == 0xDEADBEEF) {
|
||||
size++;
|
||||
i++;
|
||||
}
|
||||
printf("Allocated: Index %zu; Size: %zu\n", start, size);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the index of the allocated unit (continuously allocated portions of the memory, not memory blocks)
|
||||
* the addressed memory belongs to. If the addressed memory is not allocated or the address is outside
|
||||
* the range of the managed memory, a value less than zero provided.
|
||||
*
|
||||
* @param p_mem The pointer to the memory to query.
|
||||
* @return The unit index the address belongs to or a value less than 0 if the memory is not allocated.
|
||||
*/
|
||||
int get_unit_index(void *p_mem) {
|
||||
return 0;
|
||||
if (p_mem < (void*)memory || p_mem >= (void*)(memory + MEMORY_BLOCK_CNT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the content of the memory.
|
||||
*/
|
||||
void mem_dump() {
|
||||
return;
|
||||
int index = ((int*)p_mem - memory);
|
||||
|
||||
if (memory[index] != 0xDEADBEEF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (index > 0 && memory[index-1] == 0xDEADBEEF) {
|
||||
index--;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void mem_dump() {
|
||||
init_memory();
|
||||
|
||||
for (size_t i = 0; i < MEMORY_BLOCK_CNT; i++) {
|
||||
printf("Memory: Index %zu; Content 0x%X\n", i, memory[i]);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue