Advertisement
Guest User

Untitled

a guest
Jul 25th, 2014
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.13 KB | None | 0 0
  1. #include "my_malloc.h"
  2.  
  3. /* You *MUST* use this macro when calling my_sbrk to allocate the
  4. * appropriate size. Failure to do so may result in an incorrect
  5. * grading!
  6. */
  7. #define SBRK_SIZE 2048
  8.  
  9. /* If you want to use debugging printouts, it is HIGHLY recommended
  10. * to use this macro or something similar. If you produce output from
  11. * your code in your malloc library, then you will receive a grade
  12. * deduction. You have been warned!
  13. */
  14. #ifdef DEBUG
  15. #define DEBUG_PRINT(x) printf x
  16. #else
  17. #define DEBUG_PRINT(x)
  18. #endif
  19. static int firstTime = 1;
  20. static metadata_t* offset = 0;
  21. void split(metadata_t* block, int index);
  22. int find_index(size_t);
  23. void freeHelper(int index, metadata_t* ptr);
  24. metadata_t* find_buddy(int temp, metadata_t* ptr);
  25.  
  26. int freelist_remove(metadata_t *block, int index );
  27. /* Make sure this always points to the beginning of your current
  28. * heap space! If it does not, then the grader will not be able
  29. * to run correctly and you will probably get a 0. Remember that
  30. * only the _first_ call to my_malloc() returns the beginning of
  31. * the heap. Sequential calls will return a pointer to the newly
  32. * added space!
  33. * Technically this should be declared static because we do not
  34. * want any program outside of this file to be able to access it.
  35. * However, DO NOT CHANGE the way this variable is declared or
  36. * it will break the autograder.
  37. */
  38. void* heap;
  39.  
  40. /* Our freelist structure. This is where the current freelist of
  41. * blocks will be maintained. Failure to maintain the list inside
  42. * of this structure will result in no credit, as the grader will
  43. * expect it to be maintained here.
  44. * Technically this should be declared static for the same reasons
  45. * as above, but DO NOT CHANGE the way this structure is declared
  46. * or it will break the autograder.
  47. */
  48. metadata_t* freelist[8];
  49. /* SIZES FOR THE FREE LIST:
  50. * freelist[0] -> 16
  51. * freelist[1] -> 32
  52. * freelist[2] -> 64
  53. * freelist[3] -> 128
  54. * freelist[4] -> 256
  55. * freelist[5] -> 512
  56. * freelist[6] -> 1024
  57. * freelist[7] -> 2048
  58. */
  59.  
  60. void* my_malloc(size_t size)
  61. {
  62. int int_size = (int)size;
  63. size_t effective_size = int_size + sizeof(metadata_t); //effective size = size requested plus metadata
  64. if(effective_size >2048)
  65. {
  66. ERRNO = SINGLE_REQUEST_TOO_LARGE;
  67. return NULL;
  68. }
  69. if(int_size < 0)
  70. return NULL;
  71. int index = find_index(effective_size);
  72. metadata_t* retBlock = NULL;
  73. if(freelist[index] !=NULL) //if bock is present in freeListIndex
  74. {
  75. retBlock = freelist[index];
  76. freelist_remove(retBlock, index);
  77. retBlock->in_use = 1;
  78. char *address = (char*)retBlock;
  79. for(int i = 0; i< sizeof(metadata_t); i++) //we want to point to address right after metadata
  80. {
  81. address++;
  82. }
  83. retBlock = (metadata_t*)(address);
  84. return retBlock;
  85. }
  86. else //if block is not present in the index
  87. {
  88. metadata_t* splitBlock = NULL;
  89. int splitIndex = 0;
  90. for(int i = 8; i> index; i--) // look for block just above index. This is the block we want to split
  91. {
  92. if(freelist[i] != NULL)
  93. {
  94. splitBlock = freelist[i];
  95. splitIndex = i;
  96. }
  97. }
  98.  
  99. if(splitBlock == NULL) //no block available to split
  100. {
  101. freelist[7] = my_sbrk(SBRK_SIZE); //give size 2048 to freeList[7]
  102. if(firstTime) // if this is happening the first time, initialize heap and point it to freeList[7] which now had size 2048
  103. {
  104. offset = freelist[7];
  105. heap = freelist[7];
  106. firstTime = 0;
  107. }
  108.  
  109. if(freelist[7] == NULL)
  110. {
  111. ERRNO = OUT_OF_MEMORY; //all memory has been used up, we can't do anything
  112. return NULL;
  113. }
  114. else //not the first time, so a block was made and has been completely used up. New block was made and now, set pointers right.
  115. {
  116. freelist[7] ->size = 2048;
  117. freelist[7] ->prev = NULL;
  118. freelist[7] ->next = NULL;
  119. freelist[7] ->in_use = 0;
  120.  
  121. }
  122. }
  123. else //found a block of memory somewhere up
  124. {
  125. split(splitBlock, splitIndex);
  126. }
  127.  
  128. retBlock = my_malloc(size);
  129. }
  130.  
  131. ERRNO = NO_ERROR;
  132. return retBlock;
  133.  
  134.  
  135. }
  136.  
  137. void split(metadata_t* block, int index)
  138. {
  139. int size = block ->size; //size of the block to be split
  140. char* splitAddress = (char*)block; //split address to updated in the next step
  141. for(int i=0; i<size/2; i++)
  142. {
  143. splitAddress++; //find new splitAddress
  144. }
  145.  
  146. metadata_t *temp1 = block; //first block
  147. metadata_t *temp2 = (metadata_t*)(splitAddress); //second block
  148. freelist[index] = block->next; //remove block
  149. if(block->next !=NULL)
  150. block->next->prev = NULL; //set pointers right
  151.  
  152. temp1->next = temp2; //set all ponters correctly
  153. temp1->prev = NULL;
  154. temp2->next = NULL;
  155. temp2->prev = temp1;
  156. temp1->in_use = 0;
  157. temp2->in_use = 0;
  158. temp1->size = size/2;
  159. temp2->size = size/2;
  160.  
  161. freelist[index-1] = temp1; //put them in an index lower.
  162.  
  163.  
  164.  
  165. }
  166. int find_index(size_t effective_size)
  167. {
  168. size_t minSize = 16;
  169. int index = 7;
  170. size_t current_size = 2048;
  171. int flag = 1;
  172. while(index >0 && flag)
  173. {
  174. if(effective_size<=current_size && effective_size> current_size/2)
  175. flag =0;
  176. else if(effective_size<minSize)
  177. {
  178. index = 0;
  179. flag = 0;
  180. }
  181. else
  182. {
  183. current_size = current_size/2;
  184. index--;
  185. }
  186.  
  187. }
  188. return index;
  189. }
  190.  
  191.  
  192. int freelist_remove(metadata_t* block, int index)
  193. {
  194. metadata_t *ptr = freelist[index];
  195. if(ptr == block)
  196. {
  197. freelist[index] = block->next;
  198. if(block->next !=NULL)
  199. {
  200. block->next->prev = NULL;
  201. }
  202. block->next = NULL;
  203. block->prev = NULL;
  204. return 1;
  205. }
  206. else
  207. {
  208. while(ptr !=NULL)
  209. {
  210. if(ptr == block)
  211. {
  212. if(ptr->next == NULL)
  213. {
  214. ptr->prev->next = NULL;
  215. block->prev = NULL;
  216. block->next = NULL;
  217. return 1;
  218.  
  219. }
  220. else
  221. {
  222. ptr->next->prev = ptr->prev;
  223. ptr->prev->next = ptr->next;
  224. block->next= NULL;
  225. block->prev= NULL;
  226. return 1;
  227. }
  228. }
  229. ptr = ptr->next;
  230. }
  231. }
  232. return 0;
  233.  
  234. }
  235.  
  236. void* my_calloc(size_t num, size_t size)
  237. {
  238. if(num*size > 8192)
  239. {
  240. ERRNO = SINGLE_REQUEST_TOO_LARGE;
  241. return NULL;
  242. }
  243.  
  244. void *ptr = my_malloc(num*size);
  245. for(int i=0; i<num*size; i++)
  246. {
  247. ((char*)ptr)[i] = 0;
  248. }
  249.  
  250. ERRNO = NO_ERROR;
  251. return ptr;
  252. }
  253.  
  254. void my_free(void* ptr)
  255. {
  256. metadata_t *block = (metadata_t*)((char*)ptr - sizeof(metadata_t));
  257. if(block == NULL)
  258. return NULL;
  259.  
  260. //if the pointer to begin with is already free
  261. if(block->in_use == 0)
  262. {
  263. ERRNO = DOUBLE_FREE_DETECTED;
  264. return;
  265. }
  266. //set the block's in use to 0
  267. block->in_use = 0;
  268. block->next = NULL;
  269. block->prev = NULL;
  270.  
  271. int index = find_index(block->size);
  272.  
  273. freeHelper(index, block);
  274. }
  275.  
  276.  
  277. void freeHelper(int index, metadata_t* ptr)
  278. {
  279. metadata_t* buddy = find_buddy(index, ptr);
  280. if(buddy == NULL || buddy->in_use == 1|| buddy->size != ptr->size || ptr->size>= SBRK_SIZE) //if we don't have to coalesce, simply add to the freelist
  281. {
  282. ptr->next = freelist[index];
  283. if(ptr->next != NULL)
  284. {
  285. ptr->next->prev = ptr;
  286. }
  287. ptr->prev = NULL;
  288. freelist[index] = ptr;
  289. return;
  290. }
  291.  
  292. if(buddy->prev !=NULL)
  293. {
  294. buddy->prev->next = buddy->next;
  295. }
  296.  
  297. if(buddy->next !=NULL)
  298. {
  299. buddy->next->prev = buddy->prev;
  300. }
  301.  
  302. if(freelist[index] == buddy)
  303. {
  304. freelist[index] = freelist[index]->next;
  305. }
  306.  
  307. buddy->next = NULL;
  308. buddy->prev = NULL;
  309. if(buddy<ptr)
  310. {
  311. buddy->size = (buddy->size)*2;
  312. index++;
  313. freeHelper(index, buddy);
  314. }
  315. else
  316. {
  317. ptr->size = (ptr->size)*2;
  318. index++;
  319. freeHelper(index, ptr);
  320. }
  321. }
  322.  
  323. metadata_t* find_buddy(int index, metadata_t* ptr)
  324. {
  325.  
  326. metadata_t* myPtr = (metadata_t*)((char*) ptr - (char*) heap);
  327. index = index +4;
  328. metadata_t* buddyPtr = (metadata_t*)((((size_t)myPtr)^(1 << index)) + (char*)heap);
  329. if(ptr->size == SBRK_SIZE)
  330. return NULL;
  331. else
  332. return buddyPtr;
  333.  
  334. }
  335.  
  336.  
  337. void* my_memmove(void* dest, const void* src, size_t num_bytes)
  338. {
  339. char* destination = (char*)dest;
  340. char* source = (char*)src;
  341. size_t size = (size_t)num_bytes;
  342. while(size!=0)
  343. {
  344. *destination++ = *source++;
  345. size--;
  346. }
  347.  
  348. return dest;
  349. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement