Advertisement
minh_tran_782

Best Fit + Worst Fit Implement

Mar 13th, 2022
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.95 KB | None | 0 0
  1.  
  2. #include "mem.h"
  3. #include <stdlib.h>
  4. #include <pthread.h>
  5. #include <stdio.h>
  6.  
  7. void * mem_pool = NULL;
  8.  
  9. pthread_mutex_t lock;
  10.  
  11. struct mem_region {
  12.     size_t size;    // Size of memory region
  13.     char * pointer; // Pointer to the first byte
  14.     struct mem_region * next; // Pointer to the next region in the list
  15.     struct mem_region * prev; // Pointer to the previous region in the list
  16. };
  17.  
  18. struct mem_region * free_regions = NULL;
  19. struct mem_region * used_regions = NULL;
  20.  
  21.  
  22. static void * best_fit_allocator(unsigned int size);
  23. static void * first_fit_allocator(unsigned int size);
  24. static void * worst_fit_allocator(unsigned int size);
  25. int mem_init(unsigned int size) {
  26.     /* Initial lock for multi-thread allocators */
  27.     pthread_mutex_init(&lock, NULL);
  28.  
  29.     /* Prealocate the mem pool based on used request */
  30.     mem_pool = malloc(size);
  31.  
  32.     /* Initial free list with only 1 region */
  33.     free_regions = (struct mem_region *)malloc(sizeof(struct mem_region));
  34.     free_regions->size = size;
  35.     free_regions->pointer = (char*)mem_pool;
  36.     free_regions->next = NULL;
  37.     free_regions->prev = NULL;
  38.  
  39.     return (mem_pool != 0);
  40. }
  41.  
  42. void mem_finish() {
  43.     /* Delete lock */
  44.     pthread_mutex_destroy(&lock);
  45.    
  46.     /* Clean lists */
  47.     struct mem_region * tmp;
  48.     if (free_regions != NULL) {
  49.         tmp = free_regions->next;
  50.         while (tmp != NULL) {
  51.             free(free_regions);
  52.             free_regions = tmp;
  53.             tmp = tmp->next;
  54.         }
  55.         free(free_regions);
  56.     }
  57.     if (used_regions != NULL) {
  58.         tmp = used_regions->next;
  59.         while (tmp != NULL) {
  60.             free(used_regions);
  61.             used_regions = tmp;
  62.             tmp = tmp->next;
  63.         }
  64.         free(used_regions);
  65.     }
  66.    
  67.     /* Clean preallocated region */
  68.     free(mem_pool);
  69. }
  70.  
  71. void * mem_alloc(unsigned int size) {
  72.     pthread_mutex_lock(&lock);
  73.     // Follow is FIST FIT allocator used for demonstration only.
  74.     // You need to implment your own BEST FIT allocator.
  75.     // TODO: Comment the next line
  76.     //void * pointer = first_fit_allocator(size);
  77.     // Commnent out the previous line and uncomment to next line
  78.     // to invoke best fit allocator
  79.     // TODO: uncomment the next line
  80.     void * pointer = worst_fit_allocator(size);
  81.    
  82.     // FOR VERIFICATION ONLY. DO NOT REMOVE THESE LINES
  83.     if (pointer != NULL) {
  84.         printf("Alloc [%4d bytes] %p-%p\n", size, pointer, (char*)pointer + size - 1);
  85.     }else{
  86.         printf("Alloc [%4d bytes] NULL\n");
  87.     }
  88.  
  89.     pthread_mutex_unlock(&lock);
  90.     return pointer;
  91. }
  92.  
  93. void mem_free(void * pointer) {
  94.     pthread_mutex_lock(&lock);
  95.     struct mem_region * current_region = used_regions;
  96.     // Get allocated region from the list of used_regions
  97.     while (current_region != NULL && current_region->pointer != pointer) {
  98.         current_region = current_region->next;
  99.     }
  100.     if (current_region != NULL) {
  101.         // Remove current region from the list of used regions
  102.         if (current_region == used_regions) {
  103.             used_regions = used_regions->next;
  104.             if (used_regions != NULL) {
  105.                 used_regions->prev = NULL;
  106.             }
  107.         }else{
  108.             if (current_region->prev != NULL) {
  109.                 current_region->prev->next = current_region->next;
  110.             }
  111.             if (current_region->next != NULL) {
  112.                 current_region->next->prev = current_region->prev;
  113.             }
  114.         }
  115.  
  116.         // FOR VERIFICATION ONLY. DO NOT REMOVE THESE LINES
  117.         printf("Free  [%4d bytes] %p-%p\n", current_region->size, current_region->pointer,
  118.                 current_region->pointer + current_region->size - 1);
  119.  
  120.         // Free this region by putting it into free list
  121.         if (free_regions == NULL) {
  122.             // No free region
  123.             free_regions = current_region;
  124.         }else{
  125.             // Find a location of the list for it
  126.             if (current_region->pointer < free_regions->pointer) {
  127.                 // new region will be put on the first location
  128.                 if (current_region->pointer + current_region->size == free_regions->pointer) {
  129.                     // The new regions and the first region in the list are contiguous
  130.                     free_regions->pointer = current_region->pointer;
  131.                     free_regions->size += current_region->size;
  132.                     free(current_region);
  133.                 }else{
  134.                     // These regions are not contiguous
  135.                     free_regions->prev = current_region;
  136.                     current_region->prev = NULL;
  137.                     current_region->next = free_regions;
  138.                     free_regions = current_region;
  139.                 }
  140.             }else{
  141.                 // new region will be put on somewhere in the middle or at the end of the list
  142.                 struct mem_region * tmp = free_regions;
  143.                 while (tmp->pointer < current_region->pointer && tmp->next != NULL) {
  144.                     tmp = tmp->next;
  145.                 }
  146.                 if (tmp->pointer < current_region->pointer) {
  147.                     // new region will be put at the end of the list
  148.                     if (tmp->pointer + tmp->size == current_region->pointer) {
  149.                         // Merge two contiguous regions
  150.                         tmp->size += current_region->size;
  151.                         free(current_region);
  152.                     }else{
  153.                         tmp->next = current_region;
  154.                         current_region->prev = tmp;
  155.                         current_region->next = NULL;
  156.                     }
  157.                 }else{
  158.                     // new region is in the middle of the list
  159.                     if (tmp->prev->pointer + tmp->prev->size == current_region->pointer) {
  160.                         // current_region and its previous one are contiguous
  161.                         tmp->prev->size += current_region->size;
  162.                         free(current_region);
  163.                         current_region = tmp->prev;
  164.                     }else{
  165.                         current_region->prev = tmp->prev;
  166.                         current_region->next = tmp;
  167.                         tmp->prev->next = current_region;
  168.                         tmp->prev = current_region;
  169.                     }
  170.                     if (current_region->pointer + current_region->size == tmp->pointer) {
  171.                         // current region and its next one are contiguous
  172.                         current_region->size += tmp->size;
  173.                         current_region->next = tmp->next;
  174.                         if (tmp->next != NULL) {
  175.                             tmp->next->prev = current_region;
  176.                         }
  177.                         free(tmp);
  178.                     }
  179.                 }
  180.             }
  181.         }
  182.     }
  183.     pthread_mutex_unlock(&lock);
  184. }
  185. void * worst_fit_allocator(unsigned int size) {
  186.     // TODO: Implement your worst fit allocator here
  187.     int idx = 0;
  188.     int maxdiff = 0;
  189.     int cnt = 0;  
  190.     int found = 0;
  191.     struct mem_region * current_region = free_regions;
  192.     do {
  193.         if (size <= current_region->size) {
  194.             int diff = current_region->size - size;
  195.             found = 1;
  196.             if (diff > maxdiff) {maxdiff = diff; idx = cnt; }
  197.         }
  198.             current_region = current_region->next;
  199.             ++cnt;
  200.         } while (current_region != NULL);
  201.  
  202.     current_region = free_regions;
  203.     cnt = 0;
  204.     while (current_region != NULL)
  205.     {
  206.             if (size <= current_region->size) {
  207.             if (cnt == idx) break;
  208.         }  
  209.             current_region = current_region->next;
  210.             ++cnt;
  211.     }
  212.      
  213.     if (found) {
  214.         struct mem_region* tmp =
  215.             (struct mem_region*)malloc(sizeof(struct mem_region));
  216.         tmp->pointer = current_region->pointer;
  217.         tmp->size = size;
  218.         tmp->next = used_regions;
  219.         tmp->prev = NULL;
  220.         if (used_regions == NULL) {
  221.             used_regions = tmp;
  222.         }else{
  223.             used_regions->prev = tmp;
  224.             used_regions = tmp;
  225.         }
  226.         if (current_region->size == size) {
  227.             if (current_region == free_regions) {
  228.                 free_regions = free_regions->next;
  229.                 if (free_regions != NULL) {
  230.                     free_regions->prev = NULL;
  231.                 }
  232.             }else{
  233.                 if (current_region->prev != NULL) {
  234.                     current_region->prev->next = current_region->next;
  235.                 }
  236.                 if (current_region->next != NULL) {
  237.                     current_region->next->prev = current_region->prev;
  238.                 }
  239.             }
  240.             free(current_region);
  241.         }else{
  242.             current_region->pointer += size;
  243.             current_region->size -= size;
  244.         }
  245.         return tmp->pointer;
  246.     }else{
  247.         return NULL;
  248.     }
  249. }
  250. void * best_fit_allocator(unsigned int size) {
  251.     // TODO: Implement your best fit allocator here
  252.     int idx = 0;
  253.     int mindiff = 0;
  254.     int cnt = 0;  
  255.     int  found = 0;
  256.     struct mem_region * current_region = free_regions;
  257.     do {
  258.         if (size <= current_region->size) {
  259.             int diff = current_region->size - size;
  260.              found = 1;
  261.             if (diff < mindiff) {mindiff = diff; idx = cnt; }
  262.         }
  263.             current_region = current_region->next;
  264.             ++cnt;
  265.         } while (current_region != NULL);
  266.  
  267.     current_region = free_regions;
  268.     cnt = 0;
  269.     while (current_region != NULL)
  270.     {
  271.             if (size <= current_region->size) {
  272.             if (cnt == idx) break;
  273.         }  
  274.             current_region = current_region->next;
  275.             ++cnt;
  276.     }
  277.     if (found) {
  278.         struct mem_region* tmp =
  279.             (struct mem_region*)malloc(sizeof(struct mem_region));
  280.         tmp->pointer = current_region->pointer;
  281.         tmp->size = size;
  282.         tmp->next = used_regions;
  283.         tmp->prev = NULL;
  284.         if (used_regions == NULL) {
  285.             used_regions = tmp;
  286.         }else{
  287.             used_regions->prev = tmp;
  288.             used_regions = tmp;
  289.         }
  290.         if (current_region->size == size) {
  291.             if (current_region == free_regions) {
  292.                 free_regions = free_regions->next;
  293.                 if (free_regions != NULL) {
  294.                     free_regions->prev = NULL;
  295.                 }
  296.             }else{
  297.                 if (current_region->prev != NULL) {
  298.                     current_region->prev->next = current_region->next;
  299.                 }
  300.                 if (current_region->next != NULL) {
  301.                     current_region->next->prev = current_region->prev;
  302.                 }
  303.             }
  304.             free(current_region);
  305.         }else{
  306.             current_region->pointer += size;
  307.             current_region->size -= size;
  308.         }
  309.         return tmp->pointer;
  310.     }else{
  311.         return NULL;
  312.     }
  313. }
  314. void * first_fit_allocator(unsigned int size) {
  315.     /* First fit example */
  316.     int found = 0;
  317.     struct mem_region * current_region = free_regions;
  318.     do {
  319.         if (size <= current_region->size) {
  320.             found = 1;
  321.         }else{
  322.             current_region = current_region->next;
  323.         }
  324.     } while (!found && current_region != NULL);
  325.    
  326.     if (found) {
  327.         struct mem_region* tmp =
  328.             (struct mem_region*)malloc(sizeof(struct mem_region));
  329.         tmp->pointer = current_region->pointer;
  330.         tmp->size = size;
  331.         tmp->next = used_regions;
  332.         tmp->prev = NULL;
  333.         if (used_regions == NULL) {
  334.             used_regions = tmp;
  335.         }else{
  336.             used_regions->prev = tmp;
  337.             used_regions = tmp;
  338.         }
  339.         if (current_region->size == size) {
  340.             if (current_region == free_regions) {
  341.                 free_regions = free_regions->next;
  342.                 if (free_regions != NULL) {
  343.                     free_regions->prev = NULL;
  344.                 }
  345.             }else{
  346.                 if (current_region->prev != NULL) {
  347.                     current_region->prev->next = current_region->next;
  348.                 }
  349.                 if (current_region->next != NULL) {
  350.                     current_region->next->prev = current_region->prev;
  351.                 }
  352.             }
  353.             free(current_region);
  354.         }else{
  355.             current_region->pointer += size;
  356.             current_region->size -= size;
  357.         }
  358.         return tmp->pointer;
  359.     }else{
  360.         return NULL;
  361.     }
  362. }
  363.  
  364.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement