add primitive support for multithreading
authorbdemsky <bdemsky>
Fri, 16 Feb 2007 04:00:27 +0000 (04:00 +0000)
committerbdemsky <bdemsky>
Fri, 16 Feb 2007 04:00:27 +0000 (04:00 +0000)
12 files changed:
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Flat/BuildFlat.java
Robust/src/IR/Flat/FKind.java
Robust/src/IR/Flat/FlatBackEdge.java [new file with mode: 0644]
Robust/src/IR/State.java
Robust/src/Main/Main.java
Robust/src/Runtime/garbage.c
Robust/src/Runtime/garbage.h
Robust/src/Runtime/runtime.h
Robust/src/Runtime/thread.c [new file with mode: 0644]
Robust/src/Runtime/thread.h [new file with mode: 0644]
Robust/src/buildscript

index 361c5da4db51958722111f15830f912dfc978e08..fc5d90ea427ec6d4a7fa9747ff32d99158773157 100644 (file)
@@ -80,10 +80,19 @@ public class BuildCode {
        /* Build the virtual dispatch tables */
        buildVirtualTables(outvirtual);
 
+
        /* Output includes */
-       outstructs.println("#include \"classdefs.h\"");
+
+       outmethodheader.println("#ifndef METHODHEADERS_H");
+       outmethodheader.println("#define METHODHEADERS_H");
        outmethodheader.println("#include \"structdefs.h\"");
 
+       outstructs.println("#ifndef STRUCTDEFS_H");
+       outstructs.println("#define STRUCTDEFS_H");
+       outstructs.println("#include \"classdefs.h\"");
+
+
+
        /* Output types for short array and string */
        outstructs.println("#define STRINGARRAYTYPE "+
                           (state.getArrayNumber(
@@ -158,6 +167,8 @@ public class BuildCode {
            generateTaskStructs(outstructs, outmethodheader);
        }
 
+       outmethodheader.println("#endif");
+
        outmethodheader.close();
 
        /* Build the actual methods */
@@ -272,6 +283,8 @@ public class BuildCode {
                outmethod.println("   }");
                break;
            }
+           if (state.THREAD)
+               outmethod.println("pthread_exit();");
            outmethod.println("}");
        }
        if (state.TASK)
@@ -283,6 +296,7 @@ public class BuildCode {
            buildRepairStructs(outrepairstructs);
            outrepairstructs.close();
        }
+       outstructs.println("#endif");
 
        outstructs.close();
        outmethod.close();
@@ -902,6 +916,10 @@ public class BuildCode {
            }
        }
 
+       if (state.THREAD&&GENERATEPRECISEGC) {
+           output.println("checkcollect(&"+localsprefix+");");
+       }
+       
        //Do the actual code generation
        tovisit=new HashSet();
        visited=new HashSet();
@@ -1006,6 +1024,12 @@ public class BuildCode {
        case FKind.FlatNop:
            output.println("/* nop */");
            return;
+       case FKind.FlatBackEdge:
+           if (state.THREAD&&GENERATEPRECISEGC) {
+               output.println("checkcollect(&"+localsprefix+");");
+           } else
+               output.println("/* nop */");
+           return;
        case FKind.FlatCheckNode:
            generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
            return;
index e01e1d309058899053b66ad1bc79eca74a77e0df..3ff20b0f0d0393d06aaa0578cde62a0b00b4a4de 100644 (file)
@@ -688,10 +688,12 @@ public class BuildFlat {
            FlatNode begin=initializer.getBegin();
            FlatCondBranch fcb=new FlatCondBranch(cond_temp);
            FlatNop nopend=new FlatNop();
+           FlatBackEdge backedge=new FlatBackEdge();
 
            initializer.getEnd().addNext(condition.getBegin());
            body.getEnd().addNext(update.getBegin());
-           update.getEnd().addNext(condition.getBegin());
+           update.getEnd().addNext(backedge);
+           backedge.addNext(condition.getBegin());
            condition.getEnd().addNext(fcb);
            fcb.addFalseNext(nopend);
            fcb.addTrueNext(body.getBegin());
@@ -703,8 +705,11 @@ public class BuildFlat {
            FlatNode begin=condition.getBegin();
            FlatCondBranch fcb=new FlatCondBranch(cond_temp);
            FlatNop nopend=new FlatNop();
+           FlatBackEdge backedge=new FlatBackEdge();
+
+           body.getEnd().addNext(backedge);
+           backedge.addNext(condition.getBegin());
 
-           body.getEnd().addNext(condition.getBegin());
            condition.getEnd().addNext(fcb);
            fcb.addFalseNext(nopend);
            fcb.addTrueNext(body.getBegin());
@@ -716,11 +721,13 @@ public class BuildFlat {
            FlatNode begin=body.getBegin();
            FlatCondBranch fcb=new FlatCondBranch(cond_temp);
            FlatNop nopend=new FlatNop();
+           FlatBackEdge backedge=new FlatBackEdge();
 
            body.getEnd().addNext(condition.getBegin());
            condition.getEnd().addNext(fcb);
            fcb.addFalseNext(nopend);
-           fcb.addTrueNext(body.getBegin());
+           fcb.addTrueNext(backedge);
+           backedge.addNext(body.getBegin());
            return new NodePair(begin,nopend);
        } else throw new Error();
     }
index a348540a51238935832325d41f269a3d4a738b93..264e571187d0c9397a1c444f19bacaac7687bc74 100644 (file)
@@ -15,4 +15,5 @@ public class FKind {
     public static final int FlatElementNode=12;
     public static final int FlatFlagActionNode=13;
     public static final int FlatCheckNode=14;
+    public static final int FlatBackEdge=15;    
 }
diff --git a/Robust/src/IR/Flat/FlatBackEdge.java b/Robust/src/IR/Flat/FlatBackEdge.java
new file mode 100644 (file)
index 0000000..b6bbb25
--- /dev/null
@@ -0,0 +1,15 @@
+package IR.Flat;
+import java.util.Vector;
+
+public class FlatBackEdge extends FlatNode {
+    public FlatBackEdge() {
+    }
+
+    public String toString() {
+       return "backedge";
+    }
+
+    public int kind() {
+       return FKind.FlatBackEdge;
+    }
+}
index b4326130b8422b91f10866b47b6fa41d00a08c4b..185b859035274082a2d9c765292f4433b6f4170e 100644 (file)
@@ -22,6 +22,7 @@ public class State {
     /** Boolean flag which indicates whether compiler is compiling a task-based
      * program. */
     public boolean TASK;
+    public boolean THREAD=false;
     public boolean INSTRUCTIONFAILURE=false;
     public String structfile;
     public String main;
index cda51f7814c4639af4a5a4beea815d45923efadc..71907c575c6a075753e7a43e1f094e8c64245ef3 100644 (file)
@@ -35,6 +35,8 @@ public class Main {
              state.CONSCHECK=true;
          else if (option.equals("-task"))
              state.TASK=true;
+         else if (option.equals("-thread"))
+             state.THREAD=true;
          else if (option.equals("-instructionfailures"))
              state.INSTRUCTIONFAILURE=true;
          else if (option.equals("-help")) {
@@ -46,6 +48,7 @@ public class Main {
 
              System.out.println("-conscheck -- turn on consistency checking");
              System.out.println("-task -- compiler for tasks");
+             System.out.println("-thread -- threads");
              System.out.println("-instructionfailures -- insert code for instruction level failures");
              System.out.println("-help -- print out help");
              System.exit(0);
@@ -70,6 +73,10 @@ public class Main {
          readSourceFile(state, ClassLibraryPrefix+"StartupObject.java");
          readSourceFile(state, ClassLibraryPrefix+"Socket.java");
          readSourceFile(state, ClassLibraryPrefix+"ServerSocket.java");
+      } 
+
+      if (state.THREAD) {
+         readSourceFile(state, ClassLibraryPrefix+"Thread.java");
       }
 
       BuildIR bir=new BuildIR(state);
index 0b97ee339fd4b20655cc10f458ff3e741036fe80..a354351284ea726a7451bf10aed0e609ee212d5f 100644 (file)
@@ -5,6 +5,10 @@
 #include "SimpleHash.h"
 #include "GenericHashtable.h"
 #include <string.h>
+#ifdef THREADS
+#include "thread.h"
+#endif
+
 
 #define NUMPTRS 100
 
@@ -22,6 +26,12 @@ extern struct RuntimeHash *reverse;
 extern struct RuntimeHash *fdtoobject;
 #endif
 
+#ifdef THREADS
+int needtocollect=0;
+struct listitem * list=NULL;
+int listcount=0;
+#endif
+
 struct pointerblock {
   void * ptrs[NUMPTRS];
   struct pointerblock *next;
@@ -33,7 +43,6 @@ struct pointerblock *tail=NULL;
 int tailindex=0;
 struct pointerblock *spare=NULL;
 
-
 void enqueue(void *ptr) {
   if (headindex==NUMPTRS) {
     struct pointerblock * tmp;
@@ -69,12 +78,32 @@ int moreItems() {
 }
 
 void collect(struct garbagelist * stackptr) {
+#ifdef THREADS
+  needtocollect=1;
+  while(1) {
+    pthread_mutex_lock(&gclistlock);
+    pthread_mutex_lock(&threadtable);
+    if ((listcount+1)==threadcount) {
+      break; /* Have all other threads stopped */
+    }
+    pthread_mutex_unlock(&threadtable);
+    pthread_cond_wait(&gccond, &gclistlock);
+    pthread_mutex_unlock(&gclistlock);
+  }
+#endif
+
   if (head==NULL) {
     headindex=0;
     tailindex=0;
     head=tail=malloc(sizeof(struct pointerblock));
   }
   /* Check current stack */
+#ifdef THREADS
+ {
+   struct listitem *listptr=list;
+   while(stackptr!=NULL) {
+#endif
+     
   while(stackptr!=NULL) {
     int i;
     for(i=0;i<stackptr->size;i++) {
@@ -86,6 +115,15 @@ void collect(struct garbagelist * stackptr) {
     }
     stackptr=stackptr->next;
   }
+#ifdef THREADS
+  /* Go to next thread */
+  if (listptr!=NULL) {
+    stackptr=listptr->stackptr;
+    listptr=listptr->next;
+  }
+   }
+ }
+#endif
   
 #ifdef TASK
   {
@@ -218,6 +256,9 @@ void collect(struct garbagelist * stackptr) {
       }
     }
   }
+#ifdef THREADS
+  needtocollect=0;
+#endif
 }
 
 void * curr_heapbase=0;
@@ -238,8 +279,57 @@ void * tomalloc(int size) {
   return ptr;
 }
 
+#ifdef THREADS
+
+void checkcollect(void * ptr) {
+  if (needtocollect) {
+    struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
+    pthread_mutex_lock(&gclock);
+    restartaftergc(tmp);
+  }
+}
+
+struct listitem * stopforgc(struct garbagelist * ptr) {
+  struct listitem * litem=malloc(sizeof(struct listitem));
+  litem->stackptr=ptr;
+  litem->prev=NULL;
+  pthread_mutex_lock(&gclistlock);
+  litem->next=list;
+  if(list!=NULL)
+    list->prev=litem;
+  list=litem;
+  listcount++;
+  pthread_cond_signal(&gccond);
+  pthread_mutex_unlock(&gclistlock);
+  return litem;
+}
+
+void restartaftergc(struct listitem * litem) {
+  pthread_mutex_lock(&gclistlock);
+  if (litem->prev==NULL) {
+    list=litem->next;
+  } else {
+    litem->prev->next=litem->next;
+  }
+  if (litem->next!=NULL) {
+    litem->next->prev=litem->prev;
+  }
+  listcount--;
+  pthread_mutex_unlock(&gclistlock);
+  free(litem);
+}
+#endif
+
 void * mygcmalloc(struct garbagelist * stackptr, int size) {
-  void *ptr=curr_heapptr;
+  void *ptr;
+#ifdef THREADS
+  if (pthread_mutex_trylock(&gclock)!=0) {
+    struct listitem *tmp=stopforgc(stackptr);
+    pthread_mutex_lock(&gclock);
+    restartaftergc(tmp);
+  }
+#endif
+  ptr=curr_heapptr;
   if ((size%4)!=0)
     size+=(4-(size%4));
   curr_heapptr+=size;
@@ -255,7 +345,11 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
       to_heapbase=malloc(INITIALHEAPSIZE);
       to_heaptop=to_heapbase+INITIALHEAPSIZE;
       to_heapptr=to_heapbase;
-      return curr_heapbase;
+      ptr=curr_heapbase;
+#ifdef THREADS
+      pthread_mutex_unlock(&gclock);
+#endif
+      return ptr;
     }
 
     /* Grow the to heap if necessary */
@@ -300,14 +394,25 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
       to_heapptr=to_heapbase;
       
       /* Not enough room :(, redo gc */
-      if (curr_heapptr>curr_heapgcpoint)
+      if (curr_heapptr>curr_heapgcpoint) {
+#ifdef THREADS
+       pthread_mutex_unlock(&gclock);
+#endif
        return mygcmalloc(stackptr, size);
+      }
       
       bzero(tmp, curr_heaptop-tmp);
+#ifdef THREADS
+      pthread_mutex_unlock(&gclock);
+#endif
       return tmp;
     }
-  } else
+  } else {
+#ifdef THREADS
+    pthread_mutex_unlock(&gclock);
+#endif
     return ptr;
+  }
 }
 
 
index bf998fb1d228879569ac8efbe98a2442c9814e87..80171a58825ba7d75222ff1cf332a60ae4528c53 100644 (file)
@@ -6,6 +6,17 @@ struct garbagelist {
   void * array[];
 };
 
+struct listitem {
+  struct listitem * prev;
+  struct listitem * next;
+  struct garbagelist * stackptr;
+};
+
+#ifdef THREADS
+void checkcollect(void * ptr);
+struct listitem * stopforgc(struct garbagelist * ptr);
+void restartaftergc(struct listitem * litem);
+#endif
 void collect(struct garbagelist *stackptr);
 int gc_createcopy(void * orig, void **);
 void * mygcmalloc(struct garbagelist * ptr, int size);
index 03f0ddb52a6a25306dda454c34df6fef863b8e09..f59480981cd2780ec4bf82807006791a537a4356 100644 (file)
@@ -23,6 +23,7 @@ void createstartupobject();
 
 #ifdef PRECISE_GC
 #define VAR(name) ___params___->name
+#define CALL00(name) name(struct name ## _params * ___params___)
 #define CALL01(name, alt) name(struct name ## _params * ___params___)
 #define CALL02(name, alt1, alt2) name(struct name ## _params * ___params___)
 #define CALL11(name,rest, alt) name(struct name ## _params * ___params___, rest)
@@ -31,6 +32,7 @@ void createstartupobject();
 #define CALL23(name, rest, rest2, alt1, alt2, alt3) name(struct name ## _params * ___params___, rest, rest2)
 #else
 #define VAR(name) name
+#define CALL00(name) name()
 #define CALL01(name, alt) name(alt)
 #define CALL02(name, alt1, alt2) name(alt1, alt2)
 #define CALL11(name,rest, alt) name(alt)
diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c
new file mode 100644 (file)
index 0000000..5e3b27c
--- /dev/null
@@ -0,0 +1,42 @@
+#include "runtime.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "thread.h"
+
+
+#include <stdio.h>
+pthread_mutex_t threadtable;
+int threadcount;
+pthread_mutex_t gclock;
+pthread_mutex_t gclistlock;
+pthread_cond_t gccond;
+
+void initializethreads() {
+  pthread_mutex_init(&threadtable,NULL);
+  threadcount=1;
+  pthread_mutex_init(&gclock, NULL);
+  pthread_mutex_init(&gclistlock, NULL);
+  pthread_cond_init(&gccond, NULL);
+}
+
+void initthread(struct ___Thread___ * ___this___) {
+#ifdef PRECISE_GC
+  struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
+  ___Thread______staticStart____L___Thread___(&p);
+#else
+  ___Thread______staticStart____L___Thread___(___this___);
+#endif
+  pthread_mutex_lock(&threadtable);
+  threadcount--;
+  pthread_mutex_unlock(&threadtable);
+}
+
+void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
+  pthread_t thread;
+  pthread_mutex_lock(&threadtable);
+  threadcount++;
+  pthread_mutex_unlock(&threadtable);
+  pthread_create(&thread, NULL,(void * (*)(void *)) &initthread, VAR(___this___));
+}
diff --git a/Robust/src/Runtime/thread.h b/Robust/src/Runtime/thread.h
new file mode 100644 (file)
index 0000000..dc728cc
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef THREAD_H
+#define THREAD_H
+#include "methodheaders.h"
+#include "pthread.h"
+
+extern pthread_mutex_t threadtable;
+extern int threadcount;
+extern pthread_mutex_t gclock;
+extern pthread_mutex_t gclistlock;
+extern pthread_cond_t gccond;
+void initthread(struct ___Thread___ * ___this___);
+#endif
index 5ddacc3ce9476ebad3c8c84f593a28fbe8533f8a..69ba9461057203947ee15cedc16e0f2965f2d4d0 100755 (executable)
@@ -6,6 +6,7 @@ echo -recover compile task code
 echo -specdir directory
 echo -debug generate debug symbols
 echo -runtimedebug printout runtime debug messages
+echo "-thread use support for multiple threads"
 echo "-optimize call gcc with -O9 (optimize)"
 echo "-nooptimize call gcc with -O0 (do not optimize)"
 echo -curdir directory 
@@ -75,6 +76,10 @@ EXTRAOPTIONS="$EXTRAOPTIONS -O0"
 elif [[ $1 = '-optimize' ]]
 then
 EXTRAOPTIONS="$EXTRAOPTIONS -O9"
+elif [[ $1 = '-thread' ]]
+then
+JAVAOPTS="$JAVAOPTS -thread"
+EXTRAOPTIONS="$EXTRAOPTIONS -DTHREADS"
 elif [[ $1 = '-curdir' ]]
 then
 CURDIR=$2
@@ -156,7 +161,9 @@ $ROBUSTROOT/Runtime/GenericHashtable.c"
 if $RECOVERFLAG
 then
 EXTRAOPTIONS="$EXTRAOPTIONS -DTASK"
-FILES="$FILES $ROBUSTROOT/Runtime/socket.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/checkpoint.c "
+FILES="$FILES $ROBUSTROOT/Runtime/socket.c tmpbuilddirectory/taskdefs.c $ROBUSTROOT/Runtime/checkpoint.c"
+else
+FILES="$FILES $ROBUSTROOT/Runtime/thread.c"
 fi
 
 if $CHECKFLAG