Reformat code and add some asm functions
This commit is contained in:
parent
73a01944a4
commit
25b3f3c4f7
|
@ -5,10 +5,14 @@ KERNEL_ELF=kernel.elf
|
||||||
SOURCES=$(wildcard *.c)
|
SOURCES=$(wildcard *.c)
|
||||||
SOURCES_INTERRUPTIONS=$(wildcard interruptions/*.c)
|
SOURCES_INTERRUPTIONS=$(wildcard interruptions/*.c)
|
||||||
SOURCES_DRIVERS=$(wildcard drivers/*.c)
|
SOURCES_DRIVERS=$(wildcard drivers/*.c)
|
||||||
|
SOURCES_UTILS=$(wildcard utils/*.c)
|
||||||
|
SOURCES_TESTS=$(wildcard tests/*.c)
|
||||||
SOURCES_INTERRUPTIONS_ASM=$(wildcard interruptions/*.asm)
|
SOURCES_INTERRUPTIONS_ASM=$(wildcard interruptions/*.asm)
|
||||||
SOURCES_ASM=$(wildcard asm/*.asm)
|
SOURCES_ASM=$(wildcard asm/*.asm)
|
||||||
OBJECTS=$(SOURCES:.c=.o)
|
OBJECTS=$(SOURCES:.c=.o)
|
||||||
OBJECTS_DRIVERS=$(SOURCES_DRIVERS:.c=.o)
|
OBJECTS_DRIVERS=$(SOURCES_DRIVERS:.c=.o)
|
||||||
|
OBJECTS_UTILS=$(SOURCES_UTILS:.c=.o)
|
||||||
|
OBJECTS_TESTS=$(SOURCES_TESTS:.c=.o)
|
||||||
OBJECTS_INTERRUPTIONS=$(SOURCES_INTERRUPTIONS:.c=.o)
|
OBJECTS_INTERRUPTIONS=$(SOURCES_INTERRUPTIONS:.c=.o)
|
||||||
OBJECTS_INTERRUPTIONS_ASM=$(SOURCES_INTERRUPTIONS_ASM:.asm=.o)
|
OBJECTS_INTERRUPTIONS_ASM=$(SOURCES_INTERRUPTIONS_ASM:.asm=.o)
|
||||||
OBJECTS_ASM=$(SOURCES_ASM:.asm=.o)
|
OBJECTS_ASM=$(SOURCES_ASM:.asm=.o)
|
||||||
|
@ -17,7 +21,7 @@ LOADERSRC=loader.asm
|
||||||
LOADEROBJECT=$(LOADERSRC:.asm=.o)
|
LOADEROBJECT=$(LOADERSRC:.asm=.o)
|
||||||
STATICLIBS=
|
STATICLIBS=
|
||||||
|
|
||||||
ALL_OBJECTS= $(LOADEROBJECT) $(OBJECTS) $(OBJECTS_ASM) $(OBJECTS_INTERRUPTIONS) $(OBJECTS_INTERRUPTIONS_ASM) $(OBJECTS_DRIVERS)
|
ALL_OBJECTS= $(LOADEROBJECT) $(OBJECTS) $(OBJECTS_ASM) $(OBJECTS_INTERRUPTIONS) $(OBJECTS_INTERRUPTIONS_ASM) $(OBJECTS_DRIVERS) $(OBJECTS_UTILS) $(OBJECTS_TESTS)
|
||||||
|
|
||||||
all: $(KERNEL) $(KERNEL_ELF)
|
all: $(KERNEL) $(KERNEL_ELF)
|
||||||
|
|
||||||
|
@ -28,7 +32,7 @@ $(KERNEL_ELF): $(STATICLIBS) $(ALL_OBJECTS)
|
||||||
$(LD) $(LDFLAGS) -T kernel.ld --oformat=elf64-x86-64 -o $@ $^
|
$(LD) $(LDFLAGS) -T kernel.ld --oformat=elf64-x86-64 -o $@ $^
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCC) $(GCCFLAGS) -I./include -I./drivers -I./interruptions $(MFLAG) -c $< -o $@
|
$(GCC) $(GCCFLAGS) -I./include -I./drivers -I./interruptions -I./utils -I./tests $(MFLAG) -c $< -o $@
|
||||||
|
|
||||||
%.o : %.asm
|
%.o : %.asm
|
||||||
$(ASM) $(ASMFLAGS) $< -o $@
|
$(ASM) $(ASMFLAGS) $< -o $@
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
GLOBAL getCharInterrupt, getTimeGen, getMemGen, getRegs, getRSP
|
GLOBAL getCharInterrupt, getTimeGen, getMemGen, getRegs, getRSP, forceTimer, enter_region, leave_region
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
|
forceTimer:
|
||||||
|
int 20h
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
; tiene que ser uint32_t el parametro, no soporta más xchg. aunq también podría ser menos
|
||||||
|
enter_region:
|
||||||
|
;push eax no haría falta pues lo podemos perder...
|
||||||
|
mov eax, 1
|
||||||
|
xchg eax, [rdi]
|
||||||
|
cmp eax, 0
|
||||||
|
jne enter_region
|
||||||
|
ret
|
||||||
|
|
||||||
|
leave_region:
|
||||||
|
mov dword [rdi], 0
|
||||||
|
ret
|
||||||
|
|
||||||
getCharInterrupt:
|
getCharInterrupt:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
|
|
@ -54,8 +54,13 @@ void printBottlerAndWait();
|
||||||
|
|
||||||
#include "test_util.h"
|
#include "test_util.h"
|
||||||
|
|
||||||
|
#ifdef BUDDY
|
||||||
|
#define MAX_BLOCKS 128
|
||||||
|
#define MAX_MEMORY 800
|
||||||
|
#else
|
||||||
#define MAX_BLOCKS 42//1024/24 //128
|
#define MAX_BLOCKS 42//1024/24 //128
|
||||||
#define MAX_MEMORY 352//1024-42x16 //Should be around 80% of memory managed by the MM
|
#define MAX_MEMORY 352//1024-42x16 //Should be around 80% of memory managed by the MM
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct MM_rq{
|
typedef struct MM_rq{
|
||||||
void *address;
|
void *address;
|
||||||
|
@ -67,9 +72,9 @@ void test_mm(){
|
||||||
uint8_t rq;
|
uint8_t rq;
|
||||||
uint32_t total;
|
uint32_t total;
|
||||||
|
|
||||||
// int i = 6;
|
int i = 1000;
|
||||||
// while (i-- != 0){
|
while (i-- != 0){
|
||||||
while (1){
|
// while (1){
|
||||||
rq = 0;
|
rq = 0;
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
|
@ -124,8 +129,8 @@ void test_mm(){
|
||||||
// ncPrint("libre dps de free: ");
|
// ncPrint("libre dps de free: ");
|
||||||
// ncPrintDec(xPortGetFreeHeapSize());
|
// ncPrintDec(xPortGetFreeHeapSize());
|
||||||
// ncNewline();
|
// ncNewline();
|
||||||
// ncPrint("termine un loop regio");
|
ncPrint("termine un loop regio");
|
||||||
// ncNewline();
|
ncNewline();
|
||||||
|
|
||||||
// if (i == 5)
|
// if (i == 5)
|
||||||
// wait(3);
|
// wait(3);
|
||||||
|
@ -152,14 +157,14 @@ int main() {
|
||||||
// return EXIT_FAILURE;
|
// return EXIT_FAILURE;
|
||||||
// if (testTwo() == EXIT_FAILURE)
|
// if (testTwo() == EXIT_FAILURE)
|
||||||
// return EXIT_FAILURE;
|
// return EXIT_FAILURE;
|
||||||
test_mm();
|
|
||||||
#endif
|
#endif
|
||||||
|
// test_mm();
|
||||||
|
|
||||||
saveSampleRSP(getRSP());
|
saveSampleRSP(getRSP());
|
||||||
|
|
||||||
// printBottlerAndWait();
|
printBottlerAndWait();
|
||||||
|
|
||||||
// ((EntryPoint)sampleCodeModuleAddress)();
|
((EntryPoint)sampleCodeModuleAddress)();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,460 +0,0 @@
|
||||||
// #ifdef BUDDY
|
|
||||||
// #include <stdio.h>
|
|
||||||
// #include <stdlib.h>
|
|
||||||
// #include <time.h>
|
|
||||||
// #include <math.h>
|
|
||||||
// #include <string.h>
|
|
||||||
// #define MANAGED_MEMORY_SIZE 1024 * 1024 * 64
|
|
||||||
|
|
||||||
// // https://github.com/sdpetrides/BuddyAllocator
|
|
||||||
|
|
||||||
// // char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
|
|
||||||
// // return 1;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // void * memMalloc(const size_t memoryToAllocate) {
|
|
||||||
// // return NULL;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// typedef struct meta {
|
|
||||||
// unsigned char allo : 1; // 0000000_ - allocated
|
|
||||||
// unsigned char left : 1; // 000000_0 - first or second
|
|
||||||
// unsigned char size : 6; // ______00 - n where (2^n)-1 is the block size
|
|
||||||
// } Meta;
|
|
||||||
|
|
||||||
// // static char myblock[MANAGED_MEMORY_SIZE];
|
|
||||||
// static char *myblock;
|
|
||||||
// void initMemoryManager(void * managedMemory) {
|
|
||||||
// myblock = managedMemory;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void unpack(Meta * m, int pos);
|
|
||||||
|
|
||||||
// /* Fills myblock with zeros and creates first metadata */
|
|
||||||
// void init_block() {
|
|
||||||
// memset(&myblock, '\0', MANAGED_MEMORY_SIZE);
|
|
||||||
// memset(&myblock, 54, 1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Returns log base 2 of a double d */
|
|
||||||
// double log2(double d) {
|
|
||||||
// return log(d) / log(2);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Returns the level a reqSize will fit in */
|
|
||||||
// int size_to_n(size_t reqSize) {
|
|
||||||
// reqSize+=1;
|
|
||||||
// double d = log2((double)reqSize);
|
|
||||||
// return (int)ceil(d);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Returns the position of the next block of the correct size */
|
|
||||||
// int jump_next(int n, int pos) {
|
|
||||||
// int bits = pos>>(n);
|
|
||||||
// bits+=1;
|
|
||||||
// int ret = bits<<(n);
|
|
||||||
|
|
||||||
// if (ret == MANAGED_MEMORY_SIZE) {
|
|
||||||
// return ret;
|
|
||||||
// } else {
|
|
||||||
// return ret;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Returns the position of the left half of a pair */
|
|
||||||
// int jump_back(int n, int pos) {
|
|
||||||
// int bits = pos>>(n);
|
|
||||||
// bits-=1;
|
|
||||||
// return bits<<(n);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Fills a Meta struct with metadata at pos */
|
|
||||||
// void unpack(Meta * m, int pos) {
|
|
||||||
// memset(m, myblock[pos], 1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Returns whether position at level n is left or right partner */
|
|
||||||
// int is_left(int n, int pos) {
|
|
||||||
|
|
||||||
// // Manipulate bits to set nth bit on
|
|
||||||
// int k = 1;
|
|
||||||
// k<<=(n);
|
|
||||||
|
|
||||||
// // Manipulate bits to zero bits above n
|
|
||||||
// unsigned int p = (unsigned int)pos;
|
|
||||||
// p<<=(31-n);
|
|
||||||
// p>>=(31-n);
|
|
||||||
|
|
||||||
// if (k == p) {
|
|
||||||
// return 0; // Right
|
|
||||||
// } else {
|
|
||||||
// return 1; // Left
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Mergee two unallocated blocks with same size */
|
|
||||||
// void merge(int pos, int pos2, int n) {
|
|
||||||
|
|
||||||
// // Create new meta and set size field
|
|
||||||
// char newMeta = (n+1)<<2;
|
|
||||||
|
|
||||||
// // Set left field
|
|
||||||
// if (is_left(n+1, pos)) {
|
|
||||||
// newMeta+=2;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Add new meta
|
|
||||||
// myblock[pos] = newMeta;
|
|
||||||
|
|
||||||
// // Delete meta on right partner
|
|
||||||
// myblock[pos2] = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* MYmymalloc */
|
|
||||||
// void * mymalloc(size_t reqSize) {
|
|
||||||
|
|
||||||
// // Check if too big
|
|
||||||
// if (reqSize > MANAGED_MEMORY_SIZE - 1) {
|
|
||||||
// fprintf(stderr, "Error: Requested size too large\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Traverse heap to find block of correct size - algo(n)
|
|
||||||
// int n = size_to_n(reqSize);
|
|
||||||
// int pos = 0;
|
|
||||||
// unsigned char c = 0;
|
|
||||||
// Meta * m = memset(&c, 0, 1);
|
|
||||||
|
|
||||||
// while (pos < MANAGED_MEMORY_SIZE) {
|
|
||||||
// // Read metadata
|
|
||||||
// unpack(m, pos);
|
|
||||||
|
|
||||||
// // Debugging
|
|
||||||
// if (m->size == 0) {
|
|
||||||
// exit(0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (n <= m->size) {
|
|
||||||
// if (m->allo == 1) {
|
|
||||||
// // Jump
|
|
||||||
// pos = jump_next(n, pos);
|
|
||||||
// continue;
|
|
||||||
// } else if (m->size == n) {
|
|
||||||
// // Allocate
|
|
||||||
// myblock[pos]+=1;
|
|
||||||
// pos+=1;
|
|
||||||
// return (void*)((long int)&myblock+pos);
|
|
||||||
// } else {
|
|
||||||
// // Partition
|
|
||||||
|
|
||||||
// // Get partner position
|
|
||||||
// int partner = jump_next((m->size)-1, pos);
|
|
||||||
|
|
||||||
// // Set Left
|
|
||||||
// char meta_1 = 2;
|
|
||||||
// char meta_2 = 0;
|
|
||||||
|
|
||||||
// // Set Size
|
|
||||||
// char s = ((m->size)-1)<<2;
|
|
||||||
// meta_1 = (meta_1 | s);
|
|
||||||
// meta_2 = (meta_2 | s);
|
|
||||||
|
|
||||||
// // Fill in metadata
|
|
||||||
// myblock[pos] = meta_1;
|
|
||||||
// myblock[partner] = meta_2;
|
|
||||||
|
|
||||||
// // Continue on same position with new size of block
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // Jump
|
|
||||||
// pos = jump_next(n, pos);
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fprintf(stderr, "Error: Did not allocate %d\n", pos);
|
|
||||||
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* MYmyfree */
|
|
||||||
// void myfree(void * ptr) {
|
|
||||||
|
|
||||||
// // Error Checking
|
|
||||||
// if (ptr <= (void *)&myblock || ptr > (void *)(&myblock + MANAGED_MEMORY_SIZE)) {
|
|
||||||
// fprintf(stderr, "Error en free\n");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Get position
|
|
||||||
// // int pos = (int)(ptr-(void *)&myblock-1);
|
|
||||||
// int pos = (int)((char *)ptr-(char *)&myblock-1);
|
|
||||||
|
|
||||||
// // Check if valid metadata location
|
|
||||||
// if (pos%2 == 1 || myblock[pos] == 0) {
|
|
||||||
// fprintf(stderr, "Error con metadata\n");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// // Initialize variables for merge
|
|
||||||
// unsigned char c1 = 0;
|
|
||||||
// unsigned char c2 = 0;
|
|
||||||
// Meta * m1 = memset(&c1, 0, 1);
|
|
||||||
// Meta * m2 = memset(&c2, 0, 1);
|
|
||||||
// unpack(m1,pos);
|
|
||||||
|
|
||||||
// // Change allocated field
|
|
||||||
// myblock[pos] = myblock[pos] - 1;
|
|
||||||
|
|
||||||
// while (pos >= 0 && pos <= 8196){
|
|
||||||
// // Read metadata
|
|
||||||
// unpack(m1,pos);
|
|
||||||
|
|
||||||
// if (m1->left) { // Left Partner
|
|
||||||
|
|
||||||
// // Get position of other partner and read metadata
|
|
||||||
// int pos2 = jump_next(m1->size, pos);
|
|
||||||
|
|
||||||
// if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE - 2) {
|
|
||||||
// unpack(m2,pos2);
|
|
||||||
// } else {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Merge or break
|
|
||||||
// if (m2->allo || m2->size != m1->size) {
|
|
||||||
// break;
|
|
||||||
// } else {
|
|
||||||
// merge(pos, pos2, m1->size);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } else { // Right Partner
|
|
||||||
|
|
||||||
// // Get position of other partner and read metadata
|
|
||||||
// int pos2 = jump_back(m2->size,pos);
|
|
||||||
|
|
||||||
// if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE -2) {
|
|
||||||
// unpack(m2,pos2);
|
|
||||||
// } else {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Merge or break
|
|
||||||
// if (m2->allo || m2->size != m1->size) {
|
|
||||||
// break;
|
|
||||||
// } else {
|
|
||||||
// merge(pos2, pos, m1->size);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int rando[20] = {
|
|
||||||
// 56, 73, 2, 8, 76,
|
|
||||||
// 56, 66, 21, 13, 4,
|
|
||||||
// 99, 80, 25, 6, 38,
|
|
||||||
// 10, 64, 12, 32, 71
|
|
||||||
// };
|
|
||||||
|
|
||||||
// /* testA: mymalloc() 1 byte 3000 times, then myfree() the 3000 1 byte pointers one by one */
|
|
||||||
// void testA() {
|
|
||||||
// int i = 0;
|
|
||||||
// char * p[3000];
|
|
||||||
|
|
||||||
// while (i < 3000) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*1);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// i = 0;
|
|
||||||
|
|
||||||
// while (i < 3000) {
|
|
||||||
// myfree(p[i]);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* testB: mymalloc() 1 byte and immediately myfree it 3000 times in a row */
|
|
||||||
// void testB() {
|
|
||||||
// int i = 0;
|
|
||||||
// char * p;
|
|
||||||
|
|
||||||
// while (i < 3000) {
|
|
||||||
// p = (char *)mymalloc(sizeof(char)*1);
|
|
||||||
// myfree(p);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* testC: Randomly choose between a 1 byte mymalloc() or myfree() 6000 times */
|
|
||||||
// void testC() {
|
|
||||||
// int i = 1;
|
|
||||||
// int j = 0;
|
|
||||||
// char * p[6000];
|
|
||||||
|
|
||||||
// p[0] = (char *)mymalloc(sizeof(char)*1);
|
|
||||||
|
|
||||||
// while (i+j < 1000) {
|
|
||||||
|
|
||||||
// if ((i+j)%2 != 0) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*1);
|
|
||||||
// i++;
|
|
||||||
// } else if (p[j] != 0) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// } else {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*1);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (j <= i) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* testD: Randomly choose between a randomly-sized mymalloc() or myfree 6000 times */
|
|
||||||
// void testD() {
|
|
||||||
// int i = 1;
|
|
||||||
// int j = 0;
|
|
||||||
// char * p[6000];
|
|
||||||
|
|
||||||
// p[0] = (char *)mymalloc(sizeof(char)*(20));
|
|
||||||
|
|
||||||
// while (i+j < 6000) {
|
|
||||||
|
|
||||||
// if ((i+j)%2 != 0) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20));
|
|
||||||
// i++;
|
|
||||||
// } else if (p[j] != 0) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// } else {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20));
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (j <= i) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* testE: mymalloc 100 2bytes and myfrees 100 2bytes 10 times */
|
|
||||||
// void testE() {
|
|
||||||
// int i = 0;
|
|
||||||
// int j = 0;
|
|
||||||
// int k = 0;
|
|
||||||
// int m = 0;
|
|
||||||
// char * p[6000];
|
|
||||||
|
|
||||||
// while (i < 6000) {
|
|
||||||
// k = 0;
|
|
||||||
// while (k < 100) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*(2));
|
|
||||||
// i++; k++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// m = 0;
|
|
||||||
// while (m < 100) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++; m++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* testF: mymalloc 2000 2bytes, myfrees 1000 2bytes, mymalloc 2000 2bytes, myfrees 3000 2bytes */
|
|
||||||
// void testF() {
|
|
||||||
// int i = 0;
|
|
||||||
// int j = 0;
|
|
||||||
// char * p[6000];
|
|
||||||
|
|
||||||
|
|
||||||
// while (i < 2000) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*(2));
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (j < 1000) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (i < 2000) {
|
|
||||||
// p[i] = (char *)mymalloc(sizeof(char)*(2));
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while (j < 4000) {
|
|
||||||
// myfree(p[j]);
|
|
||||||
// j++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// int main(int argc, char const *argv[]) {
|
|
||||||
|
|
||||||
// // Inititialize variables for workflow
|
|
||||||
// int i, j;
|
|
||||||
|
|
||||||
// // Loop through fptr array
|
|
||||||
// for (j = 0; j < 6; j++) {
|
|
||||||
|
|
||||||
// // Initialize time elapsed
|
|
||||||
// double time_elapsed_in_seconds = 0.0;
|
|
||||||
|
|
||||||
// // Run the fuction 100 times and calculate total time elapsed
|
|
||||||
// for (i = 0; i < 100; i++) {
|
|
||||||
|
|
||||||
// // Initialize myblock
|
|
||||||
// init_block();
|
|
||||||
|
|
||||||
// clock_t start = clock();
|
|
||||||
// switch(j) {
|
|
||||||
// case 0:
|
|
||||||
// testA();
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// testB();
|
|
||||||
// break;
|
|
||||||
// case 2:
|
|
||||||
// testC();
|
|
||||||
// break;
|
|
||||||
// case 3:
|
|
||||||
// testD();
|
|
||||||
// break;
|
|
||||||
// case 4:
|
|
||||||
// testE();
|
|
||||||
// break;
|
|
||||||
// case 5:
|
|
||||||
// testF();
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// clock_t end = clock();
|
|
||||||
// time_elapsed_in_seconds+=(end - start)/(double)CLOCKS_PER_SEC;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Print the after execution time of 100 runs
|
|
||||||
// printf("Time Elapsed test%d: %f secs\n", j, time_elapsed_in_seconds/100);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #endif
|
|
|
@ -0,0 +1,268 @@
|
||||||
|
#ifdef BUDDY
|
||||||
|
// #include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
// #include <time.h>
|
||||||
|
// #include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define MANAGED_MEMORY_SIZE 1024
|
||||||
|
|
||||||
|
// https://github.com/sdpetrides/BuddyAllocator
|
||||||
|
|
||||||
|
// char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void * memMalloc(const size_t memoryToAllocate) {
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
|
||||||
|
typedef struct meta {
|
||||||
|
unsigned char allo : 1; // 0000000_ - allocated
|
||||||
|
unsigned char left : 1; // 000000_0 - first or second
|
||||||
|
unsigned char size : 6; // ______00 - n where (2^n)-1 is the block size
|
||||||
|
} Meta;
|
||||||
|
|
||||||
|
// static char myblock[MANAGED_MEMORY_SIZE];
|
||||||
|
static char *myblock;
|
||||||
|
void initMemoryManager(void * managedMemory) {
|
||||||
|
myblock = managedMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpack(Meta * m, int pos);
|
||||||
|
|
||||||
|
/* Fills myblock with zeros and creates first metadata */
|
||||||
|
void init_block() {
|
||||||
|
memset(&myblock, '\0', MANAGED_MEMORY_SIZE);
|
||||||
|
memset(&myblock, 54, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ceil(float num) {
|
||||||
|
int inum = (int)num;
|
||||||
|
if (num == (float)inum) {
|
||||||
|
return inum;
|
||||||
|
}
|
||||||
|
return inum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsigned int log2(unsigned int n)
|
||||||
|
// {
|
||||||
|
// return (n > 1) ? 1 + log2(n / 2) : 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Returns log base 2 of a double d */
|
||||||
|
// double log2(double d) {
|
||||||
|
// return log(d) / log(2);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/* Returns the level a reqSize will fit in */
|
||||||
|
int size_to_n(size_t reqSize) {
|
||||||
|
reqSize+=1;
|
||||||
|
double d = log2((double)reqSize);
|
||||||
|
return (int)ceil(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the position of the next block of the correct size */
|
||||||
|
int jump_next(int n, int pos) {
|
||||||
|
int bits = pos>>(n);
|
||||||
|
bits+=1;
|
||||||
|
int ret = bits<<(n);
|
||||||
|
|
||||||
|
if (ret == MANAGED_MEMORY_SIZE) {
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the position of the left half of a pair */
|
||||||
|
int jump_back(int n, int pos) {
|
||||||
|
int bits = pos>>(n);
|
||||||
|
bits-=1;
|
||||||
|
return bits<<(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fills a Meta struct with metadata at pos */
|
||||||
|
void unpack(Meta * m, int pos) {
|
||||||
|
memset(m, myblock[pos], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns whether position at level n is left or right partner */
|
||||||
|
int is_left(int n, int pos) {
|
||||||
|
|
||||||
|
// Manipulate bits to set nth bit on
|
||||||
|
int k = 1;
|
||||||
|
k<<=(n);
|
||||||
|
|
||||||
|
// Manipulate bits to zero bits above n
|
||||||
|
unsigned int p = (unsigned int)pos;
|
||||||
|
p<<=(31-n);
|
||||||
|
p>>=(31-n);
|
||||||
|
|
||||||
|
if (k == p) {
|
||||||
|
return 0; // Right
|
||||||
|
} else {
|
||||||
|
return 1; // Left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mergee two unallocated blocks with same size */
|
||||||
|
void merge(int pos, int pos2, int n) {
|
||||||
|
|
||||||
|
// Create new meta and set size field
|
||||||
|
char newMeta = (n+1)<<2;
|
||||||
|
|
||||||
|
// Set left field
|
||||||
|
if (is_left(n+1, pos)) {
|
||||||
|
newMeta+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new meta
|
||||||
|
myblock[pos] = newMeta;
|
||||||
|
|
||||||
|
// Delete meta on right partner
|
||||||
|
myblock[pos2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MYmymalloc */
|
||||||
|
void * pvPortMalloc(size_t reqSize) {
|
||||||
|
|
||||||
|
// Check if too big
|
||||||
|
if (reqSize > MANAGED_MEMORY_SIZE - 1) {
|
||||||
|
// fprintf(stderr, "Error: Requested size too large\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse heap to find block of correct size - algo(n)
|
||||||
|
int n = size_to_n(reqSize);
|
||||||
|
int pos = 0;
|
||||||
|
unsigned char c = 0;
|
||||||
|
Meta * m = memset(&c, 0, 1);
|
||||||
|
|
||||||
|
while (pos < MANAGED_MEMORY_SIZE) {
|
||||||
|
// Read metadata
|
||||||
|
unpack(m, pos);
|
||||||
|
|
||||||
|
// // Debugging
|
||||||
|
// if (m->size == 0) {
|
||||||
|
// exit(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (n <= m->size) {
|
||||||
|
if (m->allo == 1) {
|
||||||
|
// Jump
|
||||||
|
pos = jump_next(n, pos);
|
||||||
|
continue;
|
||||||
|
} else if (m->size == n) {
|
||||||
|
// Allocate
|
||||||
|
myblock[pos]+=1;
|
||||||
|
pos+=1;
|
||||||
|
return (void*)((long int)&myblock+pos);
|
||||||
|
} else {
|
||||||
|
// Partition
|
||||||
|
|
||||||
|
// Get partner position
|
||||||
|
int partner = jump_next((m->size)-1, pos);
|
||||||
|
|
||||||
|
// Set Left
|
||||||
|
char meta_1 = 2;
|
||||||
|
char meta_2 = 0;
|
||||||
|
|
||||||
|
// Set Size
|
||||||
|
char s = ((m->size)-1)<<2;
|
||||||
|
meta_1 = (meta_1 | s);
|
||||||
|
meta_2 = (meta_2 | s);
|
||||||
|
|
||||||
|
// Fill in metadata
|
||||||
|
myblock[pos] = meta_1;
|
||||||
|
myblock[partner] = meta_2;
|
||||||
|
|
||||||
|
// Continue on same position with new size of block
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Jump
|
||||||
|
pos = jump_next(n, pos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//error
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MYmyfree */
|
||||||
|
void vPortFree(void * ptr) {
|
||||||
|
|
||||||
|
// Error Checking
|
||||||
|
if (ptr <= (void *)&myblock || ptr > (void *)(&myblock + MANAGED_MEMORY_SIZE)) {
|
||||||
|
//error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get position
|
||||||
|
// int pos = (int)(ptr-(void *)&myblock-1);
|
||||||
|
int pos = (int)((char *)ptr-(char *)&myblock-1);
|
||||||
|
|
||||||
|
// Check if valid metadata location
|
||||||
|
if (pos%2 == 1 || myblock[pos] == 0) {
|
||||||
|
//error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize variables for merge
|
||||||
|
unsigned char c1 = 0;
|
||||||
|
unsigned char c2 = 0;
|
||||||
|
Meta * m1 = memset(&c1, 0, 1);
|
||||||
|
Meta * m2 = memset(&c2, 0, 1);
|
||||||
|
unpack(m1,pos);
|
||||||
|
|
||||||
|
// Change allocated field
|
||||||
|
myblock[pos] = myblock[pos] - 1;
|
||||||
|
|
||||||
|
while (pos >= 0 && pos <= 8196){
|
||||||
|
// Read metadata
|
||||||
|
unpack(m1,pos);
|
||||||
|
|
||||||
|
if (m1->left) { // Left Partner
|
||||||
|
|
||||||
|
// Get position of other partner and read metadata
|
||||||
|
int pos2 = jump_next(m1->size, pos);
|
||||||
|
|
||||||
|
if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE - 2) {
|
||||||
|
unpack(m2,pos2);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge or break
|
||||||
|
if (m2->allo || m2->size != m1->size) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
merge(pos, pos2, m1->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // Right Partner
|
||||||
|
|
||||||
|
// Get position of other partner and read metadata
|
||||||
|
int pos2 = jump_back(m2->size,pos);
|
||||||
|
|
||||||
|
if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE -2) {
|
||||||
|
unpack(m2,pos2);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge or break
|
||||||
|
if (m2->allo || m2->size != m1->size) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
merge(pos2, pos, m1->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue