Advertisement
danscod

Untitled

Aug 29th, 2014
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.78 KB | None | 0 0
  1. //
  2. // COMP1927 Assignment 1 - Memory Suballocator
  3. // allocator.c ... implementation
  4. //
  5. // Created by Liam O'Connor on 18/07/12.
  6. // Modified by John Shepherd in August 2014
  7. // Copyright (c) 2012-2014 UNSW. All rights reserved.
  8. //
  9.  
  10. #include "allocator.h"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <assert.h>
  14.  
  15.  
  16. #define HEADER_SIZE sizeof(struct free_list_header)
  17. #define MAGIC_FREE 0xDEADBEEF
  18. #define MAGIC_ALLOC 0xBEEFDEAD
  19.  
  20. typedef unsigned char byte;
  21. typedef u_int32_t vlink_t;
  22. typedef u_int32_t vsize_t;
  23. typedef u_int32_t vaddr_t;
  24.  
  25. typedef struct free_list_header {
  26. u_int32_t magic; // ought to contain MAGIC_FREE
  27. vsize_t size; // # bytes in this block (including header)
  28. vlink_t next; // memory[] index of next free block
  29. vlink_t prev; // memory[] index of previous free block
  30. } free_header_t;
  31.  
  32. // Global data
  33. static byte *memory = NULL; // pointer to start of suballocator memory
  34. static vaddr_t free_list_ptr; // index in memory[] of first block in free list
  35. static vsize_t memory_size; // number of bytes malloc'd in memory[]
  36.  
  37. //Function Prototypes
  38. u_int32_t sizeToN(u_int32_t n);
  39. free_header_t* toPointer(vlink_t index);
  40. vlink_t toIndex(free_header_t* pointer);
  41. vlink_t memoryDivide (vlink_t curr);
  42. vlink_t enslaveRegion (vlink_t curr);
  43. void merge(void);
  44. void printHeaders(void);
  45.  
  46. //Essential Functions
  47. //Initialise the suballocator, and malloc memory for it
  48. void sal_init(u_int32_t size) {
  49.  
  50. printf("////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n");
  51. //Check if already initialised, do nothing if so
  52. if (memory != NULL) {
  53. return;
  54. }
  55.  
  56. //Round size to n
  57. u_int32_t n = sizeToN(size);
  58.  
  59. //set global variables | initialise suballocator
  60. memory = (byte *)malloc(n);
  61.  
  62. //check if malloc worked properly
  63. if (memory == NULL){
  64. fprintf(stderr, "sal_init: insufficient memory");
  65. abort();
  66. }
  67.  
  68. //set global variables | size and initial location of free list
  69. free_list_ptr = 0; //index of header of initial block
  70. memory_size = n;
  71.  
  72. //set first free list pointer
  73. free_header_t *T = (free_header_t *)memory;
  74. T->magic = MAGIC_FREE;
  75. T->size = n;
  76. T->next = 0;
  77. T->prev = 0;
  78. }
  79.  
  80. //Malloc for the program above but using the suballocated region instead
  81. void *sal_malloc(u_int32_t n) {
  82.  
  83. //printf("sal_malloc entered\n");
  84. int oldSize = memory_size + 1;
  85. //Use the idea of current node to make conceptualising/coding easier
  86. vlink_t curr = free_list_ptr;
  87. vlink_t region;
  88.  
  89. //printf("1");
  90. //Round n to nearest upper power of two, including the header
  91. n = sizeToN(n + HEADER_SIZE);
  92.  
  93. /*
  94. //Check if the allocator is large enough
  95. if (n > memory_size) {
  96. return NULL;
  97. }
  98. */
  99. //Scan through list looking for region of size n
  100. //Makes the while loop work the first time free_list_ptr is passed
  101. int passCount = 0;
  102. //Boolean variable to identify if a suitable region has been found
  103. int regionFound = 0;
  104. //int currSize = 0;
  105. do{ //go until you get back to the start and a region is found
  106. //printf("passCount = %d, regionFound = %d, curr = %p, curr->next = %p\n", passCount, regionFound, toPointer(curr), toPointer(curr));
  107.  
  108. //Ensure that loop will halt next time it reaches start //please check the line ^ -- it should loop if A || B is true and A && B is not true ie. only one is true
  109. if (curr == free_list_ptr && passCount != 0) {
  110. fprintf(stderr, "sal_malloc: insufficient memory\n");
  111. return NULL;
  112. }
  113.  
  114. //Print error message if region accessed has already been allocated
  115. //(and should therefore have been removed from free list);
  116. if (toPointer(curr)->magic != MAGIC_FREE) {
  117. fprintf(stderr, "Memory corruption\n");
  118. //sal_stats();
  119. abort();
  120. }
  121.  
  122.  
  123. //Case if region is sufficiently large
  124. //currSize = toPointer(curr)->size;
  125. //printf("currSize %d\n", currSize);
  126. if (toPointer(curr)->size >= n && toPointer(curr)->size < oldSize) {
  127. //currSize = toPointer(curr)->size;
  128. regionFound = 1; //try to go through the whole list and find the smallest one that is large enough
  129. //printf("regionFound = %d\n", regionFound);
  130. region = curr; //change curr to region below so that curr can keep searching for a better (smaller) region and still have it stored
  131. //Case if region is not large enough
  132. } else {
  133. curr = toPointer(curr)->next;
  134. }
  135.  
  136. //Increment passCount
  137. passCount++;
  138. //printf("passCount = %d, regionFound = %d, curr = %p, curr->next = %p\n", passCount, regionFound, toPointer(curr), toPointer(curr));
  139. } while (regionFound == 0 && curr != free_list_ptr);
  140. //printf("loop1 escaped\n");
  141.  
  142. if (regionFound == 0) {
  143. fprintf(stderr, "sal_malloc: insufficient memory 2\n");
  144. return NULL;
  145. }
  146.  
  147. //int j = 0;
  148. //sal_stats();
  149. //printf("j = %d,: entering loop \n", j);
  150. //Divide segment of memory into smallest possible size
  151. while (toPointer(region)->size >= 2 * n) { //so it only splits if its more than twice the size, otherwise it will be too small
  152. //printf("j = %d, ", j);
  153. region = memoryDivide(region);
  154. //j++;
  155. //printf("j = %d, ", j);
  156. }
  157. //printf("loop2 escaped\n");
  158.  
  159. //Remove region from the free list
  160. region = enslaveRegion(region);
  161. //printf("region = %d, HEADER_SIZE = %d, toIndex(toPointer(region) + HEADER_SIZE) = %d, toIndex(toPointer(region) = %d\n", region, HEADER_SIZE, toIndex(toPointer(region) + 1), toIndex(toPointer(region)));
  162.  
  163. //Return pointer to the first byte AFTER the region header
  164. //printf("sal_malloc exited\n");
  165. //sal_stats();
  166. return (void *)(toPointer(region) + 1);
  167. }
  168.  
  169. void sal_free(void *object) {
  170.  
  171. //printf("sal_free entered\n");
  172. //As object points to memory AFTER the header, go back to start of header
  173. //sal_stats();
  174. object = object - HEADER_SIZE;
  175.  
  176. //sal_stats();
  177. //object = (free_header_t *)object;
  178.  
  179. //Get the index for object
  180. vlink_t objectIndex = toIndex(object);
  181.  
  182. //Ensure the region is not already free
  183. assert(toPointer(objectIndex)->magic == MAGIC_ALLOC);
  184.  
  185. vlink_t temp = toPointer(free_list_ptr)->next;
  186. vlink_t curr = temp;
  187. while (temp != free_list_ptr){
  188. if (temp < curr){
  189. curr = temp;
  190. }
  191. temp = toPointer(temp)->next;
  192. }
  193. //printf("%d\n", curr);
  194. //curr is now the lowest position in free list
  195. //Find where in the list the object belongs -- the problem is in finding where the object goes in the list
  196. while (curr < objectIndex) {
  197. curr = toPointer(curr)->next;
  198. //printf("%d\n", objectIndex);
  199. if (curr == free_list_ptr){
  200. break;
  201. }
  202. }
  203. //make a new header
  204. //free_header_t *T = (free_header_t *)object;
  205. //please check this works
  206. //insert before
  207. toPointer(objectIndex)->magic = MAGIC_FREE;
  208. toPointer(objectIndex)->prev = curr;
  209. toPointer(objectIndex)->next = toPointer(curr)->next;
  210. toPointer(toPointer(curr)->next)->prev = objectIndex;
  211. toPointer(curr)->next = objectIndex;
  212.  
  213.  
  214. //Change status of region to FREE
  215. //toPointer(objectIndex)->magic = MAGIC_FREE;
  216. //printf("merge is whats stuck\n");
  217. //Attempt to merge adjacent regions
  218. temp = toPointer(free_list_ptr)->next;
  219. while (temp != free_list_ptr){
  220. if (toPointer(temp)->magic != MAGIC_FREE) {
  221. printf("Non-free region in list/ corruption000014\n");
  222. }
  223. temp = toPointer(temp)->next;
  224. }
  225. if (toPointer(free_list_ptr)->magic != MAGIC_FREE){
  226. printf("wank\n");
  227. }
  228. //printf("exit loop -- swag\n");
  229. merge();
  230. //printf("sal_free exited\n");
  231. }
  232.  
  233. //Terminate the suballocator - must sal_init to use again
  234. void sal_end(void) {
  235.  
  236. //Free all global variables, which makes accessing the (now deleted) suballocator impossible
  237. free(memory);
  238. memory = NULL; //should check if free does this
  239. free_list_ptr = 0;
  240. memory_size = 0;
  241.  
  242. }
  243.  
  244. //Print all statistics regarding suballocator
  245. void sal_stats(void) {
  246. //Print the global variables
  247. printf("sal_stats\n\n");
  248. printf("Global Variable 'memory' is: %p\n", memory);
  249. printf("Global Variable 'free_list_ptr' is: %d\n", free_list_ptr);
  250. printf("Global Variable 'memory_size' is: %d\n\n", memory_size);
  251.  
  252. printHeaders();
  253. }
  254.  
  255.  
  256. //Complementary Functions
  257.  
  258. //Return usable size from given n value
  259. u_int32_t sizeToN(u_int32_t size) {
  260.  
  261. int n = 1;
  262. //round size to the nearest upper power of two, unless already power of two
  263. if ((size != 0) && (size & (size - 1)) == 0) {
  264. n = size;
  265. } else {
  266. while (n < size) {
  267. //This isn't very efficient, but works for time being
  268. n = 2 * n;
  269. }
  270. }
  271.  
  272. return n;
  273. }
  274.  
  275. //Helper Functions
  276. //Converts an index to a pointer
  277. free_header_t *toPointer(vlink_t index) {
  278. return ((free_header_t *)(memory + index));
  279. }
  280.  
  281. //Converts a pointer to an index
  282. vlink_t toIndex(free_header_t* pointer) {
  283. return ((byte *)pointer - memory);
  284. }
  285.  
  286. //INCOMPLETE
  287. //Splits the region of memory passed in into two
  288. vlink_t memoryDivide(vlink_t curr) {
  289.  
  290. //printf("memoryDivide entered\n");
  291.  
  292. //sal_stats();
  293.  
  294. //Create temporary vlink
  295. vlink_t temp = curr;
  296. //printf("currP = %p, curr = %d, curr->next = %p, free_list_ptr = %d, temp = %d\n", toPointer(curr), curr, toPointer(curr), free_list_ptr, temp);
  297. //printf("temp = %d, toPointer(temp) = %p, toIndex(toPointer(temp)) = %d\n\n", temp, toPointer(temp), toIndex(toPointer(temp)));
  298. //Progress temp to the new divided region
  299. temp = temp + ((toPointer(curr)->size) / 2);
  300. //printf("temp = %d, toPointer(temp) = %p, toIndex(toPointer(temp)) = %d\n\n", temp, toPointer(temp), toIndex(toPointer(temp)));
  301.  
  302.  
  303. //Setup the new region header
  304. free_header_t *new = toPointer(temp);
  305. //printf("\ntoPointer(curr)->size = %d, toIndex(new) = %d, new = %p\n\n", toPointer(curr)->size, toIndex(new), new);
  306. new->size = toPointer(curr)->size / 2;
  307. //printf("new->size = %d\n", new->size);
  308. new->magic = MAGIC_FREE;
  309.  
  310. //Shrink the old region
  311. toPointer(curr)->size = (toPointer(curr)->size) / 2;
  312. //printf("toPointer(curr)->size = %d\n", toPointer(curr)->size);
  313.  
  314. //printf("new->next = %d, new->prev = %d, curr->next = %d, curr->prev = %d\n", new->next, new->prev, toPointer(curr)->next, toPointer(curr)->prev);
  315. //Link the new regions to the old ones (and vice versa)
  316. toPointer(toPointer(curr)->next)->prev = toIndex(new);
  317. new->next = toPointer(curr)->next;
  318. //printf("new->next = %d, new->prev = %d, curr->next = %d, curr->prev = %d\n", new->next, new->prev, toPointer(curr)->next, toPointer(curr)->prev);
  319. //Now new points to the old curr->next and vice versa
  320. toPointer(curr)->next = toIndex(new);
  321. new->prev = curr;
  322. //printf("new->next = %d, new->prev = %d, curr->next = %d, curr->prev = %d\n", new->next, new->prev, toPointer(curr)->next, toPointer(curr)->prev); ///this looks suss
  323. //Now curr points to new and vice versa
  324.  
  325. //sal_stats();
  326. //printf("memoryDivide exit\n");
  327. return curr;
  328. }
  329.  
  330. //Converts a region from free to allocated, and removes it from the free list
  331. vlink_t enslaveRegion(vlink_t curr) {
  332.  
  333. //printf("enslaveRegion entered\n");
  334.  
  335. //If the enslaved region is the same as free_list_ptr, move it
  336. if (curr == free_list_ptr) {
  337. free_list_ptr = toPointer(curr)->next;
  338. }
  339. //Mark header as allocated
  340. toPointer(curr)->magic = MAGIC_ALLOC;
  341. //Change neighbour's links to skip the enslaved region
  342. toPointer(toPointer(curr)->prev)->next = toPointer(curr)->next;
  343. toPointer(toPointer(curr)->next)->prev = toPointer(curr)->prev;
  344. //Destroy links within the allocated header
  345. toPointer(curr)->next = curr;
  346. toPointer(curr)->prev = curr;
  347.  
  348. //sal_stats();
  349. //printf("curr = %p, curr->next = %p, free_list_ptr = %d\n", toPointer(curr), toPointer(curr), free_list_ptr);
  350.  
  351.  
  352. //sal_stats();
  353.  
  354. //printf("enslaveRegion exit\n");
  355.  
  356. return curr;
  357. }
  358.  
  359. void merge(void) {
  360.  
  361. static int vlink_t = free_list_ptr;
  362. //printf("merge entered\n");
  363. //set to next so you can loop until its found again
  364. //vlink_t object = free_list_ptr;
  365. int pass = 0;
  366. //loop until adjacent regions of equal size are found
  367. vlink_t object = toPointer(free_list_ptr)->next;
  368. while (object != free_list_ptr){
  369. if (toPointer(object)->magic != MAGIC_FREE) {
  370. printf("Non-free region in list/ corruption13\n");
  371. abort();
  372. }
  373. object = toPointer(object)->next;
  374. }
  375.  
  376. while (toPointer(toPointer(object)->next)->size != toPointer(object)->size) {
  377. //ends if it goes through whole list
  378. if (object == free_list_ptr && pass == 1) {
  379. printf("merge exited -- swag style\n");
  380. break;
  381. }
  382.  
  383. object = toPointer(object)->next;
  384. pass = 1;
  385. }
  386.  
  387. //check whether to merge with next or prev -- could be a problem here
  388. //printf("after loop\n");
  389. if (object % (toPointer(object)->size * 2) == 0) {
  390. printf("hello1\n");
  391. toPointer(object)->size = toPointer(object)->size * 2;
  392. toPointer(toPointer(toPointer(object)->next)->next)->prev = object;
  393. toPointer(object)->next = toPointer(toPointer(object)->next)->next;
  394. }
  395. else {
  396. /* object = toPointer(object)->prev;
  397. toPointer(object)->size = toPointer(object)->size * 2;
  398. toPointer(toPointer(toPointer(object)->next)->next)->prev = object;
  399. toPointer(object)->next = toPointer(toPointer(object)->next)->next;
  400.  
  401. */ printf("hello\n");
  402.  
  403. free_list_ptr = toPointer(toPointer(object)->next)->next;
  404. //merge();
  405. return;
  406. }
  407.  
  408. free_list_ptr = toPointer(object)->next;
  409. //recurses to check if another set can be merged, starts at new position
  410. printf("merge exited (not really)\n");
  411. pass = 0;
  412. while (object == free_list_ptr) {
  413. //ends if it goes through whole list
  414. if (object == free_list_ptr && pass == 1) {
  415. printf("merge exited -- swag style 2\n");
  416. return;
  417. }
  418. if (toPointer(toPointer(object)->next)->size != toPointer(object)->size){
  419. merge();
  420. }
  421. object = toPointer(object)->next;
  422. pass = 1;
  423. }
  424. //merge();
  425. //printf("merge exited\n");
  426. return;
  427. }
  428.  
  429. //print out all headers
  430. void printHeaders(void) {
  431.  
  432. //Start from the beginning
  433. vlink_t curr = free_list_ptr;
  434.  
  435. do {
  436. //Print this header
  437. printf("curr(index): %d\n", curr);
  438. printf("curr(pointer): %p\n", toPointer(curr));
  439. printf("curr->MAGIC: 0x%08x\n", toPointer(curr)->magic);
  440. printf("curr->size: %d\n", toPointer(curr)->size);
  441. printf("curr->next: %d\n", toPointer(curr)->next);
  442. printf("curr->prev: %d\n\n", toPointer(curr)->prev);
  443. //printf("#############################################################################\n");
  444. //Move along
  445. curr = toPointer(curr)->next;
  446. } while (curr != free_list_ptr);
  447.  
  448. return;
  449. }
  450. #include "fancystat.c"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement