summaryrefslogtreecommitdiff
path: root/support/spelchek/heap.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/spelchek/heap.c
Initial commit
Diffstat (limited to 'support/spelchek/heap.c')
-rw-r--r--support/spelchek/heap.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/support/spelchek/heap.c b/support/spelchek/heap.c
new file mode 100644
index 0000000000..2d12e52df4
--- /dev/null
+++ b/support/spelchek/heap.c
@@ -0,0 +1,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() */
+