diff --git a/.gitignore b/.gitignore index 2f88b18..50c6382 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /cmake-build-debug +/cmake-build-release /.idea diff --git a/RLBench.c b/RLBench.c index aa8f788..a482ba0 100644 --- a/RLBench.c +++ b/RLBench.c @@ -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 diff --git a/rl.c b/rl.c index 9ec4145..6b7e224 100644 --- a/rl.c +++ b/rl.c @@ -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); diff --git a/rl.h b/rl.h index 1aff91a..b117ef6 100644 --- a/rl.h +++ b/rl.h @@ -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; }; /*