summaryrefslogtreecommitdiff
path: root/support/spelchek/heap.c
blob: 2d12e52df42b05210f2b55bc472c50b748e7f956 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>

#define  align(d)	(((d)+(sizeof(void*)-1))&(~(sizeof(void*)-1)))

#define HEAPIMPLEMENTATION

typedef struct{
    struct heap_block *first;
    struct heap_block *last;
    long blocksize;
    char *top_of_heap;
}heap;

struct heap_block{
    struct heap_block *next;
    long free;
};    

#include"heap.h"

heap *heap_create( long block_size )          /* allocates memory for heap */
{
    heap *HEAP;
    HEAP = ( heap * )malloc( align( block_size) + sizeof(heap)+sizeof(struct heap_block));
    if(NULL == HEAP)return(NULL);
    HEAP->first = (struct heap_block*)(HEAP+1);
    HEAP->last = HEAP->first;
    HEAP->blocksize = align( block_size );
    HEAP->top_of_heap = (char *)(HEAP->last+1); /* next free entry */
    HEAP->first->next = NULL;
    HEAP->first->free = block_size;
    return(HEAP);
}                                               /* heap_create() */


void *heap_allocate( heap *HEAP, long size ) /* allocates on heap */
{
    void *help;
    if ( HEAP->last->free < size )
    {
        if( NULL ==(HEAP->last->next = ( struct heap_block * )malloc( HEAP->blocksize+sizeof(struct heap_block))))return(NULL);
        HEAP->last = HEAP->last->next;
        HEAP->last->next = NULL;
        HEAP->last->free = HEAP->blocksize;
        HEAP->top_of_heap = (void *)(HEAP->last+1); /* next free entry */
    }
    help = HEAP->top_of_heap;
    HEAP->top_of_heap += (align(size) + sizeof(char) -1) / sizeof(char);
    HEAP->last->free -= align(size);
    return(help);    
}                                                   /* heap_allocate() */
void heap_resize( heap *HEAP, void *entry, long size )
{
    HEAP->last->free += HEAP->top_of_heap - ( (char *)entry + align( size ) );
    HEAP->top_of_heap = (char *)entry + align( size );
}										/* heap_resize() */

void heap_delete( heap *HEAP )
{
    struct heap_block *this, *next;
    this = HEAP->first;
	free(HEAP);
	while(this)
	{
		next = this->next;
		free(this);
		this = next;
	}						/* of while(this) */
}							/* of heap_delete() */