void processCallNode(LocalityBinding currlb, FlatCall fc, Hashtable<TempDescriptor, Integer> currtable, boolean isatomic) {
MethodDescriptor nodemd=fc.getMethod();
Set methodset=null;
+ Set runmethodset=null;
if (nodemd.isStatic()||nodemd.getReturnType()==null) {
methodset=new HashSet();
methodset.add(nodemd);
} else {
methodset=callgraph.getMethods(nodemd, fc.getThis().getType());
+ // Build start -> run link
+ if (nodemd.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
+ nodemd.getSymbol().equals("start")&&!nodemd.getModifiers().isStatic()&&
+ nodemd.numParameters()==1&&nodemd.getParamType(0).isInt()) {
+ assert(nodemd.getModifiers().isNative());
+
+ MethodDescriptor runmd=null;
+ for(Iterator methodit=nodemd.getClassDesc().getMethodTable().getSet("run").iterator();methodit.hasNext();) {
+ MethodDescriptor md=(MethodDescriptor) methodit.next();
+ if (md.numParameters()!=0||md.getModifiers().isStatic())
+ continue;
+ runmd=md;
+ break;
+ }
+ if (runmd!=null) {
+ runmethodset=callgraph.getMethods(runmd,fc.getThis().getType());
+ methodset.addAll(runmethodset);
+ } else throw new Error("Can't find run method");
+ }
}
Integer currreturnval=EITHER; //Start off with the either value
for(Iterator methodit=methodset.iterator();methodit.hasNext();) {
if (isnative&&isatomic) {
System.out.println("Don't call native methods in atomic blocks!");
}
- for(int i=0;i<fc.numArgs();i++) {
- TempDescriptor arg=fc.getArg(i);
- if(isnative&&(currtable.get(arg).equals(GLOBAL)||
- currtable.get(arg).equals(CONFLICT)))
- throw new Error("Potential call to native method "+md+" with global parameter:\n"+currlb.getExplanation());
- lb.setGlobal(i,currtable.get(arg));
+ if (runmethodset==null||!runmethodset.contains(md)) {
+ //Skip this part if it is a run method
+ for(int i=0;i<fc.numArgs();i++) {
+ TempDescriptor arg=fc.getArg(i);
+ if(isnative&&(currtable.get(arg).equals(GLOBAL)||
+ currtable.get(arg).equals(CONFLICT)))
+ throw new Error("Potential call to native method "+md+" with global parameter:\n"+currlb.getExplanation());
+ lb.setGlobal(i,currtable.get(arg));
+ }
}
+
+
if (fc.getThis()!=null) {
Integer thistype=currtable.get(fc.getThis());
if (thistype==null)
thistype=EITHER;
+
+ if(runmethodset!=null&&runmethodset.contains(md)&&thistype.equals(LOCAL))
+ throw new Error("Starting thread on local object not allowed in context:\n"+currlb.getExplanation());
if(thistype.equals(CONFLICT))
throw new Error("Using type that can be either local or global in context:\n"+currlb.getExplanation());
if(thistype.equals(GLOBAL)&&!isatomic)
if (isnative&&thistype.equals(GLOBAL))
throw new Error("Potential call to native method "+md+" on global objects:\n"+currlb.getExplanation());
lb.setGlobalThis(thistype);
- } //else
- //lb.setGlobalThis(EITHER);//default value
-
+ }
//lb is built
if (!discovered.containsKey(lb)) {
if (isnative)
output.println("/* nop */");
return;
case FKind.FlatBackEdge:
- if (state.THREAD&&GENERATEPRECISEGC) {
+ if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
output.println("checkcollect(&"+localsprefix+");");
} else
output.println("/* nop */");
public static final String ObjectClass="Object";
public static final String StartupClass="StartupObject";
public static final String TagClass="TagDescriptor";
+ public static final String ThreadClass="Thread";
State state;
Hashtable supertable;
Hashtable subclasstable;
#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
extern struct RuntimeHash *fdtoobject;
#endif
-#ifdef THREADS
+#if defined(THREADS) || defined(DSTM)
int needtocollect=0;
struct listitem * list=NULL;
int listcount=0;
void collect(struct garbagelist * stackptr) {
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
needtocollect=1;
pthread_mutex_lock(&gclistlock);
while(1) {
#endif
/* Check current stack */
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
{
struct listitem *listptr=list;
while(1) {
}
stackptr=stackptr->next;
}
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
/* Go to next thread */
if (listptr!=NULL) {
void * orig=listptr->locklist;
fixtags();
#endif
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
needtocollect=0;
pthread_mutex_unlock(&gclistlock);
#endif
return ptr;
}
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
void checkcollect(void * ptr) {
if (needtocollect) {
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);
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;
/* 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;
void fixtags();
#endif
-#ifdef THREADS
+#if defined(THREADS)||defined(DSTM)
void checkcollect(void * ptr);
struct listitem * stopforgc(struct garbagelist * ptr);
void restartaftergc(struct listitem * litem);
pthread_key_t threadlocks;
void threadexit() {
+#ifdef THREADS
struct ___Object___ *ll=pthread_getspecific(threadlocks);
while(ll!=NULL) {
struct ___Object___ *llnext=ll->___nextlockobject___;
pthread_mutex_lock(&objlock);//wake everyone up
pthread_cond_broadcast(&objcond);
pthread_mutex_unlock(&objlock);
+#endif
pthread_mutex_lock(&gclistlock);
threadcount--;
pthread_cond_signal(&gccond);
sigaction(SIGFPE,&sig,0);
}
+#ifdef THREADS
void initthread(struct ___Thread___ * ___this___) {
#ifdef PRECISE_GC
struct ___Thread______staticStart____L___Thread____params p={1, NULL, ___this___};
pthread_cond_signal(&gccond);
pthread_mutex_unlock(&gclistlock);
}
+#endif
void CALL11(___Thread______sleep____J, long long ___millis___, long long ___millis___) {
#ifdef THREADS
#endif
}
+#ifdef THREADS
void CALL01(___Thread______nativeCreate____, struct ___Thread___ * ___this___) {
pthread_t thread;
int retval;
pthread_attr_destroy(&nattr);
}
+#endif
if $DSMFLAG
then
EXTRAOPTIONS="$EXTRAOPTIONS -lpthread -DCOMPILER -DDSTM -I$DSMRUNTIME"
-FILES="$FILES $DSMRUNTIME/trans.c $DSMRUNTIME/mcpileq.c $DSMRUNTIME/objstr.c $DSMRUNTIME/dstm.c $DSMRUNTIME/mlookup.c $DSMRUNTIME/clookup.c $DSMRUNTIME/llookup.c $DSMRUNTIME/dstmserver.c $DSMRUNTIME/plookup.c $DSMRUNTIME/ip.c $DSMRUNTIME/queue.c $DSMRUNTIME/prelookup.c $DSMRUNTIME/machinepile.c $DSMRUNTIME/localobjects.c"
+FILES="$FILES $DSMRUNTIME/trans.c $DSMRUNTIME/mcpileq.c $DSMRUNTIME/objstr.c $DSMRUNTIME/dstm.c $DSMRUNTIME/mlookup.c $DSMRUNTIME/clookup.c $DSMRUNTIME/llookup.c $DSMRUNTIME/dstmserver.c $DSMRUNTIME/plookup.c $DSMRUNTIME/ip.c $DSMRUNTIME/queue.c $DSMRUNTIME/prelookup.c $DSMRUNTIME/machinepile.c $DSMRUNTIME/localobjects.c $ROBUSTROOT/Runtime/thread.c"
fi
if $RECOVERFLAG