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> #include <stdlib.h>
typedef struct MemoryManagerCDT * MemoryManagerADT; // typedef struct MemoryManagerCDT * MemoryManagerADT;
// MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory); // MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory);
// void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate); // void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate);
char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory); // char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory);
void * memMalloc(const size_t memoryToAllocate); 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 // SACAR DPS
char testOne(); char testOne();

View File

@ -52,28 +52,114 @@ void load_idt();
uint64_t getRSP(); uint64_t getRSP();
void printBottlerAndWait(); 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() { int main() {
load_idt(); load_idt();
if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) { // if (initMemoryManager(memoryModuleAddress, memoryModuleAddress + sizeof(void *)) == -1) {
printStringLen(13, "createMemoryManager() -- ERROR", 31); // printStringLen(13, "createMemoryManager() -- ERROR", 31);
new_line(); // new_line();
return EXIT_FAILURE; // return EXIT_FAILURE;
} // }
initMemoryManager(memoryModuleAddress);
#ifndef BUDDY #ifndef BUDDY
// SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO! // SACAR DESPUÉS! ES SOLO PARA TESTEO... CORRER DE A UNO!
if (testOne() == EXIT_FAILURE) // if (testOne() == EXIT_FAILURE)
return EXIT_FAILURE; // return EXIT_FAILURE;
// if (testTwo() == EXIT_FAILURE) // if (testTwo() == EXIT_FAILURE)
// return EXIT_FAILURE; // return EXIT_FAILURE;
test_mm();
#endif #endif
saveSampleRSP(getRSP()); saveSampleRSP(getRSP());
printBottlerAndWait(); // printBottlerAndWait();
((EntryPoint)sampleCodeModuleAddress)(); // ((EntryPoint)sampleCodeModuleAddress)();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,460 +1,460 @@
// #ifdef BUDDY // #ifdef BUDDY
#include <stdio.h> // #include <stdio.h>
#include <stdlib.h> // #include <stdlib.h>
#include <time.h> // #include <time.h>
#include <math.h> // #include <math.h>
#include <string.h> // #include <string.h>
#define MANAGED_MEMORY_SIZE 1024 * 1024 * 64 // #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) { // // char initMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
// return 1; // // 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) { // void unpack(Meta * m, int pos);
// return NULL;
// /* Fills myblock with zeros and creates first metadata */
// void init_block() {
// memset(&myblock, '\0', MANAGED_MEMORY_SIZE);
// memset(&myblock, 54, 1);
// } // }
typedef struct meta { // /* Returns log base 2 of a double d */
unsigned char allo : 1; // 0000000_ - allocated // double log2(double d) {
unsigned char left : 1; // 000000_0 - first or second // return log(d) / log(2);
unsigned char size : 6; // ______00 - n where (2^n)-1 is the block size // }
} Meta;
// /* Returns the level a reqSize will fit in */
// static char myblock[MANAGED_MEMORY_SIZE]; // int size_to_n(size_t reqSize) {
static char *myblock; // reqSize+=1;
void initMemoryManager(void * managedMemory) { // double d = log2((double)reqSize);
myblock = managedMemory; // 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) {
/* Fills myblock with zeros and creates first metadata */ // int bits = pos>>(n);
void init_block() { // bits+=1;
memset(&myblock, '\0', MANAGED_MEMORY_SIZE); // int ret = bits<<(n);
memset(&myblock, 54, 1);
} // if (ret == MANAGED_MEMORY_SIZE) {
// return ret;
/* Returns log base 2 of a double d */ // } else {
double log2(double d) { // return ret;
return log(d) / log(2); // }
}
// }
/* Returns the level a reqSize will fit in */
int size_to_n(size_t reqSize) { // /* Returns the position of the left half of a pair */
reqSize+=1; // int jump_back(int n, int pos) {
double d = log2((double)reqSize); // int bits = pos>>(n);
return (int)ceil(d); // bits-=1;
} // return bits<<(n);
// }
/* Returns the position of the next block of the correct size */
int jump_next(int n, int pos) { // /* Fills a Meta struct with metadata at pos */
int bits = pos>>(n); // void unpack(Meta * m, int pos) {
bits+=1; // memset(m, myblock[pos], 1);
int ret = bits<<(n); // }
if (ret == MANAGED_MEMORY_SIZE) { // /* Returns whether position at level n is left or right partner */
return ret; // int is_left(int n, int pos) {
} else {
return ret; // // Manipulate bits to set nth bit on
} // int k = 1;
// k<<=(n);
}
// // Manipulate bits to zero bits above n
/* Returns the position of the left half of a pair */ // unsigned int p = (unsigned int)pos;
int jump_back(int n, int pos) { // p<<=(31-n);
int bits = pos>>(n); // p>>=(31-n);
bits-=1;
return bits<<(n); // if (k == p) {
} // return 0; // Right
// } else {
/* Fills a Meta struct with metadata at pos */ // return 1; // Left
void unpack(Meta * m, int pos) { // }
memset(m, myblock[pos], 1); // }
}
// /* Mergee two unallocated blocks with same size */
/* Returns whether position at level n is left or right partner */ // void merge(int pos, int pos2, int n) {
int is_left(int n, int pos) {
// // Create new meta and set size field
// Manipulate bits to set nth bit on // char newMeta = (n+1)<<2;
int k = 1;
k<<=(n); // // Set left field
// if (is_left(n+1, pos)) {
// Manipulate bits to zero bits above n // newMeta+=2;
unsigned int p = (unsigned int)pos; // }
p<<=(31-n);
p>>=(31-n); // // Add new meta
// myblock[pos] = newMeta;
if (k == p) {
return 0; // Right // // Delete meta on right partner
} else { // myblock[pos2] = 0;
return 1; // Left // }
}
} // /* MYmymalloc */
// void * mymalloc(size_t reqSize) {
/* Mergee two unallocated blocks with same size */
void merge(int pos, int pos2, int n) { // // Check if too big
// if (reqSize > MANAGED_MEMORY_SIZE - 1) {
// Create new meta and set size field // fprintf(stderr, "Error: Requested size too large\n");
char newMeta = (n+1)<<2; // }
// Set left field // // Traverse heap to find block of correct size - algo(n)
if (is_left(n+1, pos)) { // int n = size_to_n(reqSize);
newMeta+=2; // int pos = 0;
} // unsigned char c = 0;
// Meta * m = memset(&c, 0, 1);
// Add new meta
myblock[pos] = newMeta; // while (pos < MANAGED_MEMORY_SIZE) {
// // Read metadata
// Delete meta on right partner // unpack(m, pos);
myblock[pos2] = 0;
} // // Debugging
// if (m->size == 0) {
/* MYmymalloc */ // exit(0);
void * mymalloc(size_t reqSize) { // }
// Check if too big // if (n <= m->size) {
if (reqSize > MANAGED_MEMORY_SIZE - 1) { // if (m->allo == 1) {
fprintf(stderr, "Error: Requested size too large\n"); // // Jump
} // pos = jump_next(n, pos);
// continue;
// Traverse heap to find block of correct size - algo(n) // } else if (m->size == n) {
int n = size_to_n(reqSize); // // Allocate
int pos = 0; // myblock[pos]+=1;
unsigned char c = 0; // pos+=1;
Meta * m = memset(&c, 0, 1); // return (void*)((long int)&myblock+pos);
// } else {
while (pos < MANAGED_MEMORY_SIZE) { // // Partition
// Read metadata
unpack(m, pos); // // Get partner position
// int partner = jump_next((m->size)-1, pos);
// Debugging
if (m->size == 0) { // // Set Left
exit(0); // char meta_1 = 2;
} // char meta_2 = 0;
if (n <= m->size) { // // Set Size
if (m->allo == 1) { // char s = ((m->size)-1)<<2;
// Jump // meta_1 = (meta_1 | s);
pos = jump_next(n, pos); // meta_2 = (meta_2 | s);
continue;
} else if (m->size == n) { // // Fill in metadata
// Allocate // myblock[pos] = meta_1;
myblock[pos]+=1; // myblock[partner] = meta_2;
pos+=1;
return (void*)((long int)&myblock+pos); // // Continue on same position with new size of block
} else { // continue;
// Partition // }
// } else {
// Get partner position // // Jump
int partner = jump_next((m->size)-1, pos); // pos = jump_next(n, pos);
// continue;
// Set Left // }
char meta_1 = 2; // }
char meta_2 = 0;
// fprintf(stderr, "Error: Did not allocate %d\n", pos);
// Set Size
char s = ((m->size)-1)<<2; // return 0;
meta_1 = (meta_1 | s); // }
meta_2 = (meta_2 | s);
// /* MYmyfree */
// Fill in metadata // void myfree(void * ptr) {
myblock[pos] = meta_1;
myblock[partner] = meta_2; // // Error Checking
// if (ptr <= (void *)&myblock || ptr > (void *)(&myblock + MANAGED_MEMORY_SIZE)) {
// Continue on same position with new size of block // fprintf(stderr, "Error en free\n");
continue; // return;
} // }
} else {
// Jump // // Get position
pos = jump_next(n, pos); // // int pos = (int)(ptr-(void *)&myblock-1);
continue; // int pos = (int)((char *)ptr-(char *)&myblock-1);
}
} // // Check if valid metadata location
// if (pos%2 == 1 || myblock[pos] == 0) {
fprintf(stderr, "Error: Did not allocate %d\n", pos); // fprintf(stderr, "Error con metadata\n");
// return;
return 0; // }
}
/* MYmyfree */ // // Initialize variables for merge
void myfree(void * ptr) { // unsigned char c1 = 0;
// unsigned char c2 = 0;
// Error Checking // Meta * m1 = memset(&c1, 0, 1);
if (ptr <= (void *)&myblock || ptr > (void *)(&myblock + MANAGED_MEMORY_SIZE)) { // Meta * m2 = memset(&c2, 0, 1);
fprintf(stderr, "Error en free\n"); // unpack(m1,pos);
return;
} // // Change allocated field
// myblock[pos] = myblock[pos] - 1;
// Get position
// int pos = (int)(ptr-(void *)&myblock-1); // while (pos >= 0 && pos <= 8196){
int pos = (int)((char *)ptr-(char *)&myblock-1); // // Read metadata
// unpack(m1,pos);
// Check if valid metadata location
if (pos%2 == 1 || myblock[pos] == 0) { // if (m1->left) { // Left Partner
fprintf(stderr, "Error con metadata\n");
return; // // Get position of other partner and read metadata
} // int pos2 = jump_next(m1->size, pos);
// if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE - 2) {
// Initialize variables for merge // unpack(m2,pos2);
unsigned char c1 = 0; // } else {
unsigned char c2 = 0; // break;
Meta * m1 = memset(&c1, 0, 1); // }
Meta * m2 = memset(&c2, 0, 1);
unpack(m1,pos); // // Merge or break
// if (m2->allo || m2->size != m1->size) {
// Change allocated field // break;
myblock[pos] = myblock[pos] - 1; // } else {
// merge(pos, pos2, m1->size);
while (pos >= 0 && pos <= 8196){ // }
// Read metadata
unpack(m1,pos); // } else { // Right Partner
if (m1->left) { // Left 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_next(m1->size, pos); // if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE -2) {
// unpack(m2,pos2);
if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE - 2) { // } else {
unpack(m2,pos2); // break;
} else { // }
break;
} // // Merge or break
// if (m2->allo || m2->size != m1->size) {
// Merge or break // break;
if (m2->allo || m2->size != m1->size) { // } else {
break; // merge(pos2, pos, m1->size);
} else { // }
merge(pos, pos2, m1->size); // }
} // }
// }
} else { // Right Partner
// int rando[20] = {
// Get position of other partner and read metadata // 56, 73, 2, 8, 76,
int pos2 = jump_back(m2->size,pos); // 56, 66, 21, 13, 4,
// 99, 80, 25, 6, 38,
if (pos2 >= 0 && pos2 <= MANAGED_MEMORY_SIZE -2) { // 10, 64, 12, 32, 71
unpack(m2,pos2); // };
} else {
break; // /* testA: mymalloc() 1 byte 3000 times, then myfree() the 3000 1 byte pointers one by one */
} // void testA() {
// int i = 0;
// Merge or break // char * p[3000];
if (m2->allo || m2->size != m1->size) {
break; // while (i < 3000) {
} else { // p[i] = (char *)mymalloc(sizeof(char)*1);
merge(pos2, pos, m1->size); // i++;
} // }
}
} // i = 0;
}
// while (i < 3000) {
int rando[20] = { // myfree(p[i]);
56, 73, 2, 8, 76, // i++;
56, 66, 21, 13, 4, // }
99, 80, 25, 6, 38,
10, 64, 12, 32, 71 // return;
}; // }
/* testA: mymalloc() 1 byte 3000 times, then myfree() the 3000 1 byte pointers one by one */ // /* testB: mymalloc() 1 byte and immediately myfree it 3000 times in a row */
void testA() { // void testB() {
int i = 0; // int i = 0;
char * p[3000]; // char * p;
while (i < 3000) { // while (i < 3000) {
p[i] = (char *)mymalloc(sizeof(char)*1); // p = (char *)mymalloc(sizeof(char)*1);
i++; // myfree(p);
} // i++;
// }
i = 0;
// return;
while (i < 3000) { // }
myfree(p[i]);
i++; // /* testC: Randomly choose between a 1 byte mymalloc() or myfree() 6000 times */
} // void testC() {
// int i = 1;
return; // int j = 0;
} // char * p[6000];
/* testB: mymalloc() 1 byte and immediately myfree it 3000 times in a row */ // p[0] = (char *)mymalloc(sizeof(char)*1);
void testB() {
int i = 0; // while (i+j < 1000) {
char * p;
// if ((i+j)%2 != 0) {
while (i < 3000) { // p[i] = (char *)mymalloc(sizeof(char)*1);
p = (char *)mymalloc(sizeof(char)*1); // i++;
myfree(p); // } else if (p[j] != 0) {
i++; // myfree(p[j]);
} // j++;
// } else {
return; // p[i] = (char *)mymalloc(sizeof(char)*1);
} // i++;
// }
/* testC: Randomly choose between a 1 byte mymalloc() or myfree() 6000 times */ // }
void testC() {
int i = 1; // while (j <= i) {
int j = 0; // myfree(p[j]);
char * p[6000]; // j++;
// }
p[0] = (char *)mymalloc(sizeof(char)*1);
// return;
while (i+j < 1000) { // }
if ((i+j)%2 != 0) { // /* testD: Randomly choose between a randomly-sized mymalloc() or myfree 6000 times */
p[i] = (char *)mymalloc(sizeof(char)*1); // void testD() {
i++; // int i = 1;
} else if (p[j] != 0) { // int j = 0;
myfree(p[j]); // char * p[6000];
j++;
} else { // p[0] = (char *)mymalloc(sizeof(char)*(20));
p[i] = (char *)mymalloc(sizeof(char)*1);
i++; // while (i+j < 6000) {
}
} // if ((i+j)%2 != 0) {
// p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20));
while (j <= i) { // i++;
myfree(p[j]); // } else if (p[j] != 0) {
j++; // myfree(p[j]);
} // j++;
// } else {
return; // p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20));
} // i++;
// }
/* testD: Randomly choose between a randomly-sized mymalloc() or myfree 6000 times */ // }
void testD() {
int i = 1; // while (j <= i) {
int j = 0; // myfree(p[j]);
char * p[6000]; // j++;
// }
p[0] = (char *)mymalloc(sizeof(char)*(20));
// return;
while (i+j < 6000) { // }
if ((i+j)%2 != 0) { // /* testE: mymalloc 100 2bytes and myfrees 100 2bytes 10 times */
p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20)); // void testE() {
i++; // int i = 0;
} else if (p[j] != 0) { // int j = 0;
myfree(p[j]); // int k = 0;
j++; // int m = 0;
} else { // char * p[6000];
p[i] = (char *)mymalloc(sizeof(char)*(((i%2)+1)*20));
i++; // while (i < 6000) {
} // k = 0;
} // while (k < 100) {
// p[i] = (char *)mymalloc(sizeof(char)*(2));
while (j <= i) { // i++; k++;
myfree(p[j]); // }
j++;
} // m = 0;
// while (m < 100) {
return; // myfree(p[j]);
} // j++; m++;
// }
/* testE: mymalloc 100 2bytes and myfrees 100 2bytes 10 times */ // }
void testE() {
int i = 0; // return;
int j = 0; // }
int k = 0;
int m = 0; // /* testF: mymalloc 2000 2bytes, myfrees 1000 2bytes, mymalloc 2000 2bytes, myfrees 3000 2bytes */
char * p[6000]; // void testF() {
// int i = 0;
while (i < 6000) { // int j = 0;
k = 0; // char * p[6000];
while (k < 100) {
p[i] = (char *)mymalloc(sizeof(char)*(2));
i++; k++; // while (i < 2000) {
} // p[i] = (char *)mymalloc(sizeof(char)*(2));
// i++;
m = 0; // }
while (m < 100) {
myfree(p[j]); // while (j < 1000) {
j++; m++; // myfree(p[j]);
} // j++;
} // }
return; // while (i < 2000) {
} // p[i] = (char *)mymalloc(sizeof(char)*(2));
// i++;
/* testF: mymalloc 2000 2bytes, myfrees 1000 2bytes, mymalloc 2000 2bytes, myfrees 3000 2bytes */ // }
void testF() {
int i = 0; // while (j < 4000) {
int j = 0; // myfree(p[j]);
char * p[6000]; // j++;
// }
while (i < 2000) { // return;
p[i] = (char *)mymalloc(sizeof(char)*(2)); // }
i++;
}
// int main(int argc, char const *argv[]) {
while (j < 1000) {
myfree(p[j]); // // Inititialize variables for workflow
j++; // int i, j;
}
// // Loop through fptr array
while (i < 2000) { // for (j = 0; j < 6; j++) {
p[i] = (char *)mymalloc(sizeof(char)*(2));
i++; // // Initialize time elapsed
} // double time_elapsed_in_seconds = 0.0;
while (j < 4000) { // // Run the fuction 100 times and calculate total time elapsed
myfree(p[j]); // for (i = 0; i < 100; i++) {
j++;
} // // Initialize myblock
// init_block();
return;
} // clock_t start = clock();
// switch(j) {
// case 0:
int main(int argc, char const *argv[]) { // testA();
// break;
// Inititialize variables for workflow // case 1:
int i, j; // testB();
// break;
// Loop through fptr array // case 2:
for (j = 0; j < 6; j++) { // testC();
// break;
// Initialize time elapsed // case 3:
double time_elapsed_in_seconds = 0.0; // testD();
// break;
// Run the fuction 100 times and calculate total time elapsed // case 4:
for (i = 0; i < 100; i++) { // testE();
// break;
// Initialize myblock // case 5:
init_block(); // testF();
// break;
clock_t start = clock(); // }
switch(j) { // clock_t end = clock();
case 0: // time_elapsed_in_seconds+=(end - start)/(double)CLOCKS_PER_SEC;
testA(); // }
break;
case 1: // // Print the after execution time of 100 runs
testB(); // printf("Time Elapsed test%d: %f secs\n", j, time_elapsed_in_seconds/100);
break; // }
case 2:
testC(); // return 0;
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 // #endif

View File

@ -1,320 +1,339 @@
#include <stdlib.h> // #ifndef BUDDY
#include <stdint.h>
#include <assert.h>
#include <string.h>
#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 MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#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; // #define portCHAR char
typedef long BaseType_t; // #define portFLOAT float
typedef unsigned long UBaseType_t; // #define portDOUBLE double
// #define portLONG long
// #define portSHORT short
// #define portSTACK_TYPE uint32_t
// #define portBASE_TYPE long
#define configSUPPORT_STATIC_ALLOCATION 1 // typedef portSTACK_TYPE StackType_t;
#define configSUPPORT_DYNAMIC_ALLOCATION 1 // typedef long BaseType_t;
#define configTOTAL_HEAP_SIZE 1024 // typedef unsigned long UBaseType_t;
#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 configSUPPORT_STATIC_ALLOCATION 1
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) // #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. */
* Initialises the heap structures before their first use. // #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
*/
static void prvHeapInit(void);
/* Allocate the memory for the heap. */ // /*
// #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) // * Initialises the heap structures before their first use.
// /* 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. */ // static void prvHeapInit(void);
// extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// #else
// static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
// #endif /* configAPPLICATION_ALLOCATED_HEAP */
static uint8_t *ucHeap; // /* Allocate the memory for the heap. */
void initMemoryManager(void * managedMemory) { // // #if( configAPPLICATION_ALLOCATED_HEAP == 1 )
ucHeap = managedMemory; // // /* 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 // static uint8_t *ucHeap;
of their size. */ // void initMemoryManager(void * managedMemory) {
typedef struct A_BLOCK_LINK // ucHeap = managedMemory;
{ // }
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
// /* Define the linked list structure. This is used to link free blocks in order
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); // of their size. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) // typedef struct A_BLOCK_LINK
/* 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;
/* 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;
// 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;
/* 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 ) );
}
}
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 );
/* 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 );
/* 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;
}
}
// traceMALLOC( pvReturn, xWantedSize );
}
// ( void ) xTaskResumeAll();
// #if( configUSE_MALLOC_FAILED_HOOK == 1 )
// { // {
// if( pvReturn == NULL ) // 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 ) )
// /* 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;
// /* 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 )
// { // {
// extern void vApplicationMallocFailedHook( void ); // BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
// vApplicationMallocFailedHook(); // 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;
// }
// /* 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 ) );
// } // }
// } // }
// #endif
return pvReturn; // ncPrint("MALLOC: ");
} // ncPrintDec(xFreeBytesRemaining);
/*-----------------------------------------------------------*/ // ncPrint(" ");
// ncPrintDec(xWantedSize);
void vPortFree( void *pv ) // ncPrint(" ");
{ // ncPrintDec(configADJUSTED_HEAP_SIZE);
uint8_t *puc = ( uint8_t * ) pv; // ncPrint(" ---- ");
BlockLink_t *pxLink; // if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) )
// {
if( pv != NULL ) // /* Blocks are stored in byte order - traverse the list from the start
{ // (smallest) block until one of adequate size is found. */
/* The memory being freed will have an BlockLink_t structure immediately // pxPreviousBlock = &xStart;
before it. */ // pxBlock = xStart.pxNextFreeBlock;
puc -= heapSTRUCT_SIZE; // while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
// {
/* This unexpected casting is to keep some compilers from issuing // pxPreviousBlock = pxBlock;
byte alignment warnings. */ // ncPrintDec(pxBlock->xBlockSize);
pxLink = ( void * ) puc; // ncPrint(" - ");
// pxBlock = pxBlock->pxNextFreeBlock;
// 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;
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/
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 ) ) );
/* 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;
/* 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) */
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);
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;
}
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)) {
// /* 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;
// /* 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;
// /* Insert the new block into the list of free blocks. */
// prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
// } // }
}
return EXIT_SUCCESS; // }
// // tengo 16 de info y de alineamiento 8!
// ncPrint("Dentro: ");
// ncPrintDec(xFreeBytesRemaining);
// ncPrint(" y ");
// xFreeBytesRemaining -= pxBlock->xBlockSize;
// ncPrintDec(xFreeBytesRemaining);
// ncNewline();
// }
} // // traceMALLOC( pvReturn, xWantedSize );
*/ // }
// // ( void ) xTaskResumeAll();
// char mem[1024]; // // #if( configUSE_MALLOC_FAILED_HOOK == 1 )
// // {
// // if( pvReturn == NULL )
// // {
// // extern void vApplicationMallocFailedHook( void );
// // vApplicationMallocFailedHook();
// // }
// // }
// // #endif
int main() { // return pvReturn;
// initMemoryManager(mem); // }
if (testOne() == EXIT_FAILURE) // /*-----------------------------------------------------------*/
return EXIT_FAILURE;
// if (testTwo() == EXIT_FAILURE) // 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;
// /* 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();
// }
// }
// /*-----------------------------------------------------------*/
// size_t xPortGetFreeHeapSize( void )
// {
// return xFreeBytesRemaining;
// }
// /*-----------------------------------------------------------*/
// void vPortInitialiseBlocks( void )
// {
// /* This just exists to keep the linker quiet. */
// }
// /*-----------------------------------------------------------*/
// 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 ) ) );
// /* 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;
// /* 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) */
// // 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);
// // 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;
// // }
// // 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; // 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;
// }
// */
// // char mem[1024];
// // 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 <stdio.h>
#include <stdlib.h> // #include <stdlib.h>
#include <unistd.h> // #include <unistd.h>
#include <assert.h> // #include <assert.h>
#include <string.h> // #include <string.h>
typedef long Align; /* for alignment to long boundary */ // typedef long Align; /* for alignment to long boundary */
union header // union header
{ /* block header */ // { /* block header */
struct // 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 */
char 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); // union header *ptr; /* next block if on free list */
// Header *up; // unsigned size; /* size of this block */
// if (nu < NALLOC) // } s;
// nu = NALLOC; // Align x; /* force alignment of blocks */
// cp = sbrk(nu * sizeof(Header)); // };
// if (cp == (char *)-1) /* no space at all */ // typedef union header Header;
// return NULL;
// up = (Header *)cp; // // static Header base; /* empty list to get started */
// up->s.size = nu; // static Header *base; /* empty list to get started */
// free((void *)(up + 1)); // static Header *freep = NULL; /* start of free list */
// return freep;
// #define MAX 1024
// void initMemoryManager(void * managedMemory) {
// // freep = (Header *) managedMemory;
// // freep->s.ptr = NULL;
// // freep->s.size = ;
// base = (Header *) managedMemory;
// freep = base;
// freep->s.ptr = NULL;
// freep->s.size = 1024/sizeof(Header);
// } // }
/* free: put block ap in free list */ // /* memMalloc: general-purpose storage allocator */
void free(void *ap) // void *
{ // memMalloc(unsigned nbytes)
Header *bp, *p; // {
bp = (Header *)ap - 1; /* point to block header */ // Header *p, *prevp;
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) // // Header *moreroce(unsigned);
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) // unsigned nunits;
break; /* freed block at start or end of arena */ // // nunits = (nbytes + sizeof(Header) - 1) / sizeof(header) + 1;
if (bp + bp->s.size == p->s.ptr) // nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
{ /* join to upper nbr */ // // if ((prevp = freep) == NULL)
bp->s.size += p->s.ptr->s.size; // // { /* no free list yet */
bp->s.ptr = p->s.ptr->s.ptr; // // // base.s.ptr = freeptr = prevptr = &base;
} // // // base.s.ptr = &base;
else // // // base.s.size = 0;
bp->s.ptr = p->s.ptr; // // base->s.ptr = base;
if (p + p->s.size == bp) // // base->s.size = 0;
{ /* join to lower nbr */ // // }
p->s.size += bp->s.size; // for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr)
p->s.ptr = bp->s.ptr; // {
} // if (p->s.size >= nunits)
else // { /* big enough */
p->s.ptr = bp; // if (p->s.size == nunits) /* exactly */
freep = p; // prevp->s.ptr = p->s.ptr;
} // else
// { /* allocate tail end */
char testOne() { // p->s.size -= nunits;
void * alloc1 = memMalloc(100); // p += p->s.size;
void * alloc2 = memMalloc(200); // p->s.size = nunits;
void * alloc3 = memMalloc(300); // }
// freep = prevp;
memset(alloc1, 1, 100); // return (void *)(p + 1);
memset(alloc2, 2, 200); // }
memset(alloc3, 3, 300); // // if (p == freep) /* wrapped around free list */
// // if ((p = morecore(nunits)) == NULL)
for (int i = 0; i < 600; i++) { // // return NULL; /* none left */
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;
}
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)) {
// } // }
}
return EXIT_SUCCESS; // // #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;
// // }
char mem[1024]; // /* 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;
// }
int main() { // // char testOne() {
initMemoryManager(mem); // // void * alloc1 = memMalloc(100);
if (testOne() == EXIT_FAILURE) // // void * alloc2 = memMalloc(200);
return EXIT_FAILURE; // // void * alloc3 = memMalloc(300);
// if (testTwo() == EXIT_FAILURE)
// return EXIT_FAILURE;
}
#endif // // 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);
// // }
// // }
// // 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 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;
// // }
// // */
// // 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 "memManager.h"
// #include <stdio.h> // // #include <stdio.h>
#include <string.h> // #include <string.h>
#include <assert.h> // #include <assert.h>
#include "video.h" // #include "video.h"
#define MANAGED_MEMORY_SIZE 1024 * 1024 * 64 // #define MANAGED_MEMORY_SIZE 1024 * 1024 * 64
// char mem[MANAGED_MEMORY_SIZE]; // // char mem[MANAGED_MEMORY_SIZE];
// char mem2[MANAGED_MEMORY_SIZE]; // // char mem2[MANAGED_MEMORY_SIZE];
typedef struct MemoryManagerCDT { // typedef struct MemoryManagerCDT {
char *nextAddress; // char *nextAddress;
// char *lastAddress; // // char *lastAddress;
char *initialAddress; // char *initialAddress;
} MemoryManagerCDT; // } MemoryManagerCDT;
MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) { // MemoryManagerADT createMemoryManager(void *const restrict memoryForMemoryManager, void *const restrict managedMemory) {
MemoryManagerADT memoryManager = (MemoryManagerADT) memoryForMemoryManager; // MemoryManagerADT memoryManager = (MemoryManagerADT) memoryForMemoryManager;
memoryManager->nextAddress = managedMemory; // memoryManager->nextAddress = managedMemory;
// char * aux = managedMemory; // // char * aux = managedMemory;
// memoryManager->lastAddress = aux - 1; // // memoryManager->lastAddress = aux - 1;
memoryManager->initialAddress = managedMemory; // memoryManager->initialAddress = managedMemory;
return memoryManager; // return memoryManager;
} // }
void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate) { // void *allocMemory(MemoryManagerADT const restrict memoryManager, const size_t memoryToAllocate) {
char *allocation = memoryManager->nextAddress; // char *allocation = memoryManager->nextAddress;
if (memoryToAllocate + memoryManager->nextAddress > memoryManager->initialAddress + MANAGED_MEMORY_SIZE){ // if (memoryToAllocate + memoryManager->nextAddress > memoryManager->initialAddress + MANAGED_MEMORY_SIZE){
return NULL;
}
memoryManager->nextAddress += memoryToAllocate;
// if (!(memoryManager->nextAddress -1 == (memoryManager->lastAddress += memoryToAllocate)))
// return NULL; // return NULL;
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...
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);
}
// SACAR DESPUÉS! ES SOLO PARA TESTEO...
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);
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;
}
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)) {
// memoryManager->nextAddress += memoryToAllocate;
// // if (!(memoryManager->nextAddress -1 == (memoryManager->lastAddress += memoryToAllocate)))
// // return NULL;
// return (void *) allocation;
// } // }
}
return EXIT_SUCCESS; // // 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;
// }
/* // void * memMalloc(const size_t memoryToAllocate) {
int main() { // return allocMemory(memoryManager, memoryToAllocate);
static MemoryManagerADT memoryManager; // }
static MemoryManagerADT memoryManager2;
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 * memoryForMemoryManager2 = (void *) 0x700008; // // SACAR DESPUÉS! ES SOLO PARA TESTEO...
// void * memoryForMemoryManager2 = malloc(sizeof(void *));
memoryManager = createMemoryManager(memoryForMemoryManager, managedMemory);
void * alloc1 = allocMemory(memoryManager, 100); // char testOne() {
void * alloc2 = allocMemory(memoryManager, 200); // void * alloc1 = memMalloc(100);
void * alloc3 = allocMemory(memoryManager, 300); // void * alloc2 = memMalloc(200);
// void * alloc3 = memMalloc(300);
memset(alloc1, 1, 100); // memset(alloc1, 1, 100);
memset(alloc2, 2, 200); // memset(alloc2, 2, 200);
memset(alloc3, 3, 300); // memset(alloc3, 3, 300);
for (int i = 0; i < 600; i++) { // for (int i = 0; i < 600; i++) {
if (i < 100) { // if (i < 100) {
assert(*((char *) alloc1+i) == 1); // if (!(*((char *) alloc1+i) == 1)) {
} else if (i < 300) { // printStringLen(13, "alloc1 -- ERROR", 31);
assert(*((char *) alloc1+i) == 2); // // printStringLen(13, *((char *) alloc1+i), 1);
} else if (i < 600) { // new_line();
assert(*((char *) alloc1+i) == 3); // 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;
// }
// }
// }
managedMemory = (void *) (0x700016 + 600); // return EXIT_SUCCESS;
memoryManager2 = createMemoryManager(memoryForMemoryManager2, managedMemory); // }
void * ptr; // static unsigned long int next = 1;
while (ptr != NULL){ // int rand(void) // RAND_MAX assumed to be 32767
ptr = allocMemory(memoryManager2, (rand() % 2000) + 1); // {
assert ((char *) memoryManager2->nextAddress >= mem2); // next = next * 1103515245 + 12345;
assert ((char *) memoryManager2->nextAddress <= mem2 + MANAGED_MEMORY_SIZE); // return (unsigned int)(next/65536) % 32768;
assert ((char *) memoryManager2->lastAddress >= mem2); // }
assert ((char *) memoryManager2->lastAddress <= mem2 + MANAGED_MEMORY_SIZE);
}
}
*/
#endif // 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;
// }
// /*
// int main() {
// static MemoryManagerADT memoryManager;
// static MemoryManagerADT memoryManager2;
// 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 * 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);
// 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);
// }
// }
// 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);
// }
// }
// */
// #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);