/* 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(
generateTaskStructs(outstructs, outmethodheader);
}
+ outmethodheader.println("#endif");
+
outmethodheader.close();
/* Build the actual methods */
outmethod.println(" }");
break;
}
+ if (state.THREAD)
+ outmethod.println("pthread_exit();");
outmethod.println("}");
}
if (state.TASK)
buildRepairStructs(outrepairstructs);
outrepairstructs.close();
}
+ outstructs.println("#endif");
outstructs.close();
outmethod.close();
}
}
+ if (state.THREAD&&GENERATEPRECISEGC) {
+ output.println("checkcollect(&"+localsprefix+");");
+ }
+
//Do the actual code generation
tovisit=new HashSet();
visited=new HashSet();
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;
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());
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());
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();
}
public static final int FlatElementNode=12;
public static final int FlatFlagActionNode=13;
public static final int FlatCheckNode=14;
+ public static final int FlatBackEdge=15;
}
--- /dev/null
+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;
+ }
+}
/** 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;
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")) {
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);
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);
#include "SimpleHash.h"
#include "GenericHashtable.h"
#include <string.h>
+#ifdef THREADS
+#include "thread.h"
+#endif
+
#define NUMPTRS 100
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;
int tailindex=0;
struct pointerblock *spare=NULL;
-
void enqueue(void *ptr) {
if (headindex==NUMPTRS) {
struct pointerblock * tmp;
}
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++) {
}
stackptr=stackptr->next;
}
+#ifdef THREADS
+ /* Go to next thread */
+ if (listptr!=NULL) {
+ stackptr=listptr->stackptr;
+ listptr=listptr->next;
+ }
+ }
+ }
+#endif
#ifdef TASK
{
}
}
}
+#ifdef THREADS
+ needtocollect=0;
+#endif
}
void * curr_heapbase=0;
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;
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 */
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;
+ }
}
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);
#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)
#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)
--- /dev/null
+#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___));
+}
--- /dev/null
+#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
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
elif [[ $1 = '-optimize' ]]
then
EXTRAOPTIONS="$EXTRAOPTIONS -O9"
+elif [[ $1 = '-thread' ]]
+then
+JAVAOPTS="$JAVAOPTS -thread"
+EXTRAOPTIONS="$EXTRAOPTIONS -DTHREADS"
elif [[ $1 = '-curdir' ]]
then
CURDIR=$2
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