Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.40 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <memory.h>
  10.  
  11. const int INIT_SIZE = 64 * 1024;
  12.  
  13. #pragma pack(1)
  14. struct bos_hdr {
  15. int magic; // must be set to 0xb055;
  16. union {
  17. char padding[16];
  18. } u;
  19. };
  20.  
  21. struct bos_entry {
  22. int allocated:1; // will be non-zero if allocated
  23. int size; // includes the size of bos_entry
  24. union {
  25. char padding[8];
  26. } u;
  27. };
  28.  
  29. #pragma pack()
  30.  
  31. int main(int argc, char **argv) {
  32. if (argc != 2) {
  33. printf("USAGE: %s bos_filename\n", argv[0]);
  34. exit(2);
  35. }
  36. int fd = open(argv[1], O_CREAT | O_RDWR, 0777);
  37. if (fd == -1) {
  38. perror(argv[1]);
  39. exit(3);
  40. }
  41.  
  42. void *base = mmap(NULL, 1024*1024, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
  43. void *end;
  44. struct bos_hdr *hdr = base;
  45. struct bos_entry *first_entry = (struct bos_entry *)(hdr+1);
  46.  
  47. struct stat stat;
  48. if (fstat(fd, &stat) == -1) {
  49. perror("fstat");
  50. exit(4);
  51. }
  52. if (stat.st_size == 0) {
  53. ftruncate(fd, INIT_SIZE);
  54. memset(hdr, 0, sizeof *hdr);
  55. hdr->magic = 0xb055;
  56. memset(first_entry, 0, sizeof *first_entry);
  57. first_entry->size = INIT_SIZE - sizeof *hdr;
  58. end = (char*)base + INIT_SIZE;
  59. } else {
  60. end = (char*)base + stat.st_size;
  61. }
  62.  
  63. size_t n;
  64. char *line = NULL;
  65. while (getline(&line, &n, stdin) > 0) {
  66. // remove the newline
  67. size_t endi = strlen(line) - 1;
  68. if (line[endi] == '\n') {
  69. line[endi] = '\0';
  70. }
  71. switch(line[0]) {
  72. case 'l': {
  73. struct bos_entry *entry = first_entry;
  74. while ((void *) entry < end) {
  75. if (entry->allocated) {
  76. printf("%s\n", (char *) &entry[1]);
  77. }
  78. entry = (struct bos_entry *) ((char *) entry + entry->size);
  79. }
  80. }
  81. break; // break from the switch statement
  82. case 'a': {
  83. char *str = &line[2];
  84. struct bos_entry *bestFitEntry = NULL;
  85. struct bos_entry *entry = first_entry;
  86. int smallestLeftover = 99999;
  87. int needed_size = sizeof(*entry) + strlen(str) + 1;
  88. int left_over = 0;
  89. while ((void *) entry < end) {
  90. //Checks for duplicates if allocated
  91. printf("Checking %s against entry of value = %s\n", str, (char *)&entry[1]);
  92. if (entry->allocated) {
  93. if (strcmp(str, (char *) &entry[1]) == 0) {
  94. printf("Duplicate found\n");
  95. break;
  96. }
  97. }
  98. //If unallocated, check for best fit
  99. else {
  100. // split it (note this should be fixed so that it can grow if needed
  101. left_over = entry->size - needed_size;
  102. printf("Found space with %d leftover compared to %d best leftover\n", left_over, smallestLeftover);
  103. if ((left_over >= 0) && (left_over < smallestLeftover)) {
  104. printf("Found new best leftover = %p\n", (void *)entry);
  105. smallestLeftover = left_over;
  106. bestFitEntry = entry;
  107. }
  108. }
  109. entry = (struct bos_entry *) ((char *) entry + entry->size);
  110. /**
  111. entry = (struct bos_entry *) ((char *) entry + entry->size);
  112. if (!entry->allocated) {
  113. // split it (note this should be fixed so that it can grow if needed
  114. int needed_size = sizeof(*entry) + strlen(str) + 1;
  115. int left_over = entry->size - needed_size;
  116. if (left_over < sizeof(*entry) && smallestLeftover < left_over) {
  117. // if we don't have enough left over for an entry struct, we just
  118. // use it here and it will be internal fragmentation
  119. needed_size = entry->size;
  120. left_over = 0;
  121. }
  122. if (entry->size < needed_size) {
  123. printf("hmmm, you need to grow!!!\n");
  124. exit(6);
  125. }
  126. entry->size = needed_size;
  127. entry->allocated = 1;
  128. strcpy((char *) &entry[1], str);
  129. if (left_over > 0) {
  130. entry = (struct bos_entry *) ((char *) entry + entry->size);
  131. memset(entry, 0, sizeof *entry);
  132. entry->size = left_over;
  133. }
  134. break;
  135. **/
  136. }
  137. if(bestFitEntry != NULL){
  138. left_over = bestFitEntry->size - needed_size;
  139. if (left_over < sizeof(*entry)) {
  140. // if we don't have enough left over for an entry struct, we just
  141. // use it here and it will be internal fragmentation
  142. printf("Using all space of entry\n");
  143. needed_size = bestFitEntry->size;
  144. left_over = 0;
  145. }
  146. printf("bestfitEntry = %p\n", (void *)bestFitEntry);
  147. bestFitEntry->size = needed_size;
  148. bestFitEntry->allocated = 1;
  149. strcpy((char *) &bestFitEntry[1], str);
  150. if (left_over > 0) {
  151. printf("Turning leftover into new unallocated entry\n");
  152. entry = (struct bos_entry *) ((char *) bestFitEntry + bestFitEntry->size);
  153. memset(entry, 0, sizeof *entry);
  154. entry->size = left_over;
  155. }
  156. }
  157. }
  158. break;
  159. case 'd': {
  160. char *str = &line[2];
  161. struct bos_entry *entry = first_entry;
  162. struct bos_entry *firstUnallocatedEntry = NULL;
  163. int foundTarget = 0;
  164. int lastRecordAllocated = 1;
  165.  
  166. while ((void*)entry < end) {
  167. //If entry is unallocated or target is found, unallocate and set flags
  168. if((!entry->allocated) || (strcmp(str, (char *)&entry[1]) == 0)){
  169. if(strcmp(str, (char *)&entry[1]) == 0){
  170. foundTarget = 1;
  171. }
  172. entry->allocated = 0;
  173. //sets pointer to first unallocated entry of segment
  174. if(lastRecordAllocated){
  175. firstUnallocatedEntry = entry;
  176. lastRecordAllocated = 0;
  177. }
  178. }
  179. else{ //is allocated
  180. if(firstUnallocatedEntry != NULL){
  181. //finds total unallocated space of segment and coalesces
  182. printf("UnallocatedEntry size before: %d\n", firstUnallocatedEntry->size);
  183. firstUnallocatedEntry->size = abs((entry - 1) - firstUnallocatedEntry);
  184. printf("UnallocatedEntry size after: %d\n", firstUnallocatedEntry->size);
  185. firstUnallocatedEntry = NULL;
  186. }
  187. lastRecordAllocated = 1;
  188. if(foundTarget){
  189. break;
  190. }
  191. }
  192. entry = (struct bos_entry *) ((char *) entry + entry->size);
  193. }
  194.  
  195. /**
  196. while ((void*)entry < end) {
  197. printf("entry[1] = %s and str = %s\n", (char *)&entry[1], str);
  198. if(entry->allocated && (strcmp(str, (char *)&entry[1]) == 0)){
  199. entry->allocated = 0;
  200. printf("Entered loop and turned off allocation");
  201. }
  202. entry = (struct bos_entry *) ((char *) entry + entry->size);
  203. }
  204. **/
  205.  
  206.  
  207. }
  208. break;
  209.  
  210. case 'L': {
  211. struct bos_entry *entry = first_entry;
  212. int i = 0;
  213. while ((void*)entry < end) {
  214. char * allocated = "not allocated";
  215. if(entry->allocated){
  216. allocated = "allocated";
  217. }
  218.  
  219. printf("Entry #%d of size %d and is %s\n", i, entry->size, allocated);
  220. printf("%s\n", (char*)&entry[1]);
  221. entry = (struct bos_entry *) ((char *) entry + entry->size);
  222. i++;
  223. }
  224. printf("There were %d entries\n", i);
  225. }
  226.  
  227. break; // break from the switch statement
  228. }
  229. free(line);
  230. n = 0;
  231. line = 0;
  232. }
  233. return 0;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement