mymalloc.c


1
MyHeap myHeapInitialize(uint16_t heap_size)
2
{
3
4
    void* heap_buffer  = (void *) calloc(heap_size,sizeof(uint8_t));
5
    MyHeap heap =
6
    {
7
        .memory_ = heap_buffer,
8
        .size_ = heap_size,
9
        .freeList_ = heap_buffer,
10
    };
11
    heap.freeList_->size=heap_size - sizeof(struct block);
12
    heap.freeList_->free=true;
13
    heap.freeList_->next=NULL;
14
    return heap;
15
}
16
17
18
void myHeapSplit(struct block *fitting_slot,uint16_t size)
19
{
20
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
21
    {
22
    struct block *new=(void*)((void*)fitting_slot+size+sizeof(struct block));
23
    new->size=(fitting_slot->size)-size-sizeof(struct block);
24
    new->free=true;
25
    new->next=fitting_slot->next;
26
    fitting_slot->size=size;
27
    fitting_slot->free=false;
28
    fitting_slot->next=new;
29
    }
30
}
31
32
void* myHeapMalloc(MyHeap *heap, uint16_t size)
33
{
34
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
35
    {
36
    uint16_t min_size = 65535-sizeof(struct block);
37
    struct block *current = heap->freeList_;
38
    struct block *best_fit_block = NULL;
39
40
    do
41
    {
42
        if(current->free && current->size == size) //exact fit
43
        {
44
           current->free = false;
45
           return (void*)++current;
46
        }
47
48
        if((current->free == true) && (current->next !=NULL) && (current->next->free == true)) //merge
49
        {
50
            current->size+=(current->next->size)+sizeof(struct block);
51
            current->next=current->next->next;
52
        }
53
54
        if((current->free) && (current->size > size + sizeof(struct block)) && (current->size < min_size + sizeof(struct block) )) //best fit
55
        {
56
            best_fit_block = current;
57
            min_size = current->size;
58
        }
59
        current = current->next;
60
    }while (current != NULL);
61
62
    //we neeeeeeeed split step
63
    if(best_fit_block != NULL)
64
    {
65
        myHeapSplit(best_fit_block,size);
66
        return (void*) ++best_fit_block;
67
    }
68
    }
69
    return NULL;
70
}
71
72
73
void myHeapMerge(MyHeap *heap)
74
{
75
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
76
    {
77
    struct block *curr;
78
    curr=heap->freeList_;
79
    while(curr->next != NULL){
80
        if((curr->free == true) && (curr->next->free == true))
81
        {
82
            curr->size+=(curr->next->size)+sizeof(struct block);
83
            curr->next=curr->next->next;
84
        }
85
        else
86
        {
87
            //prev=curr;
88
            curr=curr->next;
89
        }
90
    }
91
    }
92
}
93
94
uint16_t myHeapCountBlocks(MyHeap *heap)
95
{
96
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
97
    {
98
    uint16_t blocks = 0;
99
    struct block *curr;
100
    curr=heap->freeList_;
101
    do
102
    {
103
        blocks++;
104
        curr=curr->next;
105
        if (blocks > heap->size_)
106
            return blocks;
107
    }
108
    while((curr->next)!=NULL);
109
    return blocks;
110
    }
111
    return 0;
112
}
113
114
uint16_t myHeapCountFreeBlocks(MyHeap *heap)
115
{
116
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
117
    {
118
    uint16_t blocks = 0;
119
    struct block *curr;
120
    curr=heap->freeList_;
121
    do{
122
        if (curr->free)
123
            blocks++;
124
        curr=curr->next;
125
        if (blocks > heap->size_)
126
            return blocks;
127
    }
128
    while((curr->next)!=NULL);
129
    return blocks;
130
    }
131
    return 0;
132
}
133
134
uint16_t myHeapCountUsedBlocks(MyHeap *heap)
135
{
136
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
137
    {
138
    uint16_t blocks = 0;
139
    struct block *curr;
140
    curr=heap->freeList_;
141
    do{
142
        if (!curr->free)
143
            blocks++;
144
        curr=curr->next;
145
        if (blocks > heap->size_)
146
            return blocks;
147
    }while((curr->next)!=NULL);
148
    return blocks;
149
    }
150
    return 0;
151
}
152
153
void myHeapFree(MyHeap *heap,void* ptr)
154
{
155
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
156
    {
157
    if(((void*)heap->memory_<=ptr)&&(ptr<=(void*)(heap->memory_ + heap->size_))){
158
        struct block* curr=ptr;
159
        --curr;
160
        curr->free=true;
161
        //myHeapMerge(heap);
162
        ptr = NULL;
163
    }
164
    else
165
    {
166
        PORTA.OUTSET = PIN4_bm;
167
    }
168
    }
169
}