Add cgc support
This commit is contained in:
parent
5170ab1501
commit
c308aa8ecc
|
@ -0,0 +1,114 @@
|
||||||
|
#ifndef CGC_H_
|
||||||
|
#define CGC_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define GC_DEFAULT_CAP 16
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void * ptr;
|
||||||
|
size_t id;
|
||||||
|
} GCItem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GCItem * items;
|
||||||
|
size_t size;
|
||||||
|
size_t capacity;
|
||||||
|
} GC;
|
||||||
|
|
||||||
|
typedef size_t GCIndex;
|
||||||
|
|
||||||
|
GC gcInit(void);
|
||||||
|
void gcDeinit(GC gc);
|
||||||
|
void gcGrowBuffer(GC * gc);
|
||||||
|
GCIndex gcAddItem(GC * gc, void * ptr);
|
||||||
|
void * gcAlloc(GC * gc, size_t elemNo, size_t elemSize);
|
||||||
|
void gcUpdateItem(GC * gc, GCIndex id, void * ptr);
|
||||||
|
void * gcGetPtrAt(GC gc, GCIndex id);
|
||||||
|
|
||||||
|
#ifdef CGC_IMPLEMENTATION
|
||||||
|
|
||||||
|
GC gcInit()
|
||||||
|
{
|
||||||
|
void * items = calloc(GC_DEFAULT_CAP, sizeof(GCItem));
|
||||||
|
if (items == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to allocate GC!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GC) {
|
||||||
|
.items = items,
|
||||||
|
.size = 0,
|
||||||
|
.capacity = GC_DEFAULT_CAP,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void gcDeinit(GC gc)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < gc.size; ++i)
|
||||||
|
free(gc.items[i].ptr);
|
||||||
|
|
||||||
|
free(gc.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gcGrowBuffer(GC * gc)
|
||||||
|
{
|
||||||
|
if (gc->items == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: GC is not initialized!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t newCap = gc->capacity * 2;
|
||||||
|
|
||||||
|
void * items = calloc(newCap, sizeof(GCItem));
|
||||||
|
if (items == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to allocate GC!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memcpy(items, gc->items, gc->capacity * sizeof(GCItem));
|
||||||
|
free(gc->items);
|
||||||
|
gc->items = items;
|
||||||
|
gc->capacity = newCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
GCIndex gcAddItem(GC * gc, void * ptr)
|
||||||
|
{
|
||||||
|
if (gc->size >= gc->capacity)
|
||||||
|
gcGrowBuffer(gc);
|
||||||
|
|
||||||
|
gc->size += 1;
|
||||||
|
gc->items[gc->size - 1] = (GCItem) {
|
||||||
|
.id = gc->size - 1,
|
||||||
|
.ptr = ptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
return gc->size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * gcAlloc(GC * gc, size_t elemNo, size_t elemSize)
|
||||||
|
{
|
||||||
|
void * ptr = calloc(elemNo, elemSize);
|
||||||
|
if (ptr == NULL) return NULL;
|
||||||
|
|
||||||
|
gcAddItem(gc, ptr);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gcUpdateItem(GC * gc, GCIndex id, void * ptr)
|
||||||
|
{
|
||||||
|
free(gc->items[id].ptr);
|
||||||
|
gc->items[id].ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * gcGetPtrAt(GC gc, GCIndex id)
|
||||||
|
{
|
||||||
|
return gc.items[id].ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CGC_IMPLEMENTATION
|
||||||
|
|
||||||
|
#endif // CGC_H_
|
34
da.h
34
da.h
|
@ -10,6 +10,9 @@
|
||||||
#define EHAN_IMPLEMENTATION
|
#define EHAN_IMPLEMENTATION
|
||||||
#include "ehan.h"
|
#include "ehan.h"
|
||||||
|
|
||||||
|
#define CGC_IMPLEMENTATION
|
||||||
|
#include "cgc.h"
|
||||||
|
|
||||||
enum daFields {
|
enum daFields {
|
||||||
SIZE = 0,
|
SIZE = 0,
|
||||||
CAPACITY = 1,
|
CAPACITY = 1,
|
||||||
|
@ -73,11 +76,29 @@ void daBzero(dynarr da);
|
||||||
|
|
||||||
#ifdef DA_IMPLEMENTATION
|
#ifdef DA_IMPLEMENTATION
|
||||||
|
|
||||||
|
#ifdef DA_GC
|
||||||
|
GC daGarbageCollector = {0};
|
||||||
|
|
||||||
|
void daInitGC()
|
||||||
|
{
|
||||||
|
daGarbageCollector = gcInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void daDeinitGC()
|
||||||
|
{
|
||||||
|
gcDeinit(daGarbageCollector);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dynarr _daCreate(size_t cap, size_t type, size_t size)
|
dynarr _daCreate(size_t cap, size_t type, size_t size)
|
||||||
{
|
{
|
||||||
size_t realCap = (((int)(cap / 8)) + 1 ) * 8;
|
size_t realCap = (((int)(cap / 8)) + 1 ) * 8;
|
||||||
|
#ifdef DA_GC
|
||||||
|
size_t * da = (size_t *) gcAlloc(&daGarbageCollector, 1, type * realCap + DATA * sizeof(size_t));
|
||||||
|
#else
|
||||||
size_t * da = (size_t *) calloc(1, type * realCap + DATA * sizeof(size_t));
|
size_t * da = (size_t *) calloc(1, type * realCap + DATA * sizeof(size_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (da == NULL)
|
if (da == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -118,7 +139,18 @@ dynarr daResize(dynarr da)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memcpy(newArr, da, daSize(da) * daType(da));
|
memcpy(newArr, da, daSize(da) * daType(da));
|
||||||
|
|
||||||
|
// TODO: Make use of the GCIndex returned from gcAlloc !
|
||||||
|
for (size_t i = 0; i < daGarbageCollector.size; ++i)
|
||||||
|
{
|
||||||
|
if (daGarbageCollector.items[i].ptr == da)
|
||||||
|
gcUpdateItem(&daGarbageCollector, i, newArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef DA_GC
|
||||||
daFree(da);
|
daFree(da);
|
||||||
|
#endif
|
||||||
|
|
||||||
return newArr;
|
return newArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
example.c
19
example.c
|
@ -1,6 +1,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define DA_GC
|
||||||
#define DA_IMPLEMENTATION
|
#define DA_IMPLEMENTATION
|
||||||
#include "da.h"
|
#include "da.h"
|
||||||
|
|
||||||
|
@ -9,12 +10,14 @@
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
daInitGC();
|
||||||
|
|
||||||
dynarr(int) da = daCreate(int, 8);
|
dynarr(int) da = daCreate(int, 8);
|
||||||
dynarr(char *) da2 = daCreate(char *, 8);
|
dynarr(char *) da2 = daCreate(char *, 8);
|
||||||
dynarr(float) da3 = daCreate(float, 1);
|
dynarr(float) da3 = daCreate(float, 1);
|
||||||
if (!da) goto cleanup;
|
if (!da) goto exit;
|
||||||
if (!da2) goto cleanup;
|
if (!da2) goto exit;
|
||||||
if (!da3) goto cleanup;
|
if (!da3) goto exit;
|
||||||
|
|
||||||
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
||||||
printf("errno: %d\n", errno);
|
printf("errno: %d\n", errno);
|
||||||
|
@ -24,7 +27,7 @@ int main(void)
|
||||||
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
||||||
|
|
||||||
da = daResize(da);
|
da = daResize(da);
|
||||||
if (!da) goto cleanup;
|
if (!da) goto exit;
|
||||||
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
|
||||||
|
|
||||||
printf("DA2 -----\n");
|
printf("DA2 -----\n");
|
||||||
|
@ -36,7 +39,7 @@ int main(void)
|
||||||
for (size_t i = 0; i < N; ++i)
|
for (size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
daAppend(da2, "AAA");
|
daAppend(da2, "AAA");
|
||||||
if (errno == 1) goto cleanup;
|
if (errno == 1) goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s%s\n", da2[0], da2[1]);
|
printf("%s%s\n", da2[0], da2[1]);
|
||||||
|
@ -48,10 +51,8 @@ int main(void)
|
||||||
daAppend(da3, 420.420);
|
daAppend(da3, 420.420);
|
||||||
printf("%.2f:%.3f\n", da3[0], da3[1]);
|
printf("%.2f:%.3f\n", da3[0], da3[1]);
|
||||||
|
|
||||||
cleanup:
|
exit:
|
||||||
daFree(da3);
|
daDeinitGC();
|
||||||
daFree(da2);
|
|
||||||
daFree(da);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue