bug fixes
authorbdemsky <bdemsky>
Thu, 7 Jul 2011 11:03:34 +0000 (11:03 +0000)
committerbdemsky <bdemsky>
Thu, 7 Jul 2011 11:03:34 +0000 (11:03 +0000)
12 files changed:
Robust/src/Runtime/bamboo/multicoremem.h
Robust/src/Runtime/bamboo/multicoremsg.c
Robust/src/Runtime/bamboo/multicoremsg.h
Robust/src/Runtime/bamboo/multicoreruntime.c
Robust/src/Runtime/bamboo/pmc_forward.c
Robust/src/Runtime/bamboo/pmc_garbage.c
Robust/src/Runtime/bamboo/pmc_garbage.h
Robust/src/Runtime/bamboo/pmc_mem.c
Robust/src/Runtime/bamboo/pmc_queue.c
Robust/src/Runtime/bamboo/pmc_queue.h
Robust/src/Runtime/bamboo/pmc_refupdate.c
Robust/src/Runtime/mem.c

index 4dc93afd74c118b5061643cb6fc672c904c6e0e0..561898f8c8b5c810660e3eb864b587ff5e322a52 100644 (file)
@@ -4,6 +4,7 @@
 #include "Queue.h"
 #include "SimpleHash.h"
 
+#define GC_DEBUG 1
 // data structures for shared memory allocation
 #ifdef TILERA_BME
 #ifdef MGC
index dce9f62f781a3e072f9a107f70748e2c0c636c84..8ce1acf44b7269d35122765c6f0540dc34157d51 100644 (file)
@@ -31,9 +31,11 @@ int msgsizearray[] = {
   1, //TERMINATE,             // 0xDf
   3, //MEMREQUEST,            // 0xE0
   3, //MEMRESPONSE,           // 0xE1
-#ifdef MULTICORE_GC
+#if defined(MULTICORE_GC)||defined(PMC_GC)
   1, //GCINVOKE
   1, //GCSTARTPRE,            // 0xE2
+#endif
+#ifdef MULTICORE_GC
   1, //GCSTARTINIT,           // 0xE3
   1, //GCSTART,               // 0xE4
   2, //GCSTARTCOMPACT,        // 0xE5
@@ -415,9 +417,10 @@ void processmsg_memresponse_I() {
 #endif //ifndef PMCGC
 
 
-#ifdef MULTICORE_GC
+#if defined(MULTICORE_GC)||defined(PMC_GC)
 void processmsg_gcinvoke_I() {
   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE==STARTUPCORE);
+#ifdef MULTICORE_GC
   if(!gc_status_info.gcprocessing && !gcflag) {
     gcflag = true;
     gcprecheck = true;
@@ -426,6 +429,11 @@ void processmsg_gcinvoke_I() {
       gcnumsendobjs[0][i] = 0;
       gcnumreceiveobjs[0][i] = 0;
     }
+#endif
+#ifdef PMC_GC
+  if(!gcflag) {
+    gcflag = true;
+#endif
     for(int i = 0; i < NUMCORES4GC; i++) {
       if(i != STARTUPCORE) {
         if(BAMBOO_CHECK_SEND_MODE()) {
@@ -442,7 +450,8 @@ void processmsg_gcstartpre_I() {
   // the first time to be informed to start gc
   gcflag = true;
 }
-
+#endif
+#ifdef MULTICORE_GC
 void processmsg_gcstartinit_I() {
   gc_status_info.gcphase = INITPHASE;
 }
@@ -913,7 +922,7 @@ processmsg:
       break;
     }
 #endif
-#ifdef MULTICORE_GC
+#if defined(MULTICORE_GC)||defined(PMC_GC)
     // GC msgs
     case GCINVOKE: {
       processmsg_gcinvoke_I();
@@ -924,7 +933,8 @@ processmsg:
       processmsg_gcstartpre_I();
       break;
     }
-       
+#endif
+#ifdef MULTICORE_GC
     case GCSTARTINIT: {
       processmsg_gcstartinit_I();
       break;
index 5c5c092052214309571c276cb8e09cf15a30f4b4..c64f8b2ee98490b65fd29700cf9022c33304af20 100644 (file)
@@ -172,9 +172,11 @@ typedef enum {
   TERMINATE,             // 0xDf
   MEMREQUEST,            // 0xE0
   MEMRESPONSE,           // 0xE1
-#ifdef MULTICORE_GC
+#if defined(MULTICORE_GC)||defined(PMC_GC)
   GCINVOKE,              // 0xE2
   GCSTARTPRE,            // 0xE3
+#endif
+#ifdef MULTICORE_GC
   GCSTARTINIT,           // 0xE4
   GCSTART,               // 0xE5
   GCSTARTCOMPACT,        // 0xE6
index 29e6b397e57ca0335f0892c15323e5100b92e1b3..7ee0a50b0fc56a1ec26db4498ebe81cd900a3491 100644 (file)
@@ -785,6 +785,9 @@ void run(int argc, char** argv) {
   // initialize runtime data structures
   initruntimedata();
   initCommunication();
+#ifdef PMC_GC
+  pmc_onceInit();
+#endif
   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
     numconfirm=NUMCORES-1;
     for(int i=0;i<NUMCORES;i++) {
index dcf767b02589acee802e691e8908302b5f5d5406..804179cbe52b24e8e63d8bc708bef2d5ba0e3fba 100644 (file)
@@ -17,6 +17,7 @@ void pmc_count() {
 
 //Comment: should build dummy byte arrays to allow skipping data...
 void pmc_countbytes(struct pmc_unit * unit, void *bottomptr, void *topptr) {
+  tprintf("%x--%x\n",bottomptr, topptr);
   void *tmpptr=bottomptr;
   unsigned int totalbytes=0;
   while(tmpptr<topptr) {
@@ -79,7 +80,7 @@ void pmc_doforward() {
   if (startregion==-1) 
     return;
   if (endregion==-1)
-    endregion=NUMPMCUNITS;
+    endregion=NUMPMCUNITS-1;
   region->lowunit=startregion;
   region->highunit=endregion;
   region->startptr=(startregion==0)?gcbaseva:pmc_heapptr->units[startregion-1].endptr;
@@ -122,7 +123,7 @@ void pmc_forward(struct pmc_region *region, unsigned int totalbytes, void *botto
     }
   }
 
-  while(tmpptr>topptr) {
+  while(tmpptr<topptr) {
     unsigned int type;
     unsigned int size;
     gettype_size(tmpptr, &type, &size);
index 948268e4fc669097dc83c40260133f553b863208..2c277911d671d3b04f8275e5528757cdeefb6341 100644 (file)
@@ -20,32 +20,75 @@ void decrementthreads() {
 }
 
 void * pmc_unitend(unsigned int index) {
-  return gcbaseva+(index+1)*NUMPMCUNITS;
+  return gcbaseva+(index+1)*UNITSIZE;
 }
 
 void pmc_onceInit() {
   pmc_localqueue=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE].markqueue;
   pmc_queueinit(pmc_localqueue);
-  tmc_spin_barrier_init(&pmc_heapptr->barrier, NUMCORES4GC);
-  for(int i=0;i<NUMPMCUNITS;i++) {
-    pmc_heapptr->units[i].endptr=pmc_unitend(i);
+  if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
+    tmc_spin_barrier_init(&pmc_heapptr->barrier, NUMCORES4GC);
+    for(int i=0;i<NUMPMCUNITS;i++) {
+      pmc_heapptr->units[i].endptr=pmc_unitend(i);
+      tprintf("%u endptr=%x\n", i, pmc_heapptr->units[i].endptr);
+    }
+    
+    for(int i=0;i<NUMCORES4GC;i+=2) {
+      if (i==0) {
+       pmc_heapptr->regions[i].lastptr=gcbaseva;
+      } else
+       pmc_heapptr->regions[i].lastptr=pmc_heapptr->units[i*4-1].endptr;
+      pmc_heapptr->regions[i].lowunit=4*i;
+      pmc_heapptr->regions[i].highunit=4*i+3;
+      pmc_heapptr->regions[i+1].lastptr=pmc_heapptr->units[(i+1)*4+3].endptr;
+      pmc_heapptr->regions[i+1].lowunit=4*(i+1);
+      pmc_heapptr->regions[i+1].highunit=4*(i+1)+3;
+    }
+    for(int i=0;i<NUMCORES4GC;i++) {
+      tprintf("%u lastptr=%x\n", i, pmc_heapptr->regions[i].lastptr);
+    }
   }
 }
 
 void pmc_init() {
   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
     pmc_heapptr->numthreads=NUMCORES4GC;
+    for(int i=0;i<NUMCORES4GC;i+=2) {
+      void *startptr=pmc_heapptr->regions[i].lastptr;
+      void *finishptr=pmc_heapptr->regions[i+1].lastptr;
+      struct pmc_region *region=&pmc_heapptr->regions[i];
+      unsigned int startindex=region->lowunit;
+      unsigned int endindex=pmc_heapptr->regions[i+1].highunit;
+      tprintf("Padding %x-%x\n",startptr, finishptr);
+
+      for(unsigned int index=startindex;index<endindex;index++) {
+       void *ptr=pmc_unitend(index);
+       if ((ptr>startptr)&&(ptr<=finishptr)) {
+         pmc_heapptr->units[index].endptr=ptr;
+         padspace(startptr, (unsigned int)(ptr-startptr));
+         startptr=ptr;
+       }
+       if (ptr>finishptr)
+         break;
+      }
+    }
+  }
+  if (bamboo_smem_size) {
+    tprintf("Padding %u bytes at %x\n", bamboo_smem_size, bamboo_cur_msp);
+    padspace(bamboo_cur_msp, bamboo_smem_size);  
   }
   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
 }
 
 void gc(struct garbagelist *gl) {
+  tprintf("%x\n", pmc_heapptr);
   tprintf("init\n");
   pmc_init();
   //mark live objects
   tprintf("mark\n");
   pmc_mark(gl);
   //count live objects per unit
+  tmc_spin_barrier_wait(&pmc_heapptr->barrier);
   tprintf("count\n");
   pmc_count();
   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
@@ -66,7 +109,32 @@ void gc(struct garbagelist *gl) {
   //compact data
   tprintf("compact\n");
   pmc_docompact();
-  tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+  //reset memory allocation
+  bamboo_cur_msp=NULL;
+  bamboo_smem_size=0;
+
+  if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
+    tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+    //people will resend...no need to get gcflag so quickly
+    gcflag=false;
+  } else {
+    //start to listen for gcflags before we exit
+    gcflag=false;
+    tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+  }
+}
+
+void padspace(void *ptr, unsigned int length) {
+  //zero small blocks
+  if (length<sizeof(struct ArrayObject)) {
+    BAMBOO_MEMSET_WH(ptr,0,length);
+  } else {
+    //generate fake arrays for big blocks
+    struct ArrayObject *ao=(struct ArrayObject *)ptr;
+    ao->type=CHARARRAYTYPE;
+    unsigned arraylength=length-sizeof(struct ArrayObject);
+    ao->___length___=arraylength;
+  }
 }
 
 void gettype_size(void * ptr, int * ttype, unsigned int * tsize) {
index 1662f0c197f94f68d5ee62641e27437c733763c3..ab0f449946581d0dba528cf11aec686d252bcef1 100644 (file)
@@ -4,7 +4,8 @@
 #include "pmc_queue.h"
 #include "structdefs.h"
 
-#define PMC_MINALLOC 131072
+//#define PMC_MINALLOC 131072
+#define PMC_MINALLOC 2048
 #define NUMPMCUNITS (4*NUMCORES4GC)
 #define UNITSIZE (BAMBOO_SHARED_MEM_SIZE/NUMPMCUNITS)
 
@@ -38,6 +39,7 @@ struct pmc_heap {
 extern struct pmc_heap * pmc_heapptr;
 extern struct pmc_queue * pmc_localqueue;
 
+void padspace(void *ptr, unsigned int length);
 void * pmc_unitend(unsigned int index);
 void incrementthreads();
 void decrementthreads();
index a53fb4ba8da8fb966a90bc411112ec21fecf2364..ed36e97c66e89b6ea19d0a140d2d5edf02bb6e4c 100644 (file)
@@ -1,6 +1,10 @@
 #include <stdlib.h>
+#include "multicoregc.h"
+#include "multicoreruntime.h"
 #include "pmc_garbage.h"
 #include "pmc_mem.h"
+#include "runtime_arch.h"
+#include "multicoremsg.h"
 
 void * pmc_alloc(unsigned int * numbytesallocated, unsigned int minimumbytes) {
   unsigned int memcheck=minimumbytes>PMC_MINALLOC?minimumbytes:PMC_MINALLOC;
@@ -39,5 +43,18 @@ void * pmc_alloc(unsigned int * numbytesallocated, unsigned int minimumbytes) {
       tmc_spin_mutex_unlock(&region->lock);
     }
   }
+  if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
+    BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+    if (!gcflag) {
+      gcflag = true;
+      for(int i=0;i<NUMCORESACTIVE;i++) {
+       if (i!=STARTUPCORE)
+         send_msg_1(i, GCSTARTPRE);
+      }
+    }
+    BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+  } else {
+    send_msg_1_I(STARTUPCORE,GCINVOKE);
+  }
   return NULL;
 }
index 7fd822aeecc1871bd4666e2d90b95aecb68ddcaf..32abe8fbbb98696419319f391d95c2a02f51b9f2 100644 (file)
@@ -1,58 +1,50 @@
 #include <stdlib.h>
 #include "pmc_queue.h"
 #include "mem.h"
+#include "runtime_arch.h"
 
 void pmc_queueinit(struct pmc_queue *queue) {
-  queue->head=queue->tail=RUNMALLOC(sizeof(struct pmc_queue_segment));
   queue->headindex=queue->tailindex=0;
 }
 
 void * pmc_dequeue(struct pmc_queue *queue) {
   void *value=NULL;
   tmc_spin_mutex_lock(&queue->lock);
-  //do-while loop allows sharing cleanup code
-  do {
+
+  if (queue->tailindex!=queue->headindex) {
+    value=queue->objects[queue->tailindex];
+    queue->tailindex++;
     //check for possible rollover
     if (queue->tailindex==NUM_PMC_QUEUE_OBJECTS) {
-      if (queue->tail!=queue->head) {
-       struct pmc_queue_segment *oldtail=queue->tail;
-       queue->tail=oldtail->next;
-       queue->tailindex=0;
-       RUNFREE(oldtail);
-      } else break;
-    }
-    //now try to decrement
-    if (queue->tailindex!=queue->headindex) {
-      value=queue->tail->objects[queue->tailindex];
-      queue->tailindex++;
+      queue->tailindex=0;
     }
-  } while(false);
+  }
+
   tmc_spin_mutex_unlock(&queue->lock);
   return value;
 }
 
 void pmc_enqueue(struct pmc_queue* queue, void *ptr) {
-  if (queue->headindex<NUM_PMC_QUEUE_OBJECTS) {
-    queue->head->objects[queue->headindex]=ptr;
-    //need fence to prevent reordering
-    __insn_mf();
-    queue->headindex++;
-    return;
-  } else {
-    struct pmc_queue_segment * seg=RUNMALLOC(sizeof(struct pmc_queue_segment));
-    seg->objects[0]=ptr;
-    //simplify everything by grabbing a lock on segment change
-    tmc_spin_mutex_lock(&queue->lock);
-    queue->headindex=1;
-    queue->head->next=seg;
-    queue->head=seg;
-    tmc_spin_mutex_unlock(&queue->lock);
+  unsigned int currindex=queue->headindex;
+  queue->objects[currindex]=ptr;
+  //need fence to prevent reordering
+  __insn_mf();
+
+  currindex++;
+  if (currindex==NUM_PMC_QUEUE_OBJECTS)
+    currindex=0;
+
+  if (currindex==queue->tailindex) {
+    tprintf("queue full event...\n");
+    BAMBOO_EXIT();
   }
+
+  queue->headindex=currindex;
 }
 
 bool pmc_isEmpty(struct pmc_queue *queue) {
   tmc_spin_mutex_lock(&queue->lock);
-  bool status=(queue->head==queue->tail)&&(queue->headindex==queue->tailindex);
+  bool status=(queue->headindex==queue->tailindex);
   tmc_spin_mutex_unlock(&queue->lock);
   return status;
 }
index dda1350d35fc2eede430478ff92babd9a7f382aa..6afbde0a5d8b0d2b5fbadefbb5390314dcbfc015 100644 (file)
@@ -3,15 +3,10 @@
 #include "multicore.h"
 #include <tmc/spin.h>
 
-#define NUM_PMC_QUEUE_OBJECTS 256
-struct pmc_queue_segment {
-  volatile void * objects[NUM_PMC_QUEUE_OBJECTS];
-  struct pmc_queue_segment * next;
-};
+#define NUM_PMC_QUEUE_OBJECTS 4096
 
 struct pmc_queue {
-  volatile struct pmc_queue_segment *head;
-  volatile struct pmc_queue_segment *tail;
+  volatile void * objects[NUM_PMC_QUEUE_OBJECTS];
   volatile int headindex;
   volatile int tailindex;
   tmc_spin_mutex_t lock;
index d6ccf46016c50d1a6fdf1962786458337f437f3b..5c6120863de2385187f3a592936710887a1203f2 100644 (file)
@@ -8,7 +8,7 @@
 
 #define pmcupdateObj(objptr) ((void *)((struct ___Object___ *)objptr)->marked)
 
-#define PMCUPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) {obj=pmcupdateObj(updatetmpptr);}}
+#define PMCUPDATEOBJ(obj) {void *updatetmpptr=obj; tprintf("UP%x\n", updatetmpptr); if (updatetmpptr!=NULL) {obj=pmcupdateObj(updatetmpptr);}}
 
 #define PMCUPDATEOBJNONNULL(obj) {void *updatetmpptr=obj; obj=pmcupdateObj(updatetmpptr);}
 
@@ -40,10 +40,13 @@ void pmc_doreferenceupdate() {
 
 void pmc_referenceupdate(void *bottomptr, void *topptr) {
   void *tmpptr=bottomptr;
+  tprintf("%x -- %x\n", bottomptr, topptr);
   while(tmpptr<topptr) {
     unsigned int type;
     unsigned int size;
     gettype_size(tmpptr, &type, &size);
+    size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
+    tprintf("%x typ=%u sz=%u\n", tmpptr, type, size);
     if (!type) {
       tmpptr+=ALIGNMENTSIZE;
       continue;
@@ -53,6 +56,7 @@ void pmc_referenceupdate(void *bottomptr, void *topptr) {
       pmc_updatePtrs(tmpptr, type);
     }
     tmpptr+=size;
+    tprintf("INC\n");
   }
 }
 
@@ -69,6 +73,7 @@ void pmc_compact(struct pmc_region * region, int forward, void *bottomptr, void
       unsigned int type;
       unsigned int size;
       gettype_size(tmpptr, &type, &size);
+      size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
       if (!type) {
        tmpptr+=ALIGNMENTSIZE;
        continue;
@@ -90,6 +95,7 @@ void pmc_compact(struct pmc_region * region, int forward, void *bottomptr, void
       unsigned int type;
       unsigned int size;
       gettype_size(lastobj, &type, &size);
+      size=((size-1)&(~(ALIGNMENTSIZE-1)))+ALIGNMENTSIZE;
       void *forwardptr=(void *)((struct ___Object___ *) lastobj)->marked;
       ((struct ___Object___ *) lastobj)->marked=NULL;
       if (forwardptr) {
index d33a6752eec43ff5aed5001f18f0c585cf5790a7..98b9d197a575d843c8e5484a5fdc2f36b6a728df 100644 (file)
@@ -24,7 +24,7 @@ void * mycalloc_share(struct garbagelist * stackptr, int size) {
   int hasgc = 0;
   int loopcount = 0;
 
-  while(loopcount<10000) {
+  while(true) {
     p = BAMBOO_SHARE_MEM_CALLOC(isize); // calloc(m, isize);
 
     if(p != NULL) 
@@ -42,8 +42,11 @@ void * mycalloc_share(struct garbagelist * stackptr, int size) {
       printf("Did %u collections without getting memory\n", hasgc);
       BAMBOO_EXIT();
     }
+    loopcount++;
+    if (loopcount>10000000)
+      tprintf("Loopcount in mycalloc_share hit %u\n",loopcount);
   }
-  tprintf("Loopcount hit 10000\n");
+
   BAMBOO_EXIT();
   return NULL;
 }