riccardinofuffolo

PDSC01

Apr 1st, 2015
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.88 KB | None | 0 0
  1. #include "myheap.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stddef.h>
  5.  
  6. /* http://moss.cs.iit.edu/cs351/assets/slides-malloc.pdf */
  7.  
  8. typedef struct node {
  9.     char* start;
  10.     char* end;
  11.     size_t size;
  12.     struct node *next;
  13. } Node;
  14.  
  15. struct heap_s {
  16.     char *area_dati;        /* Puntatore area dati */
  17.     size_t size;            /* Dimensione massima */
  18.     Node* free_list;        /* Lista partizioni libere */
  19.     Node* used_list;        /* Lista partizioni occupate */
  20.     Node *old_used_list;    /* Lista partizioni occupate pre-deframmentazione. */
  21.     heap_policy_t policy;   /* Politica di allocazione */
  22. };
  23.  
  24. heap_t heap;
  25.  
  26. heap_t *heapCreate(size_t heapSize) {
  27.     /* Inizializzazione struttura heap: parto da un heap grande heapSize. Liste ancora vuote. Policy di default. */
  28.     heap.area_dati = calloc(heapSize, sizeof(char));
  29.     heap.size = heapSize;
  30.     heap.free_list = NULL;
  31.     heap.used_list = NULL;
  32.     heap.policy = best_fit;
  33.  
  34.     /* Partizioni libere. Per adesso tutto l'heap è libero. */
  35.     Node* node = (Node*)malloc(sizeof(Node));
  36.     node->start = heap.area_dati;
  37.     node->end = heap.area_dati + heapSize;
  38.     node->size = heapSize;
  39.     node->next = heap.free_list;
  40.     heap.free_list = node;
  41.  
  42.     /* Partizioni usate */
  43.     /* Nessuna, LOL */
  44.  
  45.     return &heap;
  46. }
  47.  
  48. void heapDestroy(heap_t *h) {
  49.     Node* p = heap.free_list;
  50.     Node* tmp = NULL;
  51.     while (p != NULL) {
  52.         tmp = p;
  53.         p = p->next;
  54.         free(tmp);
  55.     }
  56.  
  57.     p = heap.used_list;
  58.     tmp = NULL;
  59.     while (p != NULL) {
  60.         tmp = p;
  61.         p = p->next;
  62.         free(tmp);
  63.     }
  64.  
  65.     free(h->area_dati);
  66. }
  67.  
  68. void *heapAlloc(heap_t *h, size_t size) {
  69.     /* Per politiche best-fit e worst-fit. */
  70.     size_t  this_size = 0,
  71.             min_size = INT_MAX,
  72.             max_size = 0;
  73.  
  74.     /* Puntatori ausiliari */
  75.     Node* p = heap.free_list;
  76.     Node* prev = NULL;
  77.     Node* selected = NULL;
  78.  
  79.     /* Puntatore da restituire al chiamante. */
  80.     void* pointer = NULL;
  81.    
  82.     switch (h->policy) {
  83.         /* First fit: trovo la prima partizione libera che soddisfa la richiesta. */
  84.         case first_fit: {
  85.             while (p != NULL) {
  86.                 if (p->size >= size) {
  87.                     selected = p;
  88.                     break;
  89.                 }
  90.                 else
  91.                     p = p->next;
  92.             }
  93.         }
  94.             break;
  95.        
  96.         /* Worst fit: trovo la partizione piu' grande disponibile. */
  97.         case worst_fit: {
  98.             while (p != NULL) {
  99.                 this_size = p->size;
  100.                 if (this_size >= max_size) {
  101.                     selected = p;
  102.                     max_size = this_size;
  103.                 }
  104.                 p = p->next;
  105.             }
  106.         }
  107.             break;
  108.  
  109.         /* Best fit: trovo la miglior partizione disponibile. */
  110.         case best_fit:
  111.             while (p != NULL) {
  112.                 this_size = p->size;
  113.                 if (this_size < min_size && this_size >= size) {
  114.                     selected = p;
  115.                     min_size = this_size;
  116.                 }
  117.                 p = p->next;
  118.             }
  119.             break;
  120.     }
  121.  
  122.     /* Salvataggio del puntatore da restituire all'utente. */
  123.     pointer = selected->start;
  124.  
  125.     /* Aggiornamento della used_list, con inserimento ordinato. */
  126.     Node* node = (Node*)malloc(sizeof(Node));
  127.     node->start = selected->start;
  128.     /* Se chiedi 5 byte e il tuo blocco inizia dal byte 10, occupi i byte 10-11-12-13-14. */
  129.     node->end = selected->start + size - 1;
  130.     node->size = size;
  131.    
  132.     /* Inserimento ordinato nella lista used_list delle partizioni usate. */
  133.     p = heap.used_list;
  134.     prev = NULL;
  135.     while (p != NULL) {
  136.         if (p->start > node->start)
  137.             break;
  138.         prev = p;
  139.         p = p->next;
  140.     }
  141.     if (prev != NULL) {
  142.         node->next = prev->next;
  143.         prev->next = node;
  144.     }
  145.     else {
  146.         node->next = heap.used_list;
  147.         heap.used_list = node;
  148.     }
  149.    
  150.     /* Aggiornamento della free_list. */
  151.     selected->start = selected->start + size;
  152.     selected->size = selected->size - size;
  153.  
  154.     return pointer;
  155. }
  156.  
  157. void heapFree(heap_t *h, void *p) {
  158.     Node* tmp = heap.used_list;
  159.     Node* prev = NULL;
  160.    
  161.     /* Rimozione della partizione passata dalla lista di quelle occupate */
  162.     while (tmp != NULL) {
  163.         if (p == tmp->start)
  164.             break;
  165.         prev = tmp;
  166.         tmp = tmp->next;
  167.     }
  168.     prev->next = tmp->next;
  169.    
  170.     /* tmp punta alla partizione che sto liberando. Lo devo inserire nelle partizioni libere.
  171.     Quindi niente free(). */
  172.  
  173.     /* Aggiunta ordinata della partizione alla lista delle partizioni libere. */
  174.     Node* frl = heap.free_list;
  175.     prev = NULL;
  176.  
  177.     while (frl != NULL) {
  178.         if (frl->start > tmp->start)
  179.             break;
  180.         prev = frl;
  181.         frl = frl->next;
  182.     }
  183.  
  184.     if (prev != NULL) {
  185.         tmp->next = prev->next;
  186.         prev->next = tmp;
  187.     }
  188.     else {
  189.         tmp->next = heap.free_list;
  190.         heap.free_list = tmp;
  191.     }
  192.  
  193.     /* Compattamento della lista delle partizioni libere. */
  194.     tmp = heap.free_list;
  195.     while (tmp != NULL && tmp->next != NULL) {
  196.         if (tmp->end + 1 == tmp->next->start) {
  197.             Node* me = tmp->next;
  198.             char* start = tmp->start;
  199.             char* end = tmp->next->end;
  200.             size_t size = tmp->size + tmp->next->size;
  201.             tmp->start = start;
  202.             tmp->end = end;
  203.             tmp->size = size;
  204.             tmp->next = tmp->next->next;
  205.             free(me);
  206.         }
  207.         tmp = tmp->next;
  208.     }
  209.  
  210.     //int i = 3;
  211. }
  212.  
  213. void heapSetPolicy(heap_t *h, heap_policy_t policy) {
  214.     h->policy = policy;
  215. }
  216.  
  217. void heapDefrag(heap_t *h) {
  218.     Node* p = heap.used_list;
  219.     char* cursor = heap.area_dati;
  220.     size_t used_size = 0;
  221.  
  222.     /* Libero la vecchia tabella delle partizioni riallocate. */
  223.     Node *poul = heap.old_used_list;
  224.     while (poul != NULL) {
  225.         Node *me = poul;
  226.         poul = poul->next;
  227.         free(me);
  228.     }
  229.     poul = NULL;
  230.     heap.old_used_list = NULL;
  231.     Node *pcoul = NULL;     /* Puntatore alla coda di old_used_list. */
  232.  
  233.     while (p != NULL) {
  234.         /* La partizione occupata xyz prima era a... */
  235.         Node *reallocated = (Node*)malloc(sizeof(Node));
  236.         reallocated->start = p->start;
  237.         reallocated->end = p->end;
  238.         reallocated->size = p->size;
  239.  
  240.         used_size = used_size + p->size;
  241.  
  242.         /* Ora è a... */
  243.         p->start = cursor;
  244.         p->end = cursor + p->size - 1;
  245.         cursor = p->end + 1;
  246.  
  247.         /* Inserimento in coda (così mantengo corrispondenza con used_list) */
  248.         if (heap.old_used_list == NULL) {
  249.             reallocated->next = heap.old_used_list;
  250.             heap.old_used_list = reallocated;
  251.             pcoul = heap.old_used_list;
  252.         }
  253.         else {
  254.             pcoul->next = reallocated;
  255.             reallocated->next = NULL;
  256.             reallocated = pcoul;
  257.         }
  258.  
  259.         p = p->next;
  260.     }
  261.  
  262.     /* Libero la vecchia tabella delle partizioni libere. */
  263.     /* Potrei fare un lavoro più fine, ma #sticazzi. */
  264.     Node *pfl = heap.free_list;
  265.     while (pfl != NULL) {
  266.         Node *me = pfl;
  267.         pfl = pfl->next;
  268.         free(me);
  269.     }
  270.     pfl = NULL;
  271.     heap.free_list = NULL;
  272.     Node *compacted = (Node*)malloc(sizeof(Node));
  273.     compacted->start = cursor;
  274.     compacted->size = heap.size - used_size;
  275.     compacted->end = cursor + compacted->size - 1;
  276.     compacted->next = heap.free_list;
  277.     heap.free_list = compacted;
  278.  
  279.     int i = 3;
  280. }
  281.  
  282. void *heapNewPointer(heap_t *h, void *p) {
  283.     Node *poul = heap.old_used_list;
  284.     Node *pul = heap.used_list;
  285.     while (poul != NULL) {
  286.         if (poul->start == p)
  287.             return pul->start;
  288.         poul = poul->next;
  289.         pul = pul->next;
  290.     }
  291.     return NULL;
  292. }
  293.  
  294. void heapDefragClose(heap_t *h) {
  295.     Node *poul = heap.old_used_list;
  296.     while (poul != NULL) {
  297.         Node *me = poul;
  298.         poul = poul->next;
  299.         free(me);
  300.     }
  301.     poul = NULL;
  302.     heap.old_used_list = NULL;
  303. }
Advertisement
Add Comment
Please, Sign In to add comment