Guest User

Untitled

a guest
Mar 17th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <inttypes.h>
  5. #include <sys/types.h>
  6. #include <unistd.h>
  7.  
  8. #include "ex1.h"
  9.  
  10. #define ERROR_ON_SBRK (void *)-1
  11.  
  12. info_block *find_free_block(unsigned int size)
  13. {
  14. info_block *cur = head;
  15.  
  16. while (cur)
  17. {
  18. if (cur->is_free && cur->size >= size)
  19. return cur; // free block meet size requirement
  20. cur = cur->next;
  21. }
  22.  
  23. return NULL;
  24. }
  25.  
  26. void *allocate_aligned_block(unsigned int size, unsigned int align)
  27. {
  28. void *p_cur, *p_block, *p_info_block;
  29. int cur, offset;
  30.  
  31. // allocate block for info block
  32. if (sbrk(sizeof(info_block)) == ERROR_ON_SBRK)
  33. return NULL;
  34.  
  35. p_cur = sbrk(0);
  36. cur = (uintptr_t)p_cur;
  37.  
  38. // Get offset
  39. offset = cur % align;
  40. if (offset > 0)
  41. offset = align - offset;
  42.  
  43. // increase offset to align
  44. if (sbrk(offset) == ERROR_ON_SBRK)
  45. return NULL;
  46.  
  47. // get pointer to block
  48. p_block = sbrk(0);
  49.  
  50. // increase block size
  51. if (sbrk(size) == ERROR_ON_SBRK)
  52. return NULL;
  53.  
  54. // info block is behind block
  55. p_info_block = p_block - sizeof(info_block);
  56.  
  57. return p_info_block;
  58. }
  59.  
  60. void *aligned_malloc(unsigned int size, unsigned int align)
  61. {
  62. void *return_block;
  63. info_block *info;
  64. void *new_block;
  65.  
  66. // find in current list have free block meet size requirement.
  67. info = find_free_block(size);
  68. if (info)
  69. {
  70. // Found here
  71. info->is_free = 0; // not free now
  72. return_block = (void *)(info + 1);
  73. printf("Old block: Info at %lu - Block at %lu\n", (uintptr_t)info, (uintptr_t)return_block);
  74. return return_block;
  75. }
  76.  
  77. // Not found any good free block
  78.  
  79. // new block allocated with size must have info_block
  80. new_block = allocate_aligned_block(size, align);
  81.  
  82. if (new_block == NULL)
  83. return NULL; // cannot allocate new block
  84.  
  85. // store info block
  86. info = new_block;
  87. info->size = size;
  88. info->is_free = 0;
  89. info->next = NULL;
  90.  
  91. // Update state of list via head and tail
  92. if (!head)
  93. head = info;
  94. if (tail)
  95. tail->next = info;
  96. tail = info;
  97.  
  98. // Return new block
  99. return_block = (void *)(info + 1);
  100. printf("New block: Info at %lu - Block at %lu\n", (uintptr_t)info, (uintptr_t)return_block);
  101. return return_block;
  102. }
  103.  
  104. void * aligned_free(void *block)
  105. {
  106.  
  107. info_block *info;
  108. info_block *tmp;
  109. void *program_break;
  110.  
  111. if (!block) return NULL;
  112.  
  113. // retrive block info
  114. info = (info_block *)block - 1;
  115. // get current program break;
  116. program_break = sbrk(0);
  117.  
  118. // block to free is the last block in list, should update *tail and program break
  119. if (block + info->size == program_break)
  120. {
  121. if (head == tail)
  122. // no any left blocks
  123. head = tail = NULL;
  124. else
  125. {
  126. tmp = head;
  127. // find the block point to end block
  128. while (tmp)
  129. {
  130. if (tmp->next == tail)
  131. {
  132. tmp->next = NULL;
  133. tail = tmp;
  134. }
  135. tmp = tmp->next;
  136. }
  137. }
  138. // release memory of last block to OS
  139. sbrk(0 - sizeof(info_block) - info->size);
  140. printf("Release memory to OS\n");
  141. return sbrk(0);
  142. }
  143.  
  144. // block to free is internal list, only update status free of info_block
  145. info->is_free = 1;
  146. return sbrk(0);
  147. }
Add Comment
Please, Sign In to add comment