/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/old-cs-2-01/informatik2/alloc2021-03-16-1.c


#include <stdio.h>
#include <stdlib.h>

struct lin_list {
    int base;
    int len;
    
    struct lin_list *next;
};

struct lin_list *head = NULL;

void list_insert (int len, int base) {
    struct lin_list *ptr;
    struct lin_list *prev_ptr;
    
    ptr = head;
    
    if (head == NULL) {
        if ((head = (struct lin_list *)malloc(sizeof (struct lin_list))) == NULL) {
            perror ("NOT ENOUGH MEMORY");
            exit (1);
        }
        head -> next = NULL;
        head -> len = len;
        head -> base = base;
        return;
    }
    
    while (ptr != NULL) {
        prev_ptr = ptr;
        ptr = ptr->next;
    }
    
    
    if ((ptr = (struct lin_list *) malloc (sizeof (struct lin_list))) == NULL) {
        perror ("NOT ENOUGH MEMORY");
        exit (1);
    }
    
    ptr -> next = NULL;
    ptr -> base = base;
    ptr -> len = len;
    prev_ptr -> next = ptr;
}

void lin_list_init (void) {
    int i;
    
    for (i = 0;  i < 10;  i++) {
        list_insert (10, i*10);
    }
    
}

void print_list (void) {
    struct lin_list *ptr;
    int i;
    
    ptr = head;
    
    i = 0;
    while (ptr != NULL) {
        printf ("%i %i %i\n", i++, ptr->len, ptr->base);
        ptr = ptr->next;
    }
    
}

void del_slot (struct lin_list *prev_ptr, struct lin_list *ptr) {
    struct lin_list *tmp;
    
    if (ptr == head) {
        tmp = head;
        head = head->next;
        free (tmp);
        return;
    }
    
    prev_ptr -> next = ptr -> next;
    free (ptr);
    return;
}

int alloc_mem (int clicks) {
    int old_base;
    
    struct lin_list *prev_ptr, *ptr;
    
    ptr = head;
    while (ptr != NULL) {
        if (ptr -> len >= clicks) {
            old_base = ptr -> base;
            ptr -> len -= clicks;
            ptr -> base += clicks;
            
            if ((ptr -> len) > 0)
                return old_base;
            del_slot (prev_ptr, ptr);
            return old_base;
        }
        prev_ptr = ptr;
        ptr = ptr -> next;
    }
return -1;
}

void use_memory () {
    int k;
    while (head != NULL) {
        if(alloc_mem (k = (rand ()%8)) == -1) {
            printf ("wants %i\n", k);
            printf ("Error No Mem");
            exit (1);
        }
        printf ("wants %i\n", k);
        print_list ();
    }
}



int main (void) {
    lin_list_init ();
    print_list ();
    use_memory ();
return 0;
}