adding thread support w/ locks
authorbdemsky <bdemsky>
Tue, 20 Feb 2007 08:48:57 +0000 (08:48 +0000)
committerbdemsky <bdemsky>
Tue, 20 Feb 2007 08:48:57 +0000 (08:48 +0000)
12 files changed:
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Flat/BuildFlat.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/Modifiers.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Main/Main.java
Robust/src/Parse/java14.cup
Robust/src/Runtime/garbage.c
Robust/src/Runtime/runtime.c
Robust/src/Runtime/thread.c
Robust/src/Runtime/thread.h
Robust/src/buildscript

index 20f0892c1ec8e0ce812df383aeb9937c03f52c23..1e5c92912f6abce477171b0900aef2351c98aa06 100644 (file)
@@ -107,6 +107,9 @@ public class BuildCode {
 
        // Output the C class declarations
        // These could mutually reference each other
+       if (state.THREAD)
+           outclassdefs.println("#include <pthread.h>");
+
        outclassdefs.println("struct "+arraytype+";");
 
        Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
@@ -119,9 +122,13 @@ public class BuildCode {
            //Print out definition for array type
            outclassdefs.println("struct "+arraytype+" {");
            outclassdefs.println("  int type;");
-           outclassdefs.println("  int flag;");
+           if (state.THREAD) {
+               outclassdefs.println("  pthread_t tid;");
+               outclassdefs.println("  int lockcount;");
+           }
                
            if (state.TASK) {
+               outclassdefs.println("  int flag;");
                outclassdefs.println("  void * flagptr;");
            }
            printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
@@ -289,10 +296,8 @@ public class BuildCode {
                break;
            }
            if (state.THREAD) {
-               outmethod.println("pthread_mutex_lock(&threadtable);");
-               outmethod.println("threadcount--;");
-               outmethod.println("pthread_mutex_unlock(&threadtable);");
                outmethod.println("pthread_mutex_lock(&gclistlock);");
+               outmethod.println("threadcount--;");
                outmethod.println("pthread_cond_signal(&gccond);");
                outmethod.println("pthread_mutex_unlock(&gclistlock);");
                outmethod.println("pthread_exit(NULL);");
@@ -722,9 +727,13 @@ public class BuildCode {
        /* Output class structure */
        classdefout.println("struct "+cn.getSafeSymbol()+" {");
        classdefout.println("  int type;");
-       classdefout.println("  int flag;");
+       if (state.THREAD) {
+           classdefout.println("  pthread_t tid;");
+           classdefout.println("  int lockcount;");
+       }
 
        if (state.TASK) {
+           classdefout.println("  int flag;");
            classdefout.println("  void * flagptr;");
        }
        printClassStruct(cn, classdefout);
index 3ff20b0f0d0393d06aaa0578cde62a0b00b4a4de..bce8e4ca4980cab91d54a0bbb5abd70b122c0054 100644 (file)
@@ -6,10 +6,13 @@ import java.util.*;
 public class BuildFlat {
     State state;
     Hashtable temptovar;
+    MethodDescriptor currmd;
+    TypeUtil typeutil;
 
-    public BuildFlat(State st) {
+    public BuildFlat(State st, TypeUtil typeutil) {
        state=st;
        temptovar=new Hashtable();
+       this.typeutil=typeutil;
     }
 
     public Hashtable getMap() {
@@ -67,16 +70,30 @@ public class BuildFlat {
     private void flattenClass(ClassDescriptor cn) {
        Iterator methodit=cn.getMethods();
        while(methodit.hasNext()) {
-           MethodDescriptor md=(MethodDescriptor)methodit.next();
-           BlockNode bn=state.getMethodBody(md);
-           FlatNode fn=flattenBlockNode(bn).getBegin();
-           FlatMethod fm=new FlatMethod(md, fn);
-           if (!md.isStatic())
-               fm.addParameterTemp(getTempforParam(md.getThis()));
-           for(int i=0;i<md.numParameters();i++) {
-               fm.addParameterTemp(getTempforParam(md.getParameter(i)));
+           currmd=(MethodDescriptor)methodit.next();
+           BlockNode bn=state.getMethodBody(currmd);
+           NodePair np=flattenBlockNode(bn);
+           FlatNode fn=np.getBegin();
+           if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
+               MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
+               TempDescriptor thistd=getTempforVar(currmd.getThis());
+               FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
+               fc.addNext(fn);
+               fn=fc;
+               if (np.getEnd().kind()!=FKind.FlatReturnNode) {
+                   MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+                   FlatCall fcunlock=new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
+                   np.getEnd().addNext(fcunlock);
+               }
+           }
+
+           FlatMethod fm=new FlatMethod(currmd, fn);
+           if (!currmd.isStatic())
+               fm.addParameterTemp(getTempforParam(currmd.getThis()));
+           for(int i=0;i<currmd.numParameters();i++) {
+               fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
            }
-           state.addFlatCode(md,fm);
+           state.addFlatCode(currmd,fm);
        }
     }
 
@@ -741,12 +758,20 @@ public class BuildFlat {
        }
 
        FlatReturnNode rnflat=new FlatReturnNode(retval);
+       FlatNode ln=rnflat;
+       if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
+           MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+           TempDescriptor thistd=getTempforVar(currmd.getThis());
+           FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
+           fc.addNext(rnflat);
+           ln=fc;
+       }
 
        if (cond!=null) {
-           cond.getEnd().addNext(rnflat);
+           cond.getEnd().addNext(ln);
            return new NodePair(cond.getBegin(),rnflat);
        } else
-           return new NodePair(rnflat,rnflat);
+           return new NodePair(ln,rnflat);
     }
 
     private NodePair flattenTaskExitNode(TaskExitNode ten) {
index 17eceb26ce517efaf86f4667c5402eede9af6832..fbea5fcef34e8599a7187a5e338cf4c62ebd3c46 100644 (file)
@@ -652,16 +652,19 @@ public class BuildIR {
                ParseNode modn=pnv.elementAt(i);
                if (isNode(modn,"public"))
                    m.addModifier(Modifiers.PUBLIC);
-               if (isNode(modn,"protected"))
+               else if (isNode(modn,"protected"))
                    m.addModifier(Modifiers.PROTECTED);
-               if (isNode(modn,"private"))
+               else if (isNode(modn,"private"))
                    m.addModifier(Modifiers.PRIVATE);
-               if (isNode(modn,"static"))
+               else if (isNode(modn,"static"))
                    m.addModifier(Modifiers.STATIC);
-               if (isNode(modn,"final"))
+               else if (isNode(modn,"final"))
                    m.addModifier(Modifiers.FINAL);
-               if (isNode(modn,"native"))
+               else if (isNode(modn,"native"))
                    m.addModifier(Modifiers.NATIVE);
+               else if (isNode(modn,"synchronized"))
+                   m.addModifier(Modifiers.SYNCHRONIZED);
+               else throw new Error("Unrecognized Modifier");
            }
        }
        return m;
index 827f3acfbbac2271874e141d0704c81a3ebdcecf..d20c7962005ec485131c8c504b3d8fd95dafce2b 100644 (file)
@@ -8,7 +8,7 @@ public class Modifiers {
 //     ABSTRACT=16
     public static final int FINAL=32;
     public static final int NATIVE=64;
-//     SYNCHRONIZED=128
+    public static final int SYNCHRONIZED=128;
 //     TRANSIENT=256
 //     VOLATILE=512
 //     STRICTFP=1024
@@ -25,6 +25,12 @@ public class Modifiers {
 
     public void addModifier(int mod) {
        value|=mod;
+       if (isSynchronized()&&isNative())
+           throw new Error("Synchronized native methods are not supported");
+    }
+
+    public boolean isSynchronized() {
+       return ((value&SYNCHRONIZED)!=0);
     }
 
     public boolean isStatic() {
@@ -49,6 +55,8 @@ public class Modifiers {
            st+="final ";
        if ((value&NATIVE)!=0)
            st+="native ";
+       if ((value&SYNCHRONIZED)!=0)
+           st+="synchronized ";
        return st;
     }
 }
index 0feb9d0e4deb537647dfb12e6caa219d8d0ff8d7..5cd747f7778d0b7a2991579ffa733b1a28b50d7e 100644 (file)
@@ -686,11 +686,15 @@ public class SemanticCheck {
        switch(op.getOp()) {
        case Operation.LOGIC_OR:
        case Operation.LOGIC_AND:
-           if (!(ltd.isBoolean()&&rtd.isBoolean()))
+           if (!(rtd.isBoolean()))
+               throw new Error();
+           on.setRightType(rtd);
+       case Operation.LOGIC_NOT:
+           if (!(ltd.isBoolean()))
                throw new Error();
            //no promotion
            on.setLeftType(ltd);
-           on.setRightType(rtd);
+
            on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
            break;
 
@@ -823,7 +827,7 @@ public class SemanticCheck {
            on.setType(lefttype);
            break;
        default:
-           throw new Error();
+           throw new Error(op.toString());
        }
    
        if (td!=null)
index 8fd212ebeb492d1c17e7e1fe6f910b7d387d3da4..4f391128fd5134aa1238a6bc744b9cb06e88dd2e 100644 (file)
@@ -57,7 +57,7 @@ public class Main {
          }
       }
       
-      readSourceFile(state, ClassLibraryPrefix+"Object.java");
+
       readSourceFile(state, ClassLibraryPrefix+"System.java");
       readSourceFile(state, ClassLibraryPrefix+"String.java");
       readSourceFile(state, ClassLibraryPrefix+"HashSet.java");
@@ -70,10 +70,12 @@ public class Main {
       readSourceFile(state, ClassLibraryPrefix+"FileOutputStream.java");
       readSourceFile(state, ClassLibraryPrefix+"File.java");
       if (state.TASK) {
+         readSourceFile(state, ClassLibraryPrefix+"Object.java");
          readSourceFile(state, ClassLibraryPrefix+"StartupObject.java");
          readSourceFile(state, ClassLibraryPrefix+"Socket.java");
          readSourceFile(state, ClassLibraryPrefix+"ServerSocket.java");
       } else {
+         readSourceFile(state, ClassLibraryPrefix+"ObjectJava.java");
          readSourceFile(state, ClassLibraryPrefix+"SocketJava.java");
          readSourceFile(state, ClassLibraryPrefix+"ServerSocketJava.java");
       }
@@ -91,7 +93,7 @@ public class Main {
       sc.semanticCheck();
       tu.createFullTable();
 
-      BuildFlat bf=new BuildFlat(state);
+      BuildFlat bf=new BuildFlat(state,tu);
       bf.buildFlat();
       
       BuildCode bc=new BuildCode(state, bf.getMap(), tu);
index d964ee8be488804c945ae458e3e42e6bfed8e4df..68773750e3f303b80f5cf4563d899f9ee8863f50 100644 (file)
@@ -615,8 +615,8 @@ modifier ::=
        STATIC {: RESULT=new ParseNode("static"); :} |
 //     ABSTRACT |
        FINAL {: RESULT=new ParseNode("final"); :}|
-       NATIVE {: RESULT=new ParseNode("native"); :}
-//     SYNCHRONIZED | 
+       NATIVE {: RESULT=new ParseNode("native"); :} |
+       SYNCHRONIZED {: RESULT=new ParseNode("synchronized"); :}
 //     TRANSIENT | 
 //     VOLATILE |
 //     STRICTFP // note that semantic analysis must check that the
index bbd2f04ffed28e8d71ddf084964b90a70234487a..8b8d7370067fceca3779e8c781bea1cc6ec23fb9 100644 (file)
@@ -80,17 +80,12 @@ int moreItems() {
 void collect(struct garbagelist * stackptr) {
 #ifdef THREADS
   needtocollect=1;
+  pthread_mutex_lock(&gclistlock);
   while(1) {
-    pthread_mutex_lock(&gclistlock);
-    pthread_mutex_lock(&threadtable);
     if ((listcount+1)==threadcount) {
-      pthread_mutex_unlock(&threadtable);
-      pthread_mutex_unlock(&gclistlock);      
       break; /* Have all other threads stopped */
     }
-    pthread_mutex_unlock(&threadtable);
     pthread_cond_wait(&gccond, &gclistlock);
-    pthread_mutex_unlock(&gclistlock);
   }
 #endif
 
@@ -260,6 +255,7 @@ void collect(struct garbagelist * stackptr) {
   }
 #ifdef THREADS
   needtocollect=0;
+  pthread_mutex_unlock(&gclistlock);
 #endif
 }
 
@@ -286,9 +282,10 @@ void * tomalloc(int size) {
 void checkcollect(void * ptr) {
   if (needtocollect) {
     struct listitem * tmp=stopforgc((struct garbagelist *)ptr);
-    pthread_mutex_lock(&gclock);
+    pthread_mutex_lock(&gclock); // Wait for GC
     restartaftergc(tmp);
     pthread_mutex_unlock(&gclock);
+
   }
 }
 
index 23a43fd3bcfd66320245e99fc85ed81082117fb5..f45c1be8f1410a88871beb1468b785705eaf8908 100644 (file)
@@ -414,14 +414,6 @@ void injectinstructionfailure() {
 #endif
 }
 
-int CALL01(___Object______hashCode____, struct ___Object___ * ___this___) {
-  return (int) VAR(___this___);
-}
-
-int CALL01(___Object______getType____, struct ___Object___ * ___this___) {
-  return ((int *)VAR(___this___))[0];
-}
-
 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
     struct ArrayObject * chararray=VAR(___s___)->___value___;
     int i;
@@ -436,8 +428,12 @@ void CALL01(___System______printString____L___String___,struct ___String___ * __
 
 #ifdef PRECISE_GC
 void * allocate_new(void * ptr, int type) {
-  void * v=mygcmalloc((struct garbagelist *) ptr, classsize[type]);
-  *((int *)v)=type;
+  struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
+  v->type=type;
+#ifdef THREADS
+  v->tid=0;
+  v->lockcount=0;
+#endif
   return v;
 }
 
@@ -447,6 +443,10 @@ struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
   v->type=type;
   v->___length___=length;
+#ifdef THREADS
+  v->tid=0;
+  v->lockcount=0;
+#endif
   return v;
 }
 
index 99e79cef59514d75bee960580ca4e2870838388e..2f745651e5d1f355ad9ddcc73fcefe0a67188c25 100644 (file)
@@ -7,18 +7,20 @@
 
 
 #include <stdio.h>
-pthread_mutex_t threadtable;
 int threadcount;
 pthread_mutex_t gclock;
 pthread_mutex_t gclistlock;
 pthread_cond_t gccond;
+pthread_mutex_t objlock;
+pthread_cond_t objcond;
 
 void initializethreads() {
-  pthread_mutex_init(&threadtable,NULL);
   threadcount=1;
   pthread_mutex_init(&gclock, NULL);
   pthread_mutex_init(&gclistlock, NULL);
   pthread_cond_init(&gccond, NULL);
+  pthread_mutex_init(&objlock,NULL);
+  pthread_cond_init(&objcond,NULL);
 }
 
 void initthread(struct ___Thread___ * ___this___) {
@@ -28,18 +30,16 @@ void initthread(struct ___Thread___ * ___this___) {
 #else
   ___Thread______staticStart____L___Thread___(___this___);
 #endif
-  pthread_mutex_lock(&threadtable);
-  threadcount--;
-  pthread_mutex_unlock(&threadtable);
   pthread_mutex_lock(&gclistlock);
+  threadcount--;
   pthread_cond_signal(&gccond);
   pthread_mutex_unlock(&gclistlock);
 }
 
 void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
   pthread_t thread;
-  pthread_mutex_lock(&threadtable);
+  pthread_mutex_lock(&gclistlock);
   threadcount++;
-  pthread_mutex_unlock(&threadtable);
+  pthread_mutex_unlock(&gclistlock);
   pthread_create(&thread, NULL,(void * (*)(void *)) &initthread, VAR(___this___));
 }
index dc728ccaf3a06b2a96b59b267d537d720fd26548..e12a8e061a62fc19420774cf8442198462a2bee4 100644 (file)
@@ -3,10 +3,11 @@
 #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;
+extern pthread_mutex_t objlock;
+extern pthread_cond_t objcond;
 void initthread(struct ___Thread___ * ___this___);
 #endif
index 522b8690bbe5d0b47728cc820eab1b6290b452db..0a7f880c7f23f1bbfac1867f2836b5d4b7e5f173 100755 (executable)
@@ -155,7 +155,8 @@ INCLUDES="$INCLUDES -I$ROBUSTROOT/Runtime -I. -IRuntime/include \
 FILES="$ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/file.c \
 $ROBUSTROOT/Runtime/Queue.c $ROBUSTROOT/Runtime/SimpleHash.c \
 $ROBUSTROOT/Runtime/option.c $ROBUSTROOT/Runtime/garbage.c \
-$ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/GenericHashtable.c"
+$ROBUSTROOT/Runtime/socket.c $ROBUSTROOT/Runtime/GenericHashtable.c \
+$ROBUSTROOT/Runtime/object.c"
 
 if $RECOVERFLAG
 then