start of new file
[IRC.git] / Robust / src / Runtime / garbage.c
index e86f2c1b6d1a7f259b7f12fbf19bb5809c814949..beb67c8613b1e8fbcf9a4dc3a6e03bb7139962ea 100644 (file)
@@ -5,13 +5,16 @@
 #include "SimpleHash.h"
 #include "GenericHashtable.h"
 #include <string.h>
-#ifdef THREADS
+#if defined(THREADS) || defined(DSTM)
 #include "thread.h"
 #endif
+
 #ifdef DMALLOC
 #include "dmalloc.h"
 #endif
-
+#ifdef DSTM
+#include "dstm.h"
+#endif
 
 #define NUMPTRS 100
 
@@ -22,7 +25,9 @@
 
 #ifdef TASK
 extern struct genhashtable * activetasks;
+#ifndef MULTICORE
 extern struct parameterwrapper * objectqueues[NUMCLASSES];
+#endif
 extern struct genhashtable * failedtasks;
 extern struct taskparamdescriptor *currtpd;
 extern struct RuntimeHash *forward;
@@ -30,17 +35,46 @@ extern struct RuntimeHash *reverse;
 extern struct RuntimeHash *fdtoobject;
 #endif
 
-#ifdef THREADS
+#if defined(THREADS) || defined(DSTM)
 int needtocollect=0;
 struct listitem * list=NULL;
 int listcount=0;
 #endif
 
+//Need to check if pointers are transaction pointers
+#ifdef DSTM
+#define ENQUEUE(orig, dst) \
+if ((!(((unsigned int)orig)&0x1))) {\
+if (orig>=curr_heapbase&&orig<curr_heaptop) {\
+void *copy;\
+if (gc_createcopy(orig,&copy))\
+enqueue(orig);\
+dst=copy;\
+}\
+}
+#else
+#define ENQUEUE(orig, dst) \
+void *copy; \
+if (gc_createcopy(orig,&copy))\
+enqueue(orig);\
+dst=copy
+#endif
+
 struct pointerblock {
   void * ptrs[NUMPTRS];
   struct pointerblock *next;
 };
 
+void * curr_heapbase=0;
+void * curr_heapptr=0;
+void * curr_heapgcpoint=0;
+void * curr_heaptop=0;
+
+void * to_heapbase=0;
+void * to_heapptr=0;
+void * to_heaptop=0;
+long lastgcsize=0;
+
 struct pointerblock *head=NULL;
 int headindex=0;
 struct pointerblock *tail=NULL;
@@ -98,7 +132,7 @@ void enqueuetag(struct ___TagDescriptor___ *ptr) {
 
 
 void collect(struct garbagelist * stackptr) {
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
   needtocollect=1;
   pthread_mutex_lock(&gclistlock);
   while(1) {
@@ -124,7 +158,7 @@ void collect(struct garbagelist * stackptr) {
 #endif
 
   /* Check current stack */
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
  {
    struct listitem *listptr=list;
    while(1) {
@@ -134,21 +168,15 @@ void collect(struct garbagelist * stackptr) {
     int i;
     for(i=0;i<stackptr->size;i++) {
       void * orig=stackptr->array[i];
-      void * copy;
-      if (gc_createcopy(orig,&copy))
-       enqueue(orig);
-      stackptr->array[i]=copy;
+      ENQUEUE(orig, stackptr->array[i]);
     }
     stackptr=stackptr->next;
   }
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
   /* Go to next thread */
   if (listptr!=NULL) {
     void * orig=listptr->locklist;
-    void * copy;
-    if (gc_createcopy(orig,&copy))
-      enqueue(orig);
-    listptr->locklist=copy;
+    ENQUEUE(orig, listptr->locklist);
     stackptr=listptr->stackptr;
     listptr=listptr->next;
   } else
@@ -162,22 +190,21 @@ void collect(struct garbagelist * stackptr) {
     /* Update objectsets */
     int i;
     for(i=0;i<NUMCLASSES;i++) {
+#ifdef MULTICORE
+#else
       struct parameterwrapper * p=objectqueues[i];
       while(p!=NULL) {
-       struct RuntimeHash * set=p->objectset;
-       struct RuntimeNode * ptr=set->listhead;
+       struct ObjectHash * set=p->objectset;
+       struct ObjectNode * ptr=set->listhead;
        while(ptr!=NULL) {
          void *orig=(void *)ptr->key;
-         void *copy;
-         if (gc_createcopy(orig, &copy))
-           enqueue(orig);
-         ptr->key=(int)copy;
-         
+         ENQUEUE(orig, *((void **)(&ptr->key)));
          ptr=ptr->lnext;
        }
-       RuntimeHashrehash(set); /* Rehash the table */
+       ObjectHashrehash(set); /* Rehash the table */
        p=p->next;
       }
+#endif
     }
   }
   
@@ -185,11 +212,7 @@ void collect(struct garbagelist * stackptr) {
     struct RuntimeNode * ptr=forward->listhead;
     while(ptr!=NULL) {
       void * orig=(void *)ptr->key;
-      void *copy;
-      if (gc_createcopy(orig, &copy))
-       enqueue(orig);
-      ptr->key=(int)copy;
-
+      ENQUEUE(orig, *((void **)(&ptr->key)));
       ptr=ptr->lnext;
     }
     RuntimeHashrehash(forward); /* Rehash the table */
@@ -199,11 +222,7 @@ void collect(struct garbagelist * stackptr) {
     struct RuntimeNode * ptr=reverse->listhead;
     while(ptr!=NULL) {
       void *orig=(void *)ptr->data;
-      void *copy;
-      if (gc_createcopy(orig, &copy))
-       enqueue(orig);
-      ptr->data=(int)copy;
-
+      ENQUEUE(orig, *((void**)(&ptr->data)));
       ptr=ptr->lnext;
     }
   }
@@ -212,11 +231,7 @@ void collect(struct garbagelist * stackptr) {
     struct RuntimeNode * ptr=fdtoobject->listhead;
     while(ptr!=NULL) {
       void *orig=(void *)ptr->data;
-      void *copy;
-      if (gc_createcopy(orig, &copy))
-       enqueue(orig);
-      ptr->data=(int)copy;
-
+      ENQUEUE(orig, *((void**)(&ptr->data)));
       ptr=ptr->lnext;
     }
   }
@@ -226,10 +241,7 @@ void collect(struct garbagelist * stackptr) {
     int i;
     for(i=0;i<currtpd->numParameters;i++) {
       void *orig=currtpd->parameterArray[i];
-      void *copy;
-      if (gc_createcopy(orig, &copy))
-       enqueue(orig);
-      currtpd->parameterArray[i]=copy;
+      ENQUEUE(orig, currtpd->parameterArray[i]);
     }
 
   }
@@ -242,10 +254,7 @@ void collect(struct garbagelist * stackptr) {
       int i;
       for(i=0;i<tpd->numParameters;i++) {
        void * orig=tpd->parameterArray[i];
-       void * copy;
-       if (gc_createcopy(orig, &copy))
-         enqueue(orig);
-       tpd->parameterArray[i]=copy;
+       ENQUEUE(orig, tpd->parameterArray[i]);
       }
       ptr=ptr->inext;
     }
@@ -260,10 +269,7 @@ void collect(struct garbagelist * stackptr) {
       int i;
       for(i=0;i<tpd->numParameters;i++) {
        void * orig=tpd->parameterArray[i];
-       void * copy;
-       if (gc_createcopy(orig, &copy))
-         enqueue(orig);
-       tpd->parameterArray[i]=copy;
+       ENQUEUE(orig, tpd->parameterArray[i]);
       }
       ptr=ptr->inext;
     }
@@ -288,18 +294,25 @@ void collect(struct garbagelist * stackptr) {
     if (pointer==0) {
       /* Array of primitives */
       /* Do nothing */
+#ifdef DSTM
+      struct ArrayObject *ao=(struct ArrayObject *) ptr;
+      struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
+      ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
+      ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
+#endif
     } else if (((int)pointer)==1) {
       /* Array of pointers */
       struct ArrayObject *ao=(struct ArrayObject *) ptr;
       struct ArrayObject *ao_cpy=(struct ArrayObject *) cpy;
+#ifdef DSTM
+      ENQUEUE((void *)ao->___nextobject___, *((void **)&ao_cpy->___nextobject___));
+      ENQUEUE((void *)ao->___localcopy___, *((void **)&ao_cpy->___localcopy___));
+#endif
       int length=ao->___length___;
       int i;
       for(i=0;i<length;i++) {
        void *objptr=((void **)(((char *)& ao->___length___)+sizeof(int)))[i];
-       void * copy;
-       if (gc_createcopy(objptr, &copy))
-         enqueue(objptr);
-       ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]=copy;
+       ENQUEUE(objptr, ((void **)(((char *)& ao_cpy->___length___)+sizeof(int)))[i]);
       }
     } else {
       int size=pointer[0];
@@ -307,10 +320,7 @@ void collect(struct garbagelist * stackptr) {
       for(i=1;i<=size;i++) {
        unsigned int offset=pointer[i];
        void * objptr=*((void **)(((int)ptr)+offset));
-       void * copy;
-       if (gc_createcopy(objptr, &copy))
-         enqueue(objptr);
-       *((void **) (((int)cpy)+offset))=copy;
+       ENQUEUE(objptr, *((void **) (((int)cpy)+offset)));
       }
     }
   }
@@ -318,13 +328,16 @@ void collect(struct garbagelist * stackptr) {
   fixtags();
 #endif
 
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
   needtocollect=0;
   pthread_mutex_unlock(&gclistlock);
 #endif
 }
 
 #ifdef TASK
+
+/* Fix up the references from tags.  This can't be done earlier,
+   because we don't want tags to keep objects alive */
 void fixtags() {
   while(taghead!=NULL) {
     int i;
@@ -333,7 +346,9 @@ void fixtags() {
       struct ___TagDescriptor___ *tagd=taghead->ptrs[i];
       struct ___Object___ *obj=tagd->flagptr;
       struct ___TagDescriptor___ *copy=((struct ___TagDescriptor___**)tagd)[1];
-      if (obj->type==-1) {
+      if (obj==NULL) {
+       /* Zero object case */
+      } else if (obj->type==-1) {
        /* Single object case */
        copy->flagptr=((struct ___Object___**)obj)[1];
       } else if (obj->type==OBJECTARRAYTYPE) {
@@ -353,6 +368,7 @@ void fixtags() {
        
        livecount=((livecount-1)/OBJECTARRAYINTERVAL+1)*OBJECTARRAYINTERVAL;
        aonew=(struct ArrayObject *) tomalloc(sizeof(struct ArrayObject)+sizeof(struct ___Object___*)*livecount);
+       memcpy(aonew, ao, sizeof(struct ArrayObject));
        aonew->type=OBJECTARRAYTYPE;
        aonew->___length___=livecount;
        copy->flagptr=aonew;
@@ -364,7 +380,9 @@ void fixtags() {
          }
        }
        aonew->___cachedCode___=k;
-       
+       for(;k<livecount;k++) {
+         ARRAYSET(aonew, struct ___Object___*, k, NULL);
+       }
       } else {
        /* No object live anymore */
        copy->flagptr=NULL;
@@ -377,16 +395,6 @@ void fixtags() {
 }
 #endif
 
-void * curr_heapbase=0;
-void * curr_heapptr=0;
-void * curr_heapgcpoint=0;
-void * curr_heaptop=0;
-
-void * to_heapbase=0;
-void * to_heapptr=0;
-void * to_heaptop=0;
-long lastgcsize=0;
-
 void * tomalloc(int size) {
   void * ptr=to_heapptr;
   if ((size%4)!=0)
@@ -395,8 +403,7 @@ void * tomalloc(int size) {
   return ptr;
 }
 
-#ifdef THREADS
-
+#if defined(THREADS)||defined(DSTM)
 void checkcollect(void * ptr) {
   if (needtocollect) {
     struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
@@ -407,6 +414,20 @@ void checkcollect(void * ptr) {
   }
 }
 
+#ifdef DSTM
+void checkcollect2(void * ptr, transrecord_t *trans) {
+  if (needtocollect) {
+    int ptrarray[]={1, (int)ptr, (int) trans->revertlist};
+    struct listitem * tmp=stopforgc((struct garbagelist *)ptrarray);
+    pthread_mutex_lock(&gclock); // Wait for GC
+    restartaftergc(tmp);
+    pthread_mutex_unlock(&gclock);
+    trans->revertlist=(struct ___Object___*)ptrarray[2];
+  }
+}
+#endif
+
+
 struct listitem * stopforgc(struct garbagelist * ptr) {
   struct listitem * litem=malloc(sizeof(struct listitem));
   litem->stackptr=ptr;
@@ -442,7 +463,7 @@ void restartaftergc(struct listitem * litem) {
 
 void * mygcmalloc(struct garbagelist * stackptr, int size) {
   void *ptr;
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
   if (pthread_mutex_trylock(&gclock)!=0) {
     struct listitem *tmp=stopforgc(stackptr);
     pthread_mutex_lock(&gclock);
@@ -466,7 +487,7 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
       to_heaptop=to_heapbase+INITIALHEAPSIZE;
       to_heapptr=to_heapbase;
       ptr=curr_heapbase;
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
       pthread_mutex_unlock(&gclock);
 #endif
       return ptr;
@@ -515,20 +536,20 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
       
       /* Not enough room :(, redo gc */
       if (curr_heapptr>curr_heapgcpoint) {
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
        pthread_mutex_unlock(&gclock);
 #endif
        return mygcmalloc(stackptr, size);
       }
       
       bzero(tmp, curr_heaptop-tmp);
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
       pthread_mutex_unlock(&gclock);
 #endif
       return tmp;
     }
   } else {
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
     pthread_mutex_unlock(&gclock);
 #endif
     return ptr;