Modestus Moon OS  R4
CS 450 project
mcb.c
Go to the documentation of this file.
1 #include <core/mcb.h>
2 
4 
7 
9 
10 
11 void initHeap(size_t initialHeapSize)
12 {
13 
14  initLinkedList(&mcbFreeList);
15  initLinkedList(&mcbAllocList);
16 
21  setPrintFunction(&mcbAllocList, &printMCBFunc);
22  setPrintFunction(&mcbFreeList, &printMCBFunc);
23 
24  heapLoc = (heapLocationPtr_t)kmalloc(initialHeapSize + sizeof(lmcb_t) + sizeof(cmcb_t));
25 
26  printf("Heap Loc Ptr %d :: total size %d\r\n", (int)heapLoc, ((int)((int)initialHeapSize + sizeof(lmcb_t) + sizeof(cmcb_t))));
27 
28  cmcb_t* heapCMCB = (cmcb_t*)heapLoc;
29  heapCMCB->representingNode.data = (void*)heapCMCB;
30  heapCMCB->associatedLMCB = (lmcb_t*)(heapLoc+initialHeapSize+sizeof(cmcb_t));
31 
32  heapCMCB->cmcbType = heapCMCB->associatedLMCB->lmcbType = MCB_FREE;
33 
34  heapCMCB->blockStartAddress = (mcbAddressPtr_t)(heapLoc+sizeof(cmcb_t));
36  heapCMCB->procName = "Initial Heap";
37  heapCMCB->associatedLMCB->mcbBlockSize=heapCMCB->mcbBlockSize=initialHeapSize;
38  heapCMCB->associatedLMCB->lmcbType=MCB_FREE;
39 
40  insertMCBIntoList(heapCMCB);
41 }
42 
43 //implements first fit.
44 //remember, size_t is unsigned
45 void* allocateMemFromHeap(size_t requestedSize)
46 {
48  if(!requestedSize) //if the size is greater than zero
49  {
51  return 0;
52  }
53  mcbSize_t totalBlockSize = requestedSize + sizeof(lmcb_t) + sizeof(cmcb_t);
54  //requestedSize + sizeof(lmcb_t) + sizeof(cmcb_t)
55  cmcb_t * allocatedCMCB = 0;
56  node_t * itNode = mcbFreeList.head.next;
57  for(; itNode != &(mcbFreeList.tail); itNode = itNode->next)
58  {
59  //should not do subtraction with unsigned types. < 0 IS > 0 because of wrap around
60 
61  if(((cmcb_t*)itNode->data)->mcbBlockSize >= totalBlockSize)
62  {
63  //we found a block large enough
64  //printf("\r\nBlock size %d, total block size %d\r\n", ((cmcb_t*)itNode->data)->mcbBlockSize, totalBlockSize);
65  allocatedCMCB = ((cmcb_t*)itNode->data);
66  break;
67  }
68  }
69  if(!allocatedCMCB) //if there are no blocks large enough
70  {
72  return 0;
73  }
74 
75  (void)removeNode(&(allocatedCMCB->representingNode));
76  //set the new sizes
77  allocatedCMCB->cmcbType = MCB_ALLOCATED;
78  allocatedCMCB->mcbBlockSize = requestedSize;
79 
80  //we have a pointer to a cmcb that is large enough.
81  //first step is
82  //to, firstly calculate the IMMEDIATE following cmcb offset from the cmcb block start
83 
84  cmcb_t* followCMCB = (cmcb_t*)((void*)allocatedCMCB + totalBlockSize);
85 
86  //setup the follow cmcb
87  followCMCB->representingNode.data = (void*)followCMCB;
88  followCMCB->cmcbType = MCB_FREE;
89  //the following cmcb's lmcb is the allocatedCMCBs current lmcb
90  followCMCB->associatedLMCB = allocatedCMCB->associatedLMCB;
91  //calc block start offset
92  followCMCB->blockStartAddress = ((void*)followCMCB)+sizeof(cmcb_t);
93  //the block size is the lmcb's blockStop - cmcb's blockStart
94  followCMCB->associatedLMCB->mcbBlockSize=
95  followCMCB->mcbBlockSize=
96  (followCMCB->associatedLMCB->blockStopAddress-followCMCB->blockStartAddress);
97  followCMCB->procName = "";
98 
99  //setup the allocatedCMCB's new lmcb
100  allocatedCMCB->associatedLMCB = (lmcb_t*)(((void*)allocatedCMCB->blockStartAddress)+allocatedCMCB->mcbBlockSize);
101  allocatedCMCB->associatedLMCB->lmcbType = allocatedCMCB->cmcbType;
102  allocatedCMCB->associatedLMCB->blockStopAddress = allocatedCMCB->associatedLMCB;
103 
104  //put the process's name pointer
106  {
107  allocatedCMCB->procName = currentOperatingProcess->name;
108  }
109  else
110  {
111  allocatedCMCB->procName = "init";
112  }
113 
114 
115  insertMCBIntoList(allocatedCMCB);
116  insertMCBIntoList(followCMCB);
117 
118 
119  return (void*)allocatedCMCB->blockStartAddress;
120 
121 }
122 
124 {
125  printf("%s", "\r\nAllocated Memory Blocks\r\n");
126  printList(&mcbAllocList);
127 }
128 
129 void printFree()
130 {
131  printf("%s", "\r\nFree Memory Blocks\r\n");
132  printList(&mcbFreeList);
133 }
134 
135 int mcbCompareFunc(void* mcb, void* mcbToCompare)
136 {
137  if(((cmcb_t*)mcb)->blockStartAddress == ((cmcb_t*)mcbToCompare)->blockStartAddress)
138  {
139  return 0;
140  }
141  return (((cmcb_t*)mcb)->blockStartAddress < ((cmcb_t*)mcbToCompare)->blockStartAddress)?-1:1;
142 }
143 
145 {
146  if(((cmcb_t*)mcb)->blockStartAddress == blockStartAddress)
147  {
148  return 0;
149  }
150  return (((cmcb_t*)mcb)->blockStartAddress < blockStartAddress)?-1:1;
151 }
152 
153 
154 int freeHeapMem(void* blockAddress)
155 {
157  node_t* foundNode = searchList(&mcbAllocList, blockAddress);
158  cmcb_t* foundCMCB = (foundNode)?(cmcb_t*)foundNode->data:0;
159  if(!foundCMCB)
160  {
162  return lastMCBError;
163  }
164  if(currentOperatingProcess->name != foundCMCB->procName)
165  {
167  return lastMCBError;
168  }
169 
170  //printf("\r\nin free%s","\r\n");
171  printMCBFunc(foundCMCB);
172 
173  (void)removeNode(&(foundCMCB->representingNode));
174  foundCMCB->procName = "";
175  foundCMCB->cmcbType=foundCMCB->associatedLMCB->lmcbType=MCB_FREE;
176  insertMCBIntoList(foundCMCB);
177 
178  reclaimFreeMem();
179  reclaimFreeMem();
180 
181  return lastMCBError;
182 }
183 
185 {
186  cmcb_t* foundCMCB=(cmcb_t*)mcbFreeList.head.next;
187  for(; &(foundCMCB->representingNode) != &(mcbFreeList.tail); foundCMCB=(cmcb_t*)foundCMCB->representingNode.next)
188  {
189  //check if not beginning of list
190  if(foundCMCB->representingNode.prev != &(mcbFreeList.head))
191  {
192  //chek if contiguous memory
193  if(((void*)((cmcb_t*)foundCMCB->representingNode.prev)->associatedLMCB)+sizeof(lmcb_t*) == foundCMCB)
194  {
195  //cmcbs are contiguous, combine
196 
197  ((cmcb_t*)foundCMCB->representingNode.prev)->associatedLMCB=foundCMCB->associatedLMCB;
198  foundCMCB=((cmcb_t*)foundCMCB->representingNode.prev);
199  foundCMCB->mcbBlockSize=foundCMCB->associatedLMCB->mcbBlockSize=
200  ((void*)foundCMCB->associatedLMCB->blockStopAddress)-
201  ((void*)foundCMCB->blockStartAddress); //set the new mcb block size
202 
203  (void)removeNode(foundCMCB->representingNode.next);
204  }
205  }
206  //check if not end of list
207  if(foundCMCB->representingNode.next != &(mcbFreeList.tail))
208  {
209  //chek if contiguous memory
210  if(((void*)(((cmcb_t*)foundCMCB->representingNode.next)))==(((void*)foundCMCB->associatedLMCB)+sizeof(lmcb_t)))
211  {
212  foundCMCB->associatedLMCB=((cmcb_t*)foundCMCB->representingNode.next)->associatedLMCB;
213  foundCMCB->mcbBlockSize=foundCMCB->associatedLMCB->mcbBlockSize=
214  ((void*)foundCMCB->associatedLMCB->blockStopAddress)-
215  ((void*)foundCMCB->blockStartAddress);
216 
217  (void)removeNode(foundCMCB->representingNode.next);
218  }
219  }
220  }
221 }
222 
223 void printMCBFunc(void* cmcb)
224 {
225  printf("Type: %s || Associ Proc: %s || Block Size: %d || block ptr: %d\r\n", mcbTypeToString(((cmcb_t*)cmcb)->cmcbType),
226  ((cmcb_t*)cmcb)->procName, ((cmcb_t*)cmcb)->mcbBlockSize, (int)((cmcb_t*)cmcb)->blockStartAddress);
227 }
228 
230 {
232  if(mcbAllocList.head.next == &mcbAllocList.tail) return 0;
233  return 1;
234 }
236 {
237  switch(result)
238  {
239  case MCB_SUCCESS:
240  return "SUCCESS";
242  return "ERROR_BLOCK_NOT_FOUND";
244  return "ERROR_BLOCK_NOT_ALLOCATED";
246  return "ERROR_NOT_ENOUGH_MEMORY";
248  return "ACCESS_DENIED";
249 
250  case ERROR_GENERIC:
251  default:
252  return "ERROR_UNKNOWN";
253  }
254  return "ERROR_UNKNOWN";
255 }
256 
257 const char* mcbTypeToString(e_mcb_type_t type)
258 {
259  switch(type)
260  {
261  case MCB_FREE:
262  return "FREE ";
263  case MCB_ALLOCATED:
264  return "ALLOCATED";
265  default:
266  break;
267  }
268  return "UNKNOWN ";
269 }
270 
271 void insertMCBIntoList(cmcb_t* blockToInsert)
272 {
274  switch (blockToInsert->cmcbType) {
275  case MCB_FREE:
276  insertNode(&mcbFreeList, &(blockToInsert->representingNode));
277  break;
278  case MCB_ALLOCATED:
279  insertNode(&mcbAllocList, &(blockToInsert->representingNode));
280  break;
281  default:
282  break;
283  }
284 }
285 
286 void heapTest()
287 {
288  printf("HEAP TEST%s","\r\n");
289  printf("%s", "Alloc list\r\n")
290  printList(&mcbAllocList);
291  printf("%s", "free list\r\n")
292  printList(&mcbFreeList);
293  printf("%s","\r\n\r\n");
294  int* test = (int*)allocateMemFromHeap(20);
296  {
297  printf("MCB Error! %s\r\n",mcbResultToString(lastMCBError));
298  }
299  printf("test int ptr %d\r\n",(int)test);
300  int *blocks[5];
301  for(*test = 0; *test < 5; (*test)++)
302  {
303  blocks[*test] = (int*)allocateMemFromHeap(20);
305  {
306  printf("MCB Error! %s\r\n",mcbResultToString(lastMCBError));
307  }
308  }
309  printf("%s", "\r\nAlloc list\r\n")
310  printList(&mcbAllocList);
311  printf("%s", "\r\nfree list\r\n")
312  printList(&mcbFreeList);
313  for(*test = 0; *test < 5; (*test)++)
314  {
315  freeHeapMem(blocks[*test]);
317  {
318  printf("MCB Error! %s\r\n",mcbResultToString(lastMCBError));
319  }
320  }
321  freeHeapMem(test);
322  printf("%s", "\r\nAlloc list\r\n")
323  printList(&mcbAllocList);
324  printf("%s", "\r\nfree list\r\n")
325  printList(&mcbFreeList);
326 }
const char * mcbTypeToString(e_mcb_type_t type)
Definition: mcb.c:257
int heapIsEmpty()
heapIsEmpty returns if the heap is empty.
Definition: mcb.c:229
void * heapLocationPtr_t
Definition: mcb.h:36
typedef of linked list node (see s_ll_node).
const char * mcbResultToString(e_mcb_result_t result)
Definition: mcb.c:235
void setPrintFunction(linkedList_t *list, void(*newPrintFunc)(void *))
sets the function whose job it is to print the list to the screen.
Definition: linked_list.c:207
void reclaimFreeMem()
reclaimFreeMem groups free blocks together if they are adjacent.
Definition: mcb.c:184
The s_cmcb struct the struct type for cmcb&#39;s -> defines the properties.
Definition: mcb.h:41
u32int kmalloc(u32int size)
Definition: heap.c:52
void insertMCBIntoList(cmcb_t *blockToInsert)
insertMCBIntoList inserts the mcb into the list specified.
Definition: mcb.c:271
const char * procName
Definition: mcb.h:43
size_t mcbSize_t
Definition: mcb.h:34
void setSearchComparisonFunction(linkedList_t *list, int(*newSearchFunc)(void *, void *))
sets the function whose job it is to compare the input data with the data in the list. the first void parameter will always be the data contained in the list, the second will be the data passed to the search function.
Definition: linked_list.c:73
void initHeap(size_t initialHeapSize)
initHeap initializes the system heap by calling kmalloc with a valid byte size. Creates a CMCB at the...
Definition: mcb.c:11
e_mcb_type_t cmcbType
Definition: mcb.h:45
node_t * removeNode(node_t *nodeToRemove)
will remove the node from the list. the list hierarchy will change to reflect the missing node...
Definition: linked_list.c:120
struct s_lmcb lmcb_t
Definition: mcb.h:30
pcb_t * currentOperatingProcess
Definition: pcb.c:9
void initLinkedList(linkedList_t *list)
initilize list and the optional array that backs the list
Definition: linked_list.c:3
heapLocationPtr_t heapLoc
Definition: mcb.c:3
e_mcb_type_t lmcbType
Definition: mcb.h:66
void printAlloc()
printAlloc prints the allocated memory blocks. Traverses through the allocated mcb list...
Definition: mcb.c:123
mcbSize_t mcbBlockSize
Definition: mcb.h:41
#define printf(format,...)
printf is simply a wrapper macro around sprintf with built in terminal print builtin needs to be a ma...
Definition: string.h:112
void printMCBFunc(void *cmcb)
printMCBFunc prints the type, block size, block pointer of the blocks in a given list.
Definition: mcb.c:223
e_mcb_type_t cmcbType
Definition: mcb.h:39
typedef of linked list (see s_ll).
mcbAddressPtr_t blockStartAddress
Definition: mcb.h:47
void * mcbAddressPtr_t
Definition: mcb.h:32
int mcbCompareFunc(void *mcb, void *mcbToCompare)
mcbCompareFunc compares the start addresses of two mcbs.
Definition: mcb.c:135
mcbSize_t mcbBlockSize
Definition: mcb.h:47
mcbSize_t mcbBlockSize
Definition: mcb.h:64
e_mcb_result_t lastMCBError
Definition: mcb.c:8
mcbAddressPtr_t blockStartAddress
Definition: mcb.h:53
void printList(linkedList_t *list)
test function to show list functionality. uses const char* as test data
Definition: linked_list.c:212
void * allocateMemFromHeap(size_t requestedSize)
allocateMemFromHeap takes the requested size and finds the first block that fits. Implements first fi...
Definition: mcb.c:45
The s_lmcb struct defines the properties of lmcb&#39;s.
Definition: mcb.h:60
linkedList_t mcbFreeList
Definition: mcb.c:5
void printFree()
printFree prints the free memory blocks. Traverses through the free mcb list.
Definition: mcb.c:129
e_mcb_result_t
The e_mcb_result_t enum defines the return status of functions working with MCBs. ...
Definition: mcb.h:16
e_mcb_type_t
The e_mcb_type_t enum defines the state of the MCBs.
Definition: mcb.h:23
node_t representingNode
Definition: mcb.h:43
void setInsertComparisonFunction(linkedList_t *list, int(*newCompFunc)(void *, void *))
takes in a function pointer and sets the library shared comparison pointer
Definition: linked_list.c:63
struct s_cmcb cmcb_t
Definition: mcb.h:28
mcbAddressPtr_t blockStopAddress
Definition: mcb.h:62
node_t * insertNode(linkedList_t *list, node_t *newNode)
Will insert the node into the list. This function will attempt to call the list&#39;s insert comparison f...
Definition: linked_list.c:173
lmcb_t * associatedLMCB
Definition: mcb.h:51
Definition: mcb.h:23
int freeHeapMem(void *blockAddress)
freeHeapMem takes the block address and frees the memory from the CMCB start to the LMCB end location...
Definition: mcb.c:154
int mcbSearchCompFunc(void *mcb, void *blockStartAddress)
mcbSearchCompFunc searches for the mcb that you want to compare with.
Definition: mcb.c:144
linkedList_t mcbAllocList
Definition: mcb.c:6
node_t * searchList(linkedList_t *listToSearch, void *data)
goes through the list using the list&#39;s comparison function to find the node which matches the data...
Definition: linked_list.c:154
const char * procName
Definition: mcb.h:49
void heapTest()
heapTest test function to create sample mcbs.
Definition: mcb.c:286