Correctness without cycles tested.

Dieser Commit ist enthalten in:
Lixfel 2023-03-16 15:52:22 +01:00
Ursprung 412ca96760
Commit 1cee0d900a
4 geänderte Dateien mit 55 neuen und 71 gelöschten Zeilen

1
.gitignore vendored
Datei anzeigen

@ -1,2 +1,3 @@
/cmake-build-debug
/cmake-build-release
/.idea

Datei anzeigen

@ -85,30 +85,30 @@ typedef struct Node0_struct {
int i, j;
} Node0;
#ifdef HOLES
# define HOLE() GC_NEW(Node0);
#else
# define HOLE()
#endif
typedef Rl* Node;
#define TO_NODE(rl) ((Node0*) (rl)->ref)
#ifdef DEBUG
int allocated = 0;
int freed = 0;
#endif
void init_Node(Node me, Node l, Node r) {
Node0* node = TO_NODE(me);
rl_set(&node->left, me->ref, l);
rl_set(&node->right, me->ref, r);
}
#ifndef GC
void destroy_Node(void* me) {
#ifdef DEBUG
freed++;
#endif
Node0* node = (Node0*)me;
if(node->left.ref)
rl_free(&node->left);
if(node->right.ref)
rl_free(&node->right);
}
#endif
// Nodes used by a tree of a given size
static int TreeSize(int i) {
@ -129,13 +129,11 @@ static void Populate(int iDepth, Node thisNode) {
return;
} else {
iDepth--;
# ifdef GC
thisNode->left = GC_NEW(Node0); HOLE();
thisNode->right = GC_NEW(Node0); HOLE();
# else
rl_alloc(&node->left, node, sizeof(Node0), destroy_Node);
rl_alloc(&node->right, node, sizeof(Node0), destroy_Node);
# endif
#ifdef DEBUG
allocated+=2;
#endif
Populate (iDepth, &node->left);
Populate (iDepth, &node->right);
}
@ -144,26 +142,23 @@ static void Populate(int iDepth, Node thisNode) {
// Build tree bottom-up
static void MakeTree(Node result, int iDepth) {
if (iDepth<=0) {
# ifndef GC
rl_alloc(result, NULL, sizeof(Node0), destroy_Node);
#ifdef DEBUG
allocated++;
#endif
Node0* node = TO_NODE(result);
node->left.ref = NULL;
node->right.ref = NULL;
# else
result = GC_NEW(Node0); HOLE();
# endif
/* result is implicitly initialized in both cases. */
} else {
Rl left, right;
MakeTree(&left, iDepth-1);
MakeTree(&right, iDepth-1);
# ifndef GC
rl_alloc(result, NULL, sizeof(Node0), destroy_Node);
# else
result = GC_NEW(Node0); HOLE();
# endif
#ifdef DEBUG
allocated++;
#endif
init_Node(result, &left, &right);
printf("Set works\n");
rl_free(&left);
rl_free(&right);
}
@ -190,15 +185,9 @@ static void TimeConstruction(int depth) {
tStart = currentTime();
for (i = 0; i < iNumIters; ++i) {
# ifndef GC
rl_alloc(&tempTree, NULL, sizeof(Node0), destroy_Node);
# else
tempTree = GC_NEW(Node0);
# endif
Populate(depth, &tempTree);
# ifndef GC
rl_free(&tempTree);
# endif
}
tFinish = currentTime();
printf("\tTop down construction took %d msec\n",
@ -207,9 +196,7 @@ static void TimeConstruction(int depth) {
tStart = currentTime();
for (i = 0; i < iNumIters; ++i) {
MakeTree(&tempTree, depth);
# ifndef GC
rl_free(&tempTree);
# endif
}
tFinish = currentTime();
printf("\tBottom up construction took %d msec\n",
@ -219,18 +206,13 @@ static void TimeConstruction(int depth) {
int main() {
Node root;
Node longLivedTree;
Rl longLivedTree;
Rl tempTree;
long tStart, tFinish;
long tElapsed;
int i, d;
double *array;
#ifdef GC
// GC_full_freq = 30;
// GC_free_space_divisor = 16;
// GC_enable_incremental();
#endif
printf("Garbage Collector Test\n");
printf(" Live storage will peak at %d bytes.\n\n",
2 * sizeof(Node0) * TreeSize(kLongLivedTreeDepth) +
@ -246,32 +228,27 @@ int main() {
// Stretch the memory space quickly
MakeTree(&tempTree, kStretchTreeDepth);
printf("Made tree\n");
# ifndef GC
#ifdef DEBUG
printf("Made tree %i/%i\n", freed, allocated);
#endif
rl_free(&tempTree);
# endif
#ifdef DEBUG
printf("Deleted tree %i/%i\n", freed, allocated);
#endif
// Create a long lived object
printf(" Creating a long-lived binary tree of depth %d\n",
kLongLivedTreeDepth);
# ifndef GC
rl_alloc(longLivedTree, NULL, sizeof(Node0), destroy_Node);
# else
longLivedTree = GC_NEW(Node0);
# endif
Populate(kLongLivedTreeDepth, longLivedTree);
rl_alloc(&longLivedTree, NULL, sizeof(Node0), destroy_Node);
Populate(kLongLivedTreeDepth, &longLivedTree);
#ifdef DEBUG
printf("Populated tree %i/%i\n", freed, allocated);
#endif
// Create long-lived array, filling half of it
printf(" Creating a long-lived array of %d doubles\n", kArraySize);
# ifndef GC
array = malloc(kArraySize * sizeof(double));
# else
# ifndef NO_PTRFREE
array = GC_MALLOC_ATOMIC(sizeof(double) * kArraySize);
# else
array = GC_MALLOC(sizeof(double) * kArraySize);
# endif
# endif
for (i = 0; i < kArraySize/2; ++i) {
array[i] = 1.0/i;
}
@ -280,8 +257,11 @@ int main() {
for (d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) {
TimeConstruction(d);
}
#ifdef DEBUG
printf("Smol trees %i/%i\n", freed, allocated);
#endif
if (longLivedTree == 0 || array[1000] != 1.0/1000)
if (longLivedTree.ref == 0 || array[1000] != 1.0/1000)
fprintf(stderr, "Failed\n");
// fake reference to LongLivedTree
// and array
@ -291,10 +271,6 @@ int main() {
tElapsed = elapsedTime(tFinish-tStart);
PrintDiagnostics();
printf("Completed in %d msec\n", tElapsed);
# ifdef GC
printf("Completed %d collections\n", GC_gc_no);
printf("Heap size is %d\n", GC_get_heap_size());
# endif
# ifdef PROFIL
dump_profile();
# endif

29
rl.c
Datei anzeigen

@ -10,27 +10,29 @@ struct RlBox {
};
#define RLBOX_SIZE sizeof(struct RlBox)
#define PTR_TO_RLBOX(ptr) ((struct RlBox*)((ptr) - RLBOX_SIZE))
#define PTR_TO_RLBOX(ptr) ((struct RlBox*)(((void*)ptr) - RLBOX_SIZE))
inline void rl_alloc(Rl* reference, const void* owner, const size_t size, const Destructor destructor) {
struct RlBox* box = (struct RlBox*) malloc(RLBOX_SIZE + size);
box->marked = false;
box->first = NULL;
box->last = NULL;
box->first = reference;
box->last = reference;
box->destructor = destructor;
reference->prev = NULL;
reference->next = NULL;
reference->owner = PTR_TO_RLBOX(owner);
reference->ref = box + RLBOX_SIZE;
reference->owner = owner ? PTR_TO_RLBOX(owner) : NULL;
reference->ref = (void*)box + RLBOX_SIZE;
}
// reference may not point to a valid object
inline void rl_set(Rl* reference, const void* owner, const Rl* copy) {
reference->prev = PTR_TO_RLBOX(copy->ref)->last;
struct RlBox* obj = PTR_TO_RLBOX(copy->ref);
reference->prev = obj->last;
reference->next = NULL;
reference->owner = PTR_TO_RLBOX(owner);
reference->owner = owner ? PTR_TO_RLBOX(owner) : NULL;
reference->ref = copy->ref;
reference->prev->next = reference;
obj->last->next = reference;
obj->last = reference;
}
static void unmark(struct RlBox* obj) {
@ -94,8 +96,13 @@ inline void rl_free(Rl* reference) {
return;
}
if(search_root(obj))
return;
if(reference->next) {
obj->first = reference->next;
reference->next->prev = NULL;
if(search_root(obj))
return;
}
obj->destructor(reference->ref);
free(obj);

4
rl.h
Datei anzeigen

@ -5,10 +5,10 @@ typedef struct Rl Rl;
typedef void (*Destructor)(void*);
struct Rl {
void* ref;
struct RlBox* owner;
Rl* prev;
Rl* next;
struct RlBox* owner;
void* ref;
};
/*