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:
parent
31ea74f515
commit
73a01944a4
|
@ -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();
|
||||||
|
|
104
Kernel/kernel.c
104
Kernel/kernel.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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) */
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
// }
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
Loading…
Reference in New Issue