Add tests and FRT4

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
This commit is contained in:
Santiago Lo Coco 2021-10-17 11:13:48 -03:00
parent 31ea74f515
commit 73a01944a4
10 changed files with 1570 additions and 951 deletions

View File

@ -3,13 +3,19 @@
#include <stdlib.h>
typedef struct MemoryManagerCDT * MemoryManagerADT;
// typedef struct MemoryManagerCDT * MemoryManagerADT;
// MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory);
// void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate);
char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory);
void * memMalloc(const size_t memoryToAllocate);
// char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory);
void initMemoryManager(void * managedMemory);
void * memMalloc(unsigned nbytes);
void memFree(void *ap);
// void * memMalloc(const size_t memoryToAllocate);
void * pvPortMalloc(size_t xWantedSize);
void vPortFree( void *pv );
size_t xPortGetFreeHeapSize( void );
// SACAR DPS
char testOne();

View File

@ -52,28 +52,114 @@ void load_idt();
uint64_t getRSP();
void printBottlerAndWait();
#include "test_util.h"
#define MAX_BLOCKS 42//1024/24 //128
#define MAX_MEMORY 352//1024-42x16 //Should be around 80% of memory managed by the MM
typedef struct MM_rq{
void *address;
uint32_t size;
}mm_rq;
void test_mm(){
mm_rq mm_rqs[MAX_BLOCKS];
uint8_t rq;
uint32_t total;
// int i = 6;
// while (i-- != 0){
while (1){
rq = 0;
total = 0;
// Request as many blocks as we can
while(rq < MAX_BLOCKS && total < MAX_MEMORY){
mm_rqs[rq].size = GetUniform(MAX_MEMORY - total - 1) + 1;
mm_rqs[rq].address = pvPortMalloc(mm_rqs[rq].size);
// mm_rqs[rq].address = memMalloc(mm_rqs[rq].size);
if (mm_rqs[rq].address == NULL) {
for (int rqAux = 0; rqAux < rq; rqAux++) {
ncPrintDec(mm_rqs[rqAux].size );
ncPrint(" - ");
}
// printStringLen(13, "malloc() -- ERROR", 20);
// new_line();
ncPrint("Malloc -- null");
ncNewline();
}
total += mm_rqs[rq].size;
rq++;
}
// ncPrint("libre dps de malloc: ");
// ncPrintDec(xPortGetFreeHeapSize());
// ncNewline();
// ncPrint("cumpli maximo");
// ncNewline();
// Set
uint32_t i;
for (i = 0; i < rq; i++)
if (mm_rqs[i].address != NULL)
memset(mm_rqs[i].address, i, mm_rqs[i].size);
// Check
for (i = 0; i < rq; i++)
if (mm_rqs[i].address != NULL)
if(!memcheck(mm_rqs[i].address, i, mm_rqs[i].size)) {
// printStringLen(13, "memCheck() -- ERROR", 20);
// new_line();
ncPrint("memCheck -- null");
ncNewline();
}
// Free
for (i = 0; i < rq; i++) {
if (mm_rqs[i].address != NULL)
vPortFree(mm_rqs[i].address);
}
// memFree(mm_rqs[i].address);
// ncPrint("libre dps de free: ");
// ncPrintDec(xPortGetFreeHeapSize());
// ncNewline();
// ncPrint("termine un loop regio");
// ncNewline();
// if (i == 5)
// wait(3);
// ncClear();
// printStringLen(13, "ALL GOOD", 9);
// new_line();
}
}
int main() {
load_idt();
if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
printStringLen(13, "createMemoryManager() -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
// if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
// printStringLen(13, "createMemoryManager() -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
initMemoryManager(memoryModuleAddress);
#ifndef BUDDY
// SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO!
if (testOne() == EXIT_FAILURE)
return EXIT_FAILURE;
// if (testOne() == EXIT_FAILURE)
// return EXIT_FAILURE;
// if (testTwo() == EXIT_FAILURE)
// return EXIT_FAILURE;
test_mm();
#endif
saveSampleRSP(getRSP());
printBottlerAndWait();
// printBottlerAndWait();
((EntryPoint)sampleCodeModuleAddress)();
// ((EntryPoint)sampleCodeModuleAddress)();
return EXIT_SUCCESS;
}

View File

@ -1,460 +1,460 @@
// #ifdef BUDDY
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#define MANAGED_MEMORY_SIZE 1024 * 1024 * 64
// #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
// // https://github.com/sdpetrides/BuddyAllocator
// char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
// return 1;
// // 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 * memMalloc(const size_t memoryToAllocate) {
// return NULL;
// 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);
// }
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;
// /* Returns log base 2 of a double d */
// double log2(double d) {
// return log(d) / log(2);
// }
// static char myblock[MANAGED_MEMORY_SIZE];
static char *myblock;
void initMemoryManager(void * managedMemory) {
myblock = managedMemory;
}
// /* 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);
// }
void unpack(Meta * m, int pos);
// /* 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);
/* 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;
}
// 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);
}
// /* 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);
}
// /* 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) {
// /* 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 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);
// // 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
}
}
// 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) {
// /* 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;
// // Create new meta and set size field
// char newMeta = (n+1)<<2;
// Set left field
if (is_left(n+1, pos)) {
newMeta+=2;
}
// // Set left field
// if (is_left(n+1, pos)) {
// newMeta+=2;
// }
// Add new meta
myblock[pos] = newMeta;
// // Add new meta
// myblock[pos] = newMeta;
// Delete meta on right partner
myblock[pos2] = 0;
}
// // Delete meta on right partner
// myblock[pos2] = 0;
// }
/* MYmymalloc */
void * mymalloc(size_t reqSize) {
// /* MYmymalloc */
// void * mymalloc(size_t reqSize) {
// Check if too big
if (reqSize > MANAGED_MEMORY_SIZE - 1) {
fprintf(stderr, "Error: Requested size too large\n");
}
// // 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);
// // 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);
// while (pos < MANAGED_MEMORY_SIZE) {
// // Read metadata
// unpack(m, pos);
// Debugging
if (m->size == 0) {
exit(0);
}
// // 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
// 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);
// // Get partner position
// int partner = jump_next((m->size)-1, pos);
// Set Left
char meta_1 = 2;
char meta_2 = 0;
// // 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);
// // 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;
// // 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;
}
}
// // 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);
// fprintf(stderr, "Error: Did not allocate %d\n", pos);
return 0;
}
// return 0;
// }
/* MYmyfree */
void myfree(void * ptr) {
// /* MYmyfree */
// void myfree(void * ptr) {
// Error Checking
if (ptr <= (void *)&myblock || ptr > (void *)(&myblock + MANAGED_MEMORY_SIZE)) {
fprintf(stderr, "Error en free\n");
return;
}
// // 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);
// // 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;
}
// // 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);
// // 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;
// // Change allocated field
// myblock[pos] = myblock[pos] - 1;
while (pos >= 0 && pos <= 8196){
// Read metadata
unpack(m1,pos);
// while (pos >= 0 && pos <= 8196){
// // Read metadata
// unpack(m1,pos);
if (m1->left) { // Left Partner
// if (m1->left) { // Left Partner
// Get position of other partner and read metadata
int pos2 = jump_next(m1->size, pos);
// // 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;
}
// 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);
}
// // Merge or break
// if (m2->allo || m2->size != m1->size) {
// break;
// } else {
// merge(pos, pos2, m1->size);
// }
} else { // Right Partner
// } else { // Right Partner
// Get position of other partner and read metadata
int pos2 = jump_back(m2->size,pos);
// // 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;
}
// 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);
}
}
}
}
// // 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
};
// 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];
// /* 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++;
}
// while (i < 3000) {
// p[i] = (char *)mymalloc(sizeof(char)*1);
// i++;
// }
i = 0;
// i = 0;
while (i < 3000) {
myfree(p[i]);
i++;
}
// while (i < 3000) {
// myfree(p[i]);
// i++;
// }
return;
}
// return;
// }
/* testB: mymalloc() 1 byte and immediately myfree it 3000 times in a row */
void testB() {
int i = 0;
char * p;
// /* 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++;
}
// while (i < 3000) {
// p = (char *)mymalloc(sizeof(char)*1);
// myfree(p);
// i++;
// }
return;
}
// return;
// }
/* testC: Randomly choose between a 1 byte mymalloc() or myfree() 6000 times */
void testC() {
int i = 1;
int j = 0;
char * p[6000];
// /* 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);
// p[0] = (char *)mymalloc(sizeof(char)*1);
while (i+j < 1000) {
// 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++;
}
}
// 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++;
}
// while (j <= i) {
// myfree(p[j]);
// j++;
// }
return;
}
// return;
// }
/* testD: Randomly choose between a randomly-sized mymalloc() or myfree 6000 times */
void testD() {
int i = 1;
int j = 0;
char * p[6000];
// /* 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));
// p[0] = (char *)mymalloc(sizeof(char)*(20));
while (i+j < 6000) {
// 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++;
}
}
// 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++;
}
// while (j <= i) {
// myfree(p[j]);
// j++;
// }
return;
}
// 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];
// /* 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++;
}
// 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++;
}
}
// m = 0;
// while (m < 100) {
// myfree(p[j]);
// j++; m++;
// }
// }
return;
}
// 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];
// /* 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 (i < 2000) {
// p[i] = (char *)mymalloc(sizeof(char)*(2));
// i++;
// }
while (j < 1000) {
myfree(p[j]);
j++;
}
// while (j < 1000) {
// myfree(p[j]);
// j++;
// }
while (i < 2000) {
p[i] = (char *)mymalloc(sizeof(char)*(2));
i++;
}
// while (i < 2000) {
// p[i] = (char *)mymalloc(sizeof(char)*(2));
// i++;
// }
while (j < 4000) {
myfree(p[j]);
j++;
}
// while (j < 4000) {
// myfree(p[j]);
// j++;
// }
return;
}
// return;
// }
int main(int argc, char const *argv[]) {
// int main(int argc, char const *argv[]) {
// Inititialize variables for workflow
int i, j;
// // Inititialize variables for workflow
// int i, j;
// Loop through fptr array
for (j = 0; j < 6; j++) {
// // Loop through fptr array
// for (j = 0; j < 6; j++) {
// Initialize time elapsed
double time_elapsed_in_seconds = 0.0;
// // 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++) {
// // Run the fuction 100 times and calculate total time elapsed
// for (i = 0; i < 100; i++) {
// Initialize myblock
init_block();
// // 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;
}
// 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);
}
// // Print the after execution time of 100 runs
// printf("Time Elapsed test%d: %f secs\n", j, time_elapsed_in_seconds/100);
// }
return 0;
}
// return 0;
// }
// #endif

View File

@ -1,320 +1,339 @@
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
// #ifndef BUDDY
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
// #include <stdlib.h>
// #include <stdint.h>
// #include <assert.h>
// #include <string.h>
// #include <naiveConsole.h>
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
// #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
// #define portCHAR char
// #define portFLOAT float
// #define portDOUBLE double
// #define portLONG long
// #define portSHORT short
// #define portSTACK_TYPE uint32_t
// #define portBASE_TYPE long
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE 1024
#define configAPPLICATION_ALLOCATED_HEAP 0
#define portBYTE_ALIGNMENT 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) // 8
#define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 )
#define portPOINTER_SIZE_TYPE uint32_t
// typedef portSTACK_TYPE StackType_t;
// typedef long BaseType_t;
// typedef unsigned long UBaseType_t;
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
// #define configSUPPORT_STATIC_ALLOCATION 1
// #define configSUPPORT_DYNAMIC_ALLOCATION 1
// #define configTOTAL_HEAP_SIZE 1024
// #define configAPPLICATION_ALLOCATED_HEAP 0
// #define portBYTE_ALIGNMENT 8
// #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) // 8
// #define pdFALSE ( ( BaseType_t ) 0 )
// #define pdTRUE ( ( BaseType_t ) 1 )
// #define portPOINTER_SIZE_TYPE uint32_t
/*
* Initialises the heap structures before their first use.
*/
static void prvHeapInit(void);
// /* A few bytes might be lost to byte aligning the heap start address. */
// #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/* Allocate the memory for the heap. */
// #if( configAPPLICATION_ALLOCATED_HEAP == 1 )
// /* The application writer has already defined the array used for the RTOS
// heap - probably so it can be placed in a special segment or address. */
// extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// #else
// static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// #endif /* configAPPLICATION_ALLOCATED_HEAP */
// /*
// * Initialises the heap structures before their first use.
// */
// static void prvHeapInit(void);
static uint8_t *ucHeap;
void initMemoryManager(void * managedMemory) {
ucHeap = managedMemory;
}
// /* Allocate the memory for the heap. */
// // #if( configAPPLICATION_ALLOCATED_HEAP == 1 )
// // /* The application writer has already defined the array used for the RTOS
// // heap - probably so it can be placed in a special segment or address. */
// // extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// // #else
// // static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// // #endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Define the linked list structure. This is used to link free blocks in order
of their size. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
// static uint8_t *ucHeap;
// void initMemoryManager(void * managedMemory) {
// ucHeap = managedMemory;
// }
// /* Define the linked list structure. This is used to link free blocks in order
// of their size. */
// typedef struct A_BLOCK_LINK
// {
// struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
// size_t xBlockSize; /*<< The size of the free block. */
// } BlockLink_t;
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
// static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
// #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, xEnd;
// /* Create a couple of list links to mark the start and end of the list. */
// static BlockLink_t xStart, xEnd;
/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
// /* Keeps track of the number of free bytes remaining, but says nothing about
// fragmentation. */
// static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
// /* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
/*
* Insert a block into the list of free blocks - which is ordered by size of
* the block. Small blocks at the start of the list and large blocks at the end
* of the list.
*/
#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
{ \
BlockLink_t *pxIterator; \
size_t xBlockSize; \
\
xBlockSize = pxBlockToInsert->xBlockSize; \
\
/* Iterate through the list until a block is found that has a larger size */ \
/* than the block we are inserting. */ \
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
{ \
/* There is nothing to do here - just iterate to the correct position. */ \
} \
\
/* Update the list to include the block being inserted in the correct */ \
/* position. */ \
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
pxIterator->pxNextFreeBlock = pxBlockToInsert; \
}
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
static BaseType_t xHeapHasBeenInitialised = pdFALSE;
void *pvReturn = NULL;
// /*
// * Insert a block into the list of free blocks - which is ordered by size of
// * the block. Small blocks at the start of the list and large blocks at the end
// * of the list.
// */
// #define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
// { \
// BlockLink_t *pxIterator; \
// size_t xBlockSize; \
// \
// xBlockSize = pxBlockToInsert->xBlockSize; \
// \
// /* Iterate through the list until a block is found that has a larger size */ \
// /* than the block we are inserting. */ \
// for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
// { \
// /* There is nothing to do here - just iterate to the correct position. */ \
// } \
// \
// /* Update the list to include the block being inserted in the correct */ \
// /* position. */ \
// pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
// pxIterator->pxNextFreeBlock = pxBlockToInsert; \
// }
// /*-----------------------------------------------------------*/
// void *pvPortMalloc( size_t xWantedSize )
// {
// BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
// static BaseType_t xHeapHasBeenInitialised = pdFALSE;
// void *pvReturn = NULL;
// // vTaskSuspendAll();
// {
// /* If this is the first call to malloc then the heap will require
// initialisation to setup the list of free blocks. */
// if( xHeapHasBeenInitialised == pdFALSE )
// {
// prvHeapInit();
// xHeapHasBeenInitialised = pdTRUE;
// }
// vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */
if( xHeapHasBeenInitialised == pdFALSE )
{
prvHeapInit();
xHeapHasBeenInitialised = pdTRUE;
}
// /* The wanted size is increased so it can contain a BlockLink_t
// structure in addition to the requested amount of bytes. */
// if( xWantedSize > 0 )
// {
// xWantedSize += heapSTRUCT_SIZE;
/* The wanted size is increased so it can contain a BlockLink_t
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += heapSTRUCT_SIZE;
// /* Ensure that blocks are always aligned to the required number of bytes. */
// if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 )
// {
// /* Byte alignment required. */
// xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
// }
// }
/* Ensure that blocks are always aligned to the required number of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
// ncPrint("MALLOC: ");
// ncPrintDec(xFreeBytesRemaining);
// ncPrint(" ");
// ncPrintDec(xWantedSize);
// ncPrint(" ");
// ncPrintDec(configADJUSTED_HEAP_SIZE);
// ncPrint(" ---- ");
// if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
// {
// /* Blocks are stored in byte order - traverse the list from the start
// (smallest) block until one of adequate size is found. */
// pxPreviousBlock = &xStart;
// pxBlock = xStart.pxNextFreeBlock;
// while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
// {
// pxPreviousBlock = pxBlock;
// ncPrintDec(pxBlock->xBlockSize);
// ncPrint(" - ");
// pxBlock = pxBlock->pxNextFreeBlock;
// }
if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
{
/* Blocks are stored in byte order - traverse the list from the start
(smallest) block until one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
// /* If we found the end marker then a block of adequate size was not found. */
// if( pxBlock != &xEnd )
// {
// /* Return the memory space - jumping over the BlockLink_t structure
// at its start. */
// pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
/* If we found the end marker then a block of adequate size was not found. */
if( pxBlock != &xEnd )
{
/* Return the memory space - jumping over the BlockLink_t structure
at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
// /* This block is being returned for use so must be taken out of the
// list of free blocks. */
// pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* This block is being returned for use so must be taken out of the
list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
// /* If the block is larger than required it can be split into two. */
// if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
// {
// /* This block is to be split into two. Create a new block
// following the number of bytes requested. The void cast is
// used to prevent byte alignment warnings from the compiler. */
// pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
/* If the block is larger than required it can be split into two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new block
following the number of bytes requested. The void cast is
used to prevent byte alignment warnings from the compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
// /* Calculate the sizes of two blocks split from the single
// block. */
// pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
// pxBlock->xBlockSize = xWantedSize;
/* Calculate the sizes of two blocks split from the single
block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
// /* Insert the new block into the list of free blocks. */
// prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
// }
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
// }
// // tengo 16 de info y de alineamiento 8!
// ncPrint("Dentro: ");
// ncPrintDec(xFreeBytesRemaining);
// ncPrint(" y ");
// xFreeBytesRemaining -= pxBlock->xBlockSize;
// ncPrintDec(xFreeBytesRemaining);
// ncNewline();
// }
xFreeBytesRemaining -= pxBlock->xBlockSize;
}
}
// // traceMALLOC( pvReturn, xWantedSize );
// }
// // ( void ) xTaskResumeAll();
// traceMALLOC( pvReturn, xWantedSize );
}
// ( void ) xTaskResumeAll();
// // #if( configUSE_MALLOC_FAILED_HOOK == 1 )
// // {
// // if( pvReturn == NULL )
// // {
// // extern void vApplicationMallocFailedHook( void );
// // vApplicationMallocFailedHook();
// // }
// // }
// // #endif
// #if( configUSE_MALLOC_FAILED_HOOK == 1 )
// {
// if( pvReturn == NULL )
// {
// extern void vApplicationMallocFailedHook( void );
// vApplicationMallocFailedHook();
// }
// }
// #endif
// return pvReturn;
// }
// /*-----------------------------------------------------------*/
return pvReturn;
}
/*-----------------------------------------------------------*/
// void vPortFree( void *pv )
// {
// uint8_t *puc = ( uint8_t * ) pv;
// BlockLink_t *pxLink;
void vPortFree( void *pv )
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
// if( pv != NULL )
// {
// /* The memory being freed will have an BlockLink_t structure immediately
// before it. */
// puc -= heapSTRUCT_SIZE;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
puc -= heapSTRUCT_SIZE;
// /* This unexpected casting is to keep some compilers from issuing
// byte alignment warnings. */
// pxLink = ( void * ) puc;
/* This unexpected casting is to keep some compilers from issuing
byte alignment warnings. */
pxLink = ( void * ) puc;
// // vTaskSuspendAll();
// {
// /* Add this block to the list of free blocks. */
// prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
// xFreeBytesRemaining += pxLink->xBlockSize;
// // traceFREE( pv, pxLink->xBlockSize );
// }
// // ( void ) xTaskResumeAll();
// }
// }
// /*-----------------------------------------------------------*/
// vTaskSuspendAll();
{
/* Add this block to the list of free blocks. */
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
xFreeBytesRemaining += pxLink->xBlockSize;
// traceFREE( pv, pxLink->xBlockSize );
}
// ( void ) xTaskResumeAll();
}
}
/*-----------------------------------------------------------*/
// size_t xPortGetFreeHeapSize( void )
// {
// return xFreeBytesRemaining;
// }
// /*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
// void vPortInitialiseBlocks( void )
// {
// /* This just exists to keep the linker quiet. */
// }
// /*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/
// static void prvHeapInit( void )
// {
// BlockLink_t *pxFirstFreeBlock;
// uint8_t *pucAlignedHeap;
static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;
// /* Ensure the heap starts on a correctly aligned boundary. */
// pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
// /* xStart is used to hold a pointer to the first item in the list of free
// blocks. The void cast is used to prevent compiler warnings. */
// xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
// xStart.xBlockSize = ( size_t ) 0;
/* xStart is used to hold a pointer to the first item in the list of free
blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
// /* xEnd is used to mark the end of the list of free blocks. */
// xEnd.xBlockSize = configADJUSTED_HEAP_SIZE;
// xEnd.pxNextFreeBlock = NULL;
/* xEnd is used to mark the end of the list of free blocks. */
xEnd.xBlockSize = configADJUSTED_HEAP_SIZE;
xEnd.pxNextFreeBlock = NULL;
// /* To start with there is a single free block that is sized to take up the
// entire heap space. */
// pxFirstFreeBlock = ( void * ) pucAlignedHeap;
// pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE;
// pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
// }
// /*-----------------------------------------------------------*/
/* To start with there is a single free block that is sized to take up the
entire heap space. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE;
pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
}
/*-----------------------------------------------------------*/
// // #endif /* #ifdef configHEAP_ALLOCATION_SCHEME */
// // #endif /* #if(configHEAP_ALLOCATION_SCHEME == HEAP_ALLOCATION_TYPE1) */
// #endif /* #ifdef configHEAP_ALLOCATION_SCHEME */
// #endif /* #if(configHEAP_ALLOCATION_SCHEME == HEAP_ALLOCATION_TYPE1) */
// // char testOne() {
// // void * alloc1 = pvPortMalloc(100);
// // void * alloc2 = pvPortMalloc(200);
// // void * alloc3 = pvPortMalloc(300);
char testOne() {
void * alloc1 = pvPortMalloc(100);
void * alloc2 = pvPortMalloc(200);
void * alloc3 = pvPortMalloc(300);
// // memset(alloc1, 1, 100);
// // memset(alloc2, 2, 200);
// // memset(alloc3, 3, 300);
memset(alloc1, 1, 100);
memset(alloc2, 2, 200);
memset(alloc3, 3, 300);
// // for (int i = 0; i < 600; i++) {
// // if (i < 100) {
// // assert(*((char *) alloc1+i) == 1);
// // } else if (i < 300) {
// // assert(*((char *) alloc2+i-100) == 2);
// // } else if (i < 600) {
// // assert(*((char *) alloc3+i-300) == 3);
// // }
// // }
for (int i = 0; i < 600; i++) {
if (i < 100) {
assert(*((char *) alloc1+i) == 1);
} else if (i < 300) {
assert(*((char *) alloc2+i-100) == 2);
} else if (i < 600) {
assert(*((char *) alloc3+i-300) == 3);
}
}
// // return EXIT_SUCCESS;
// // }
return EXIT_SUCCESS;
}
// // static unsigned long int next = 1;
// // int rand(void) // RAND_MAX assumed to be 32767
// // {
// // next = next * 1103515245 + 12345;
// // return (unsigned int)(next/65536) % 32768;
// // }
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
// /*
// char testTwo() {
// void * ptr;
// while (ptr != NULL){
// ptr = memMalloc((rand() % 2000) + 1);
// if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
// printStringLen(13, "allocRand1 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// printStringLen(13, "allocRand2 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// // if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// // }
// // if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// // }
// }
/*
char testTwo() {
void * ptr;
while (ptr != NULL){
ptr = memMalloc((rand() % 2000) + 1);
if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
printStringLen(13, "allocRand1 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
printStringLen(13, "allocRand2 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
// if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// }
// if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// }
}
// return EXIT_SUCCESS;
return EXIT_SUCCESS;
// }
// */
}
*/
// // char mem[1024];
// char mem[1024];
// // int main() {
// // // initMemoryManager(mem);
// // if (testOne() == EXIT_FAILURE)
// // return EXIT_FAILURE;
// // // if (testTwo() == EXIT_FAILURE)
// // // return EXIT_FAILURE;
// // }
int main() {
// initMemoryManager(mem);
if (testOne() == EXIT_FAILURE)
return EXIT_FAILURE;
// if (testTwo() == EXIT_FAILURE)
// return EXIT_FAILURE;
}
// #endif

418
Kernel/memManagerFRT4.c Normal file
View File

@ -0,0 +1,418 @@
#ifndef BUDDY
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
#include <naiveConsole.h>
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE 1024
#define configAPPLICATION_ALLOCATED_HEAP 0
#define portBYTE_ALIGNMENT 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) // 8
#define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 )
#define portPOINTER_SIZE_TYPE uint32_t
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
static uint8_t *ucHeap;
void initMemoryManager(void * managedMemory) {
ucHeap = managedMemory;
}
/* Definition of the Heap_stats_t structure. */
typedef struct xHeapStats
{
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
} HeapStats_t;
/* Prototype of the vPortGetHeapStats() function. */
void vPortGetHeapStats( HeapStats_t *xHeapStats );
/*-----------------------------------------------------------*/
/*
* Inserts a block of memory that is being freed into the correct position in
* the list of free memory blocks. The block being freed will be merged with
* the block in front it and/or the block behind it if the memory blocks are
* adjacent to each other.
*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
/*
* Called automatically to setup the required heap structures the first time
* pvPortMalloc() is called.
*/
static void prvHeapInit( void );
/*-----------------------------------------------------------*/
/* The size of the structure placed at the beginning of each allocated memory
block must by correctly byte aligned. */
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL;
/* Keeps track of the number of calls to allocate and free memory as well as the
number of free bytes remaining, but says nothing about fragmentation. */
static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U;
static size_t xNumberOfSuccessfulAllocations = 0;
static size_t xNumberOfSuccessfulFrees = 0;
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the
application. When the bit is free the block is still part of the free heap
space. */
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
/* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
{
prvHeapInit();
}
/* Check the requested block size is not so large that the top bit is
set. The top bit of the block size member of the BlockLink_t structure
is used to determine who owns the block - the application or the
kernel, so it must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
/* The wanted size is increased so it can contain a BlockLink_t
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
// configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 );
}
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the end marker was reached then a block of adequate size
was not found. */
if( pxBlock != pxEnd )
{
/* Return the memory space pointed to - jumping over the
BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out
of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into
two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new
block following the number of bytes requested. The void
cast is used to prevent byte alignment warnings from the
compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
// configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the
single block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( pxNewBlockLink );
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
/* The block is being returned - it is allocated and owned
by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
xNumberOfSuccessfulAllocations++;
}
}
else {
ncNewline();
ncPrint("MALLOC: ");
ncPrintDec(xFreeBytesRemaining);
ncPrint(" ");
ncPrintDec(xWantedSize);
ncPrint(" ");
ncPrintDec(configADJUSTED_HEAP_SIZE);
ncNewline();
}
}
// configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
before it. */
puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
/* Check the block is actually allocated. */
// configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
// configASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
/* The block is being returned to the heap - it is no longer
allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
xNumberOfSuccessfulFrees++;
}
}
}
}
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/
static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;
size_t uxAddress;
size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */
uxAddress = ( size_t ) ucHeap;
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{
uxAddress += ( portBYTE_ALIGNMENT - 1 );
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
}
pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free
blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted
at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
{
BlockLink_t *pxIterator;
uint8_t *puc;
/* Iterate through the list until a block is found that has a higher address
than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after
make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
/* Do the block being inserted, and the block it is being inserted before
make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
/* If the block being inserted plugged a gab, so was merged with the block
before and the block after, then it's pxNextFreeBlock pointer will have
already been set, and should not be set here as that would make it point
to itself. */
if( pxIterator != pxBlockToInsert )
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
}
/*-----------------------------------------------------------*/
void vPortGetHeapStats( HeapStats_t *pxHeapStats )
{
BlockLink_t *pxBlock;
size_t xBlocks = 0, xMaxSize = 0, xMinSize = configTOTAL_HEAP_SIZE;//portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
pxBlock = xStart.pxNextFreeBlock;
/* pxBlock will be NULL if the heap has not been initialised. The heap
is initialised automatically when the first allocation is made. */
if( pxBlock != NULL )
{
do
{
/* Increment the number of blocks and record the largest block seen
so far. */
xBlocks++;
if( pxBlock->xBlockSize > xMaxSize )
{
xMaxSize = pxBlock->xBlockSize;
}
if( pxBlock->xBlockSize < xMinSize )
{
xMinSize = pxBlock->xBlockSize;
}
/* Move to the next block in the chain until the last block is
reached. */
pxBlock = pxBlock->pxNextFreeBlock;
} while( pxBlock != pxEnd );
}
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
pxHeapStats->xNumberOfFreeBlocks = xBlocks;
pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
}
#endif /* #ifdef configHEAP_ALLOCATION_SCHEME */
// #endif /* #if(configHEAP_ALLOCATION_SCHEME == HEAP_ALLOCATION_TYPE4) */

View File

@ -1,179 +1,183 @@
#ifndef BUDDY
// #ifndef BUDDY
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
// #include <stdio.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <assert.h>
// #include <string.h>
typedef long Align; /* for alignment to long boundary */
union header
{ /* block header */
struct
{
union header *ptr; /* next block if on free list */
unsigned size; /* size of this block */
} s;
Align x; /* force alignment of blocks */
};
typedef union header Header;
// typedef long Align; /* for alignment to long boundary */
// union header
// { /* block header */
// struct
// {
// union header *ptr; /* next block if on free list */
// unsigned size; /* size of this block */
// } s;
// Align x; /* force alignment of blocks */
// };
// typedef union header Header;
// static Header base; /* empty list to get started */
static Header *base; /* empty list to get started */
static Header *freep = NULL; /* start of free list */
// // static Header base; /* empty list to get started */
// static Header *base; /* empty list to get started */
// static Header *freep = NULL; /* start of free list */
char initMemoryManager(void * managedMemory) {
// freep = (Header *) managedMemory;
// freep->s.ptr = NULL;
// freep->s.size = ;
// #define MAX 1024
// void initMemoryManager(void * managedMemory) {
// // freep = (Header *) managedMemory;
// // freep->s.ptr = NULL;
// // freep->s.size = ;
base = (Header *) managedMemory;
}
/* memMalloc: general-purpose storage allocator */
void *
memMalloc(unsigned nbytes)
{
Header *p, *prevp;
Header *moreroce(unsigned);
unsigned nunits;
// nunits = (nbytes + sizeof(Header) - 1) / sizeof(header) + 1;
nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
if ((prevp = freep) == NULL)
{ /* no free list yet */
// base.s.ptr = freeptr = prevptr = &base;
// base.s.ptr = &base;
// base.s.size = 0;
base->s.ptr = base;
base->s.size = 0;
}
for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
{
if (p->s.size >= nunits)
{ /* big enough */
if (p->s.size == nunits) /* exactly */
prevp->s.ptr = p->s.ptr;
else
{ /* allocate tail end */
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p + 1);
}
// if (p == freep) /* wrapped around free list */
// if ((p = morecore(nunits)) == NULL)
// return NULL; /* none left */
}
}
// #define NALLOC 1024 /* minimum #units to request */
// /* morecore: ask system for more memory */
// static Header *morecore(unsigned nu)
// {
// char *cp, *sbrk(int);
// Header *up;
// if (nu < NALLOC)
// nu = NALLOC;
// cp = sbrk(nu * sizeof(Header));
// if (cp == (char *)-1) /* no space at all */
// return NULL;
// up = (Header *)cp;
// up->s.size = nu;
// free((void *)(up + 1));
// return freep;
// base = (Header *) managedMemory;
// freep = base;
// freep->s.ptr = NULL;
// freep->s.size = 1024/sizeof(Header);
// }
/* free: put block ap in free list */
void free(void *ap)
{
Header *bp, *p;
bp = (Header *)ap - 1; /* point to block header */
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break; /* freed block at start or end of arena */
if (bp + bp->s.size == p->s.ptr)
{ /* join to upper nbr */
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
}
else
bp->s.ptr = p->s.ptr;
if (p + p->s.size == bp)
{ /* join to lower nbr */
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
}
else
p->s.ptr = bp;
freep = p;
}
// /* memMalloc: general-purpose storage allocator */
// void *
// memMalloc(unsigned nbytes)
// {
// Header *p, *prevp;
// // Header *moreroce(unsigned);
// unsigned nunits;
// // nunits = (nbytes + sizeof(Header) - 1) / sizeof(header) + 1;
// nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
// // if ((prevp = freep) == NULL)
// // { /* no free list yet */
// // // base.s.ptr = freeptr = prevptr = &base;
// // // base.s.ptr = &base;
// // // base.s.size = 0;
// // base->s.ptr = base;
// // base->s.size = 0;
// // }
// for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
// {
// if (p->s.size >= nunits)
// { /* big enough */
// if (p->s.size == nunits) /* exactly */
// prevp->s.ptr = p->s.ptr;
// else
// { /* allocate tail end */
// p->s.size -= nunits;
// p += p->s.size;
// p->s.size = nunits;
// }
// freep = prevp;
// return (void *)(p + 1);
// }
// // if (p == freep) /* wrapped around free list */
// // if ((p = morecore(nunits)) == NULL)
// // return NULL; /* none left */
// }
// }
char testOne() {
void * alloc1 = memMalloc(100);
void * alloc2 = memMalloc(200);
void * alloc3 = memMalloc(300);
// // #define NALLOC 1024 /* minimum #units to request */
memset(alloc1, 1, 100);
memset(alloc2, 2, 200);
memset(alloc3, 3, 300);
// // /* morecore: ask system for more memory */
// // static Header *morecore(unsigned nu)
// // {
// // char *cp, *sbrk(int);
// // Header *up;
// // if (nu < NALLOC)
// // nu = NALLOC;
// // cp = sbrk(nu * sizeof(Header));
// // if (cp == (char *)-1) /* no space at all */
// // return NULL;
// // up = (Header *)cp;
// // up->s.size = nu;
// // free((void *)(up + 1));
// // return freep;
// // }
for (int i = 0; i < 600; i++) {
if (i < 100) {
assert(*((char *) alloc1+i) == 1);
} else if (i < 300) {
assert(*((char *) alloc1+i) == 2);
} else if (i < 600) {
assert(*((char *) alloc1+i) == 3);
}
}
// /* free: put block ap in free list */
// void memFree(void *ap)
// {
// Header *bp, *p;
// bp = (Header *)ap - 1; /* point to block header */
// for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
// if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
// break; /* freed block at start or end of arena */
// if (bp + bp->s.size == p->s.ptr)
// { /* join to upper nbr */
// bp->s.size += p->s.ptr->s.size;
// bp->s.ptr = p->s.ptr->s.ptr;
// }
// else
// bp->s.ptr = p->s.ptr;
// if (p + p->s.size == bp)
// { /* join to lower nbr */
// p->s.size += bp->s.size;
// p->s.ptr = bp->s.ptr;
// }
// else
// p->s.ptr = bp;
// freep = p;
// }
return EXIT_SUCCESS;
}
// // char testOne() {
// // void * alloc1 = memMalloc(100);
// // void * alloc2 = memMalloc(200);
// // void * alloc3 = memMalloc(300);
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
// // memset(alloc1, 1, 100);
// // memset(alloc2, 2, 200);
// // memset(alloc3, 3, 300);
/*
char testTwo() {
void * ptr;
while (ptr != NULL){
ptr = memMalloc((rand() % 2000) + 1);
if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
printStringLen(13, "allocRand1 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
printStringLen(13, "allocRand2 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
// if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// }
// if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// }
}
// // for (int i = 0; i < 600; i++) {
// // if (i < 100) {
// // assert(*((char *) alloc1+i) == 1);
// // } else if (i < 300) {
// // assert(*((char *) alloc1+i) == 2);
// // } else if (i < 600) {
// // assert(*((char *) alloc1+i) == 3);
// // }
// // }
return EXIT_SUCCESS;
// // return EXIT_SUCCESS;
// // }
}
*/
// // static unsigned long int next = 1;
// // int rand(void) // RAND_MAX assumed to be 32767
// // {
// // next = next * 1103515245 + 12345;
// // return (unsigned int)(next/65536) % 32768;
// // }
char mem[1024];
// // /*
// // char testTwo() {
// // void * ptr;
// // while (ptr != NULL){
// // ptr = memMalloc((rand() % 2000) + 1);
// // if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
// // printStringLen(13, "allocRand1 -- ERROR", 31);
// // new_line();
// // return EXIT_FAILURE;
// // }
// // if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// // printStringLen(13, "allocRand2 -- ERROR", 31);
// // new_line();
// // return EXIT_FAILURE;
// // }
// // // if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// // // }
// // // if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// // // }
// // }
int main() {
initMemoryManager(mem);
if (testOne() == EXIT_FAILURE)
return EXIT_FAILURE;
// if (testTwo() == EXIT_FAILURE)
// return EXIT_FAILURE;
}
// // return EXIT_SUCCESS;
#endif
// // }
// // */
// // char mem[1024];
// // int main() {
// // initMemoryManager(mem);
// // if (testOne() == EXIT_FAILURE)
// // return EXIT_FAILURE;
// // // if (testTwo() == EXIT_FAILURE)
// // // return EXIT_FAILURE;
// // }
// #endif

View File

@ -1,176 +1,176 @@
#ifndef BUDDY
// #ifndef BUDDY
#include "memManager.h"
// #include <stdio.h>
#include <string.h>
#include <assert.h>
#include "video.h"
// #include "memManager.h"
// // #include <stdio.h>
// #include <string.h>
// #include <assert.h>
// #include "video.h"
#define MANAGED_MEMORY_SIZE 1024 * 1024 * 64
// #define MANAGED_MEMORY_SIZE 1024 * 1024 * 64
// char mem[MANAGED_MEMORY_SIZE];
// char mem2[MANAGED_MEMORY_SIZE];
// // char mem[MANAGED_MEMORY_SIZE];
// // char mem2[MANAGED_MEMORY_SIZE];
typedef struct MemoryManagerCDT {
char *nextAddress;
// char *lastAddress;
char *initialAddress;
} MemoryManagerCDT;
// typedef struct MemoryManagerCDT {
// char *nextAddress;
// // char *lastAddress;
// char *initialAddress;
// } MemoryManagerCDT;
MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
MemoryManagerADT memoryManager = (MemoryManagerADT) memoryForMemoryManager;
memoryManager->nextAddress = managedMemory;
// char * aux = managedMemory;
// memoryManager->lastAddress = aux - 1;
memoryManager->initialAddress = managedMemory;
// MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
// MemoryManagerADT memoryManager = (MemoryManagerADT) memoryForMemoryManager;
// memoryManager->nextAddress = managedMemory;
// // char * aux = managedMemory;
// // memoryManager->lastAddress = aux - 1;
// memoryManager->initialAddress = managedMemory;
return memoryManager;
}
// return memoryManager;
// }
void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate) {
char *allocation = memoryManager->nextAddress;
if (memoryToAllocate + memoryManager->nextAddress > memoryManager->initialAddress + MANAGED_MEMORY_SIZE){
return NULL;
}
// void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate) {
// char *allocation = memoryManager->nextAddress;
// if (memoryToAllocate + memoryManager->nextAddress > memoryManager->initialAddress + MANAGED_MEMORY_SIZE){
// return NULL;
// }
memoryManager->nextAddress += memoryToAllocate;
// if (!(memoryManager->nextAddress -1 == (memoryManager->lastAddress += memoryToAllocate)))
// return NULL;
// memoryManager->nextAddress += memoryToAllocate;
// // if (!(memoryManager->nextAddress -1 == (memoryManager->lastAddress += memoryToAllocate)))
// // return NULL;
return (void *) allocation;
}
// return (void *) allocation;
// }
// Esto es mejor para independizarnos del puntero a memoryManager! Y poder llamar desde distintos lugares (sin la referencia del memManager) a malloc...
// // Esto es mejor para independizarnos del puntero a memoryManager! Y poder llamar desde distintos lugares (sin la referencia del memManager) a malloc...
static MemoryManagerADT memoryManager;
char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
return ((memoryManager = createMemoryManager(memoryForMemoryManager, managedMemory)) == NULL) ? EXIT_FAILURE : EXIT_SUCCESS;
}
// static MemoryManagerADT memoryManager;
// char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
// return ((memoryManager = createMemoryManager(memoryForMemoryManager, managedMemory)) == NULL) ? EXIT_FAILURE : EXIT_SUCCESS;
// }
void * memMalloc(const size_t memoryToAllocate) {
return allocMemory(memoryManager, memoryToAllocate);
}
// void * memMalloc(const size_t memoryToAllocate) {
// return allocMemory(memoryManager, memoryToAllocate);
// }
// SACAR DESPUÉS! ES SOLO PARA TESTEO...
// // SACAR DESPUÉS! ES SOLO PARA TESTEO...
char testOne() {
void * alloc1 = memMalloc(100);
void * alloc2 = memMalloc(200);
void * alloc3 = memMalloc(300);
// char testOne() {
// void * alloc1 = memMalloc(100);
// void * alloc2 = memMalloc(200);
// void * alloc3 = memMalloc(300);
memset(alloc1, 1, 100);
memset(alloc2, 2, 200);
memset(alloc3, 3, 300);
// memset(alloc1, 1, 100);
// memset(alloc2, 2, 200);
// memset(alloc3, 3, 300);
for (int i = 0; i < 600; i++) {
if (i < 100) {
if (!(*((char *) alloc1+i) == 1)) {
printStringLen(13, "alloc1 -- ERROR", 31);
// printStringLen(13, *((char *) alloc1+i), 1);
new_line();
return EXIT_FAILURE;
}
} else if (i < 300) {
if (!(*((char *) alloc1+i) == 2)) {
printStringLen(13, "alloc2 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
} else if (i < 600) {
if (!(*((char *) alloc1+i) == 3)) {
printStringLen(13, "alloc3 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
}
}
// for (int i = 0; i < 600; i++) {
// if (i < 100) {
// if (!(*((char *) alloc1+i) == 1)) {
// printStringLen(13, "alloc1 -- ERROR", 31);
// // printStringLen(13, *((char *) alloc1+i), 1);
// new_line();
// return EXIT_FAILURE;
// }
// } else if (i < 300) {
// if (!(*((char *) alloc1+i) == 2)) {
// printStringLen(13, "alloc2 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// } else if (i < 600) {
// if (!(*((char *) alloc1+i) == 3)) {
// printStringLen(13, "alloc3 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// }
// }
return EXIT_SUCCESS;
}
// return EXIT_SUCCESS;
// }
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
// static unsigned long int next = 1;
// int rand(void) // RAND_MAX assumed to be 32767
// {
// next = next * 1103515245 + 12345;
// return (unsigned int)(next/65536) % 32768;
// }
char testTwo() {
void * ptr;
while (ptr != NULL){
ptr = memMalloc((rand() % 2000) + 1);
if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
printStringLen(13, "allocRand1 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
printStringLen(13, "allocRand2 -- ERROR", 31);
new_line();
return EXIT_FAILURE;
}
// if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// }
// if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// }
}
// char testTwo() {
// void * ptr;
// while (ptr != NULL){
// ptr = memMalloc((rand() % 2000) + 1);
// if (!((char *) memoryManager->nextAddress >= memoryManager->initialAddress)) {
// printStringLen(13, "allocRand1 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// if (!((char *) memoryManager->nextAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// printStringLen(13, "allocRand2 -- ERROR", 31);
// new_line();
// return EXIT_FAILURE;
// }
// // if (!((char *) memoryManager->lastAddress >= memoryManager->initialAddress)) {
// // }
// // if (!((char *) memoryManager->lastAddress <= memoryManager->initialAddress + MANAGED_MEMORY_SIZE)) {
// // }
// }
return EXIT_SUCCESS;
// return EXIT_SUCCESS;
}
// }
/*
int main() {
static MemoryManagerADT memoryManager;
static MemoryManagerADT memoryManager2;
// /*
// int main() {
// static MemoryManagerADT memoryManager;
// static MemoryManagerADT memoryManager2;
void * memoryForMemoryManager = (void *) 0x700000;
// void * memoryForMemoryManager = malloc(sizeof(void *));
if (memoryForMemoryManager == NULL) {
return 1;
}
// void * memoryForMemoryManager = (void *) 0x700000;
// // void * memoryForMemoryManager = malloc(sizeof(void *));
// if (memoryForMemoryManager == NULL) {
// return 1;
// }
void *managedMemory = (void *) 0x700016;// malloc(MANAGED_MEMORY_SIZE);
if (managedMemory == NULL) {
return 1;
}
// void *managedMemory = (void *) 0x700016;// malloc(MANAGED_MEMORY_SIZE);
// if (managedMemory == NULL) {
// return 1;
// }
void * memoryForMemoryManager2 = (void *) 0x700008;
// void * memoryForMemoryManager2 = malloc(sizeof(void *));
memoryManager = createMemoryManager(memoryForMemoryManager, managedMemory);
// void * memoryForMemoryManager2 = (void *) 0x700008;
// // void * memoryForMemoryManager2 = malloc(sizeof(void *));
// memoryManager = createMemoryManager(memoryForMemoryManager, managedMemory);
void * alloc1 = allocMemory(memoryManager, 100);
void * alloc2 = allocMemory(memoryManager, 200);
void * alloc3 = allocMemory(memoryManager, 300);
// void * alloc1 = allocMemory(memoryManager, 100);
// void * alloc2 = allocMemory(memoryManager, 200);
// void * alloc3 = allocMemory(memoryManager, 300);
memset(alloc1, 1, 100);
memset(alloc2, 2, 200);
memset(alloc3, 3, 300);
// memset(alloc1, 1, 100);
// memset(alloc2, 2, 200);
// memset(alloc3, 3, 300);
for (int i = 0; i < 600; i++) {
if (i < 100) {
assert(*((char *) alloc1+i) == 1);
} else if (i < 300) {
assert(*((char *) alloc1+i) == 2);
} else if (i < 600) {
assert(*((char *) alloc1+i) == 3);
}
}
// for (int i = 0; i < 600; i++) {
// if (i < 100) {
// assert(*((char *) alloc1+i) == 1);
// } else if (i < 300) {
// assert(*((char *) alloc1+i) == 2);
// } else if (i < 600) {
// assert(*((char *) alloc1+i) == 3);
// }
// }
managedMemory = (void *) (0x700016 + 600);
memoryManager2 = createMemoryManager(memoryForMemoryManager2, managedMemory);
// managedMemory = (void *) (0x700016 + 600);
// memoryManager2 = createMemoryManager(memoryForMemoryManager2, managedMemory);
void * ptr;
while (ptr != NULL){
ptr = allocMemory(memoryManager2, (rand() % 2000) + 1);
assert ((char *) memoryManager2->nextAddress >= mem2);
assert ((char *) memoryManager2->nextAddress <= mem2 + MANAGED_MEMORY_SIZE);
assert ((char *) memoryManager2->lastAddress >= mem2);
assert ((char *) memoryManager2->lastAddress <= mem2 + MANAGED_MEMORY_SIZE);
}
}
*/
// void * ptr;
// while (ptr != NULL){
// ptr = allocMemory(memoryManager2, (rand() % 2000) + 1);
// assert ((char *) memoryManager2->nextAddress >= mem2);
// assert ((char *) memoryManager2->nextAddress <= mem2 + MANAGED_MEMORY_SIZE);
// assert ((char *) memoryManager2->lastAddress >= mem2);
// assert ((char *) memoryManager2->lastAddress <= mem2 + MANAGED_MEMORY_SIZE);
// }
// }
// */
#endif
// #endif

54
Kernel/test_mm.c Normal file
View File

@ -0,0 +1,54 @@
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include "test_util.h"
// #define MAX_BLOCKS 128
// #define MAX_MEMORY 1024 //Should be around 80% of memory managed by the MM
// typedef struct MM_rq{
// void *address;
// uint32_t size;
// }mm_rq;
// void test_mm(){
// mm_rq mm_rqs[MAX_BLOCKS];
// uint8_t rq;
// uint32_t total;
// while (1){
// rq = 0;
// total = 0;
// // Request as many blocks as we can
// while(rq < MAX_BLOCKS && total < MAX_MEMORY){
// mm_rqs[rq].size = GetUniform(MAX_MEMORY - total - 1) + 1;
// mm_rqs[rq].address = malloc(mm_rqs[rq].size); // TODO: Port this call as required
// //TODO: check if NULL
// total += mm_rqs[rq].size;
// rq++;
// }
// // Set
// uint32_t i;
// for (i = 0; i < rq; i++)
// if (mm_rqs[i].address != NULL)
// memset(mm_rqs[i].address, i, mm_rqs[i].size); // TODO: Port this call as required
// // Check
// for (i = 0; i < rq; i++)
// if (mm_rqs[i].address != NULL)
// if(!memcheck(mm_rqs[i].address, i, mm_rqs[i].size))
// printf("ERROR!\n"); // TODO: Port this call as required
// // Free
// for (i = 0; i < rq; i++)
// if (mm_rqs[i].address != NULL)
// free(mm_rqs[i].address); // TODO: Port this call as required
// }
// }
// int main(){
// test_mm();
// return 0;
// }

27
Kernel/test_util.c Normal file
View File

@ -0,0 +1,27 @@
#include <stdint.h>
#include "test_util.h"
static uint32_t m_z = 362436069;
static uint32_t m_w = 521288629;
uint32_t GetUint(){
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w;
}
uint32_t GetUniform(uint32_t max){
uint32_t u = GetUint();
return (u + 1.0) * 2.328306435454494e-10 * max;
}
uint8_t memcheck(void *start, uint8_t value, uint32_t size){
uint8_t *p = (uint8_t *) start;
uint32_t i;
for (i = 0; i < size; i++, p++)
if (*p != value)
return 0;
return 1;
}

5
Kernel/test_util.h Normal file
View File

@ -0,0 +1,5 @@
#include <stdint.h>
uint32_t GetUint();
uint32_t GetUniform(uint32_t max);
uint8_t memcheck(void *start, uint8_t value, uint32_t size);