initial multicore gargbage collection, not finish yet
[IRC.git] / Robust / src / Runtime / garbage.c
index f6c43d688cd1f5a75c5a7b9721a890a96d3abf09..e43dd3cb3e067e0f3cf025cc56530f096b4c3f8c 100644 (file)
 #ifdef STM
 #include "tm.h"
 #endif
+#ifdef DELAYCOMP
+#include "delaycomp.h"
+#endif
+
 
 #define NUMPTRS 100
 
-#define INITIALHEAPSIZE 128*1024*1024
-#define GCPOINT(x) ((int)((x)*0.95))
+#define INITIALHEAPSIZE 256*1024*1024L
+#define GCPOINT(x) ((INTPTR)((x)*0.99))
 /* This define takes in how full the heap is initially and returns a new heap size to use */
-#define HEAPSIZE(x,y) ((int)(x+y))*2
+#define HEAPSIZE(x,y) ((INTPTR)(x+y))*2
 
 #ifdef TASK
 extern struct genhashtable * activetasks;
@@ -39,6 +43,11 @@ extern struct ctable *reverse;
 extern struct RuntimeHash *fdtoobject;
 #endif
 
+#ifdef GARBAGESTATS
+#define MAXSTATS 500
+long garbagearray[MAXSTATS];
+#endif
+
 #if defined(THREADS) || defined(DSTM) || defined(STM)
 int needtocollect=0;
 struct listitem * list=NULL;
@@ -56,7 +65,7 @@ __thread struct listitem litem;
     if (orig>=curr_heapbase&&orig<curr_heaptop) { \
       void *copy; \
       if (gc_createcopy(orig,&copy)) \
-       enqueue(orig);\
+       enqueue(copy);\
       dst=copy; \
     } \
   }
@@ -65,14 +74,14 @@ __thread struct listitem litem;
   if (orig>=curr_heapbase&&orig<curr_heaptop) { \
     void *copy; \
     if (gc_createcopy(orig,&copy)) \
-      enqueue(orig);\
+      enqueue(copy);\
     dst=copy; \
   }
 #define SENQUEUE(orig, dst) \
   { \
     void *copy; \
     if (gc_createcopy(orig,&copy)) \
-      enqueue(orig);\
+      enqueue(copy);\
     dst=copy; \
   }
 #elif defined(FASTCHECK)
@@ -80,13 +89,13 @@ __thread struct listitem litem;
   if (((unsigned int)orig)!=1) { \
     void *copy; \
     if (gc_createcopy(orig,&copy)) \
-      enqueue(orig);\
+      enqueue(copy);\
     dst=copy; }
 #else
 #define ENQUEUE(orig, dst) \
   void *copy; \
   if (gc_createcopy(orig,&copy)) \
-    enqueue(orig);\
+    enqueue(copy);\
   dst=copy
 #endif
 
@@ -286,6 +295,18 @@ void collect(struct garbagelist * stackptr) {
     pthread_cond_wait(&gccond, &gclistlock);
   }
 #endif
+#ifdef DELAYCOMP
+  ptrstack.prev=stackptr;
+  stackptr=(struct garbagelist *) &ptrstack;
+#endif
+
+#ifdef GARBAGESTATS
+  {
+    int i;
+    for(i=0;i<MAXSTATS;i++)
+      garbagearray[i]=0;
+  }
+#endif
 
   if (head==NULL) {
     headindex=0;
@@ -465,7 +486,7 @@ void collect(struct garbagelist * stackptr) {
 
   while(moreItems()) {
     void * ptr=dequeue();
-    void *cpy=((void **)ptr)[1];
+    void *cpy=ptr;
     int type=((int *)cpy)[0];
     unsigned INTPTR * pointer;
 #ifdef TASK
@@ -599,23 +620,24 @@ void * tomalloc(int size) {
 #if defined(THREADS)||defined(DSTM)||defined(STM)
 void checkcollect(void * ptr) {
   stopforgc((struct garbagelist *)ptr);
-  pthread_mutex_lock(&gclock); // Wait for GC
   restartaftergc();
-  pthread_mutex_unlock(&gclock);
 }
 
 #ifdef DSTM
 void checkcollect2(void * ptr) {
   int ptrarray[]={1, (int)ptr, (int) revertlist};
   stopforgc((struct garbagelist *)ptrarray);
-  pthread_mutex_lock(&gclock); // Wait for GC
   restartaftergc();
-  pthread_mutex_unlock(&gclock);
   revertlist=(struct ___Object___*)ptrarray[2];
 }
 #endif
 
 void stopforgc(struct garbagelist * ptr) {
+#ifdef DELAYCOMP
+  //just append us to the list
+  ptrstack.prev=ptr;
+  ptr=(struct garbagelist *) &ptrstack;
+#endif
 #ifndef MAC
   litem.stackptr=ptr;
 #ifdef THREADS
@@ -650,6 +672,10 @@ void stopforgc(struct garbagelist * ptr) {
 }
 
 void restartaftergc() {
+  if (needtocollect) {
+    pthread_mutex_lock(&gclock); // Wait for GC
+    pthread_mutex_unlock(&gclock);
+  }
   pthread_mutex_lock(&gclistlock);
   listcount--;
   pthread_mutex_unlock(&gclistlock);
@@ -662,7 +688,7 @@ void * helper(struct garbagelist *, int);
 void * mygcmalloc(struct garbagelist * stackptr, int size) {
   if ((size&7)!=0)
     size=(size&~7)+8;
-  if (memorybase==NULL||(memorybase+size)>memorytop) {
+  if (memorybase==NULL||size>(memorytop-memorybase)) {
     int toallocate=(size>MEMORYBLOCK)?size:MEMORYBLOCK;
     memorybase=helper(stackptr, toallocate);
     memorytop=memorybase+toallocate;
@@ -678,9 +704,8 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
 #endif
   void *ptr;
 #if defined(THREADS)||defined(DSTM)||defined(STM)
-  if (pthread_mutex_trylock(&gclock)!=0) {
+  while (pthread_mutex_trylock(&gclock)!=0) {
     stopforgc(stackptr);
-    pthread_mutex_lock(&gclock);
     restartaftergc();
   }
 #endif
@@ -688,12 +713,12 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
   if ((size&7)!=0)
     size=(size&~7)+8;
   curr_heapptr+=size;
-  if (curr_heapptr>curr_heapgcpoint) {
+  if (curr_heapptr>curr_heapgcpoint||curr_heapptr<curr_heapbase) {
     if (curr_heapbase==0) {
       /* Need to allocate base heap */
       curr_heapbase=malloc(INITIALHEAPSIZE);
       if (curr_heapbase==NULL) {
-       printf("malloc failed\n");
+       printf("malloc failed.  Garbage collector couldn't get enough memory.  Try changing heap size.\n");
        exit(-1);
       }
       bzero(curr_heapbase, INITIALHEAPSIZE);
@@ -703,7 +728,7 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
 
       to_heapbase=malloc(INITIALHEAPSIZE);
       if (to_heapbase==NULL) {
-       printf("malloc failed\n");
+       printf("malloc failed.  Garbage collector couldn't get enough memory.  Try changing heap size.\n");
        exit(-1);
       }
       to_heaptop=to_heapbase+INITIALHEAPSIZE;
@@ -717,9 +742,9 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
 
     /* Grow the to heap if necessary */
     {
-      int curr_heapsize=curr_heaptop-curr_heapbase;
-      int to_heapsize=to_heaptop-to_heapbase;
-      int last_heapsize=0;
+      INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
+      INTPTR to_heapsize=to_heaptop-to_heapbase;
+      INTPTR last_heapsize=0;
       if (lastgcsize>0) {
        last_heapsize=HEAPSIZE(lastgcsize, size);
        if ((last_heapsize&7)!=0)
@@ -749,6 +774,13 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
     printf("Garbage collected: Old bytes: %u\n", curr_heapptr-curr_heapbase);
     printf("New space: %u\n", to_heapptr-to_heapbase);
     printf("Total space: %u\n", to_heaptop-to_heapbase);
+    {
+      int i;
+      for(i=0;i<MAXSTATS;i++) {
+       if (garbagearray[i]!=0)
+         printf("Type=%d Size=%u\n", i, garbagearray[i]);
+      }
+    }
 #endif
     /* Flip to/curr heaps */
     {
@@ -809,6 +841,9 @@ int gc_createcopy(void * orig, void ** copy_ptr) {
       int size=classsize[type];
       void *newobj=tomalloc(size);
       memcpy(newobj, orig, size);
+#endif
+#ifdef GARBAGESTATS
+      garbagearray[type]+=size;
 #endif
       ((int *)orig)[0]=-1;
       ((void **)orig)[1]=newobj;
@@ -829,7 +864,9 @@ int gc_createcopy(void * orig, void ** copy_ptr) {
       void *newobj=tomalloc(size);
       memcpy(newobj, orig, size);
 #endif
-
+#ifdef GARBAGESTATS
+      garbagearray[type]+=size;
+#endif
       ((int *)orig)[0]=-1;
       ((void **)orig)[1]=newobj;
       *copy_ptr=newobj;