Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add VMThread REPR and thread-related nqp:: ops.
  • Loading branch information
jnthn committed Feb 19, 2014
1 parent 321e13b commit 58e1b65
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/vm/jvm/QAST/Compiler.nqp
Expand Up @@ -2450,6 +2450,14 @@ QAST::OperationsJAST.map_classlib_core_op('getenvhash', $TYPE_OPS, 'getenvhash',
QAST::OperationsJAST.map_classlib_core_op('getpid', $TYPE_OPS, 'getpid', [], $RT_INT, :tc);
QAST::OperationsJAST.map_classlib_core_op('jvmgetproperties', $TYPE_OPS, 'jvmgetproperties', [], $RT_OBJ, :tc);

# thread related opcodes
QAST::OperationsJAST.map_classlib_core_op('newthread', $TYPE_OPS, 'newthread', [$RT_OBJ, $RT_INT], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadrun', $TYPE_OPS, 'threadrun', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadjoin', $TYPE_OPS, 'threadjoin', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadid', $TYPE_OPS, 'threadid', [$RT_OBJ], $RT_INT, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadyield', $TYPE_OPS, 'threadyield', [], $RT_INT, :tc);
QAST::OperationsJAST.map_classlib_core_op('currentthread', $TYPE_OPS, 'currentthread', [], $RT_OBJ, :tc);

# JVM-specific ops for compilation unit handling
QAST::OperationsJAST.map_classlib_core_op('compilejastlines', $TYPE_OPS, 'compilejastlines', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('compilejastlinestofile', $TYPE_OPS, 'compilejastlinestofile', [$RT_OBJ, $RT_STR], $RT_OBJ, :tc);
Expand Down
7 changes: 6 additions & 1 deletion src/vm/jvm/runtime/org/perl6/nqp/runtime/GlobalContext.java
Expand Up @@ -85,6 +85,11 @@ public class GlobalContext {
*/
public SixModelObject CallCapture;

/**
* Thread type; a basic, method-less type with the Thread REPR.
*/
public SixModelObject Thread;

/**
* BOOTException type; a basic, method-less type with the VMException REPR.
*/
Expand Down Expand Up @@ -310,7 +315,7 @@ public ThreadContext getCurrentThreadContext() {
if (tcRef != null) return tcRef.get();

ThreadContext tc = new ThreadContext(this);
synchronized(this) { allThreads.put(Thread.currentThread(), tc); }
synchronized(this) { allThreads.put(java.lang.Thread.currentThread(), tc); }
currentThreadCtxRef.set(new WeakReference< >(tc));
return tc;
}
Expand Down
70 changes: 70 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
Expand Up @@ -87,6 +87,7 @@
import org.perl6.nqp.sixmodel.reprs.VMHash;
import org.perl6.nqp.sixmodel.reprs.VMHashInstance;
import org.perl6.nqp.sixmodel.reprs.VMIterInstance;
import org.perl6.nqp.sixmodel.reprs.VMThreadInstance;

/**
* Contains complex operations that are more involved that the simple ops that the
Expand Down Expand Up @@ -4177,6 +4178,75 @@ else if (pvlc.indexOf("mac os x") >= 0)
return res;
}

/* Thread related. */
static class CodeRunnable implements Runnable {
private GlobalContext gc;
private SixModelObject vmthread;
private SixModelObject code;

public CodeRunnable(GlobalContext gc, SixModelObject vmthread, SixModelObject code) {
this.gc = gc;
this.vmthread = vmthread;
this.code = code;
}

public void run() {
ThreadContext tc = gc.getCurrentThreadContext();
tc.VMThread = vmthread;
invokeArgless(tc, code);
}
}
public static SixModelObject newthread(SixModelObject code, long appLifetime, ThreadContext tc) {
SixModelObject thread = tc.gc.Thread.st.REPR.allocate(tc, tc.gc.Thread.st);
((VMThreadInstance)thread).thread = new Thread(new CodeRunnable(tc.gc, thread, code));
return thread;
}

public static SixModelObject threadrun(SixModelObject thread, ThreadContext tc) {
if (thread instanceof VMThreadInstance)
((VMThreadInstance)thread).thread.start();
else
throw ExceptionHandling.dieInternal(tc, "threadrun requires an operand with REPR VMThread");
return thread;
}

public static SixModelObject threadjoin(SixModelObject thread, ThreadContext tc) {
if (thread instanceof VMThreadInstance) {
try {
((VMThreadInstance)thread).thread.join();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
else {
throw ExceptionHandling.dieInternal(tc, "threadjoin requires an operand with REPR VMThread");
}
return thread;
}

public static long threadid(SixModelObject thread, ThreadContext tc) {
if (thread instanceof VMThreadInstance)
return ((VMThreadInstance)thread).thread.getId();
else
throw ExceptionHandling.dieInternal(tc, "threadid requires an operand with REPR VMThread");
}

public static long threadyield(ThreadContext tc) {
Thread.yield();
return 0;
}

public static SixModelObject currentthread(ThreadContext tc) {
SixModelObject thread = tc.VMThread;
if (thread == null) {
thread = tc.gc.Thread.st.REPR.allocate(tc, tc.gc.Thread.st);
((VMThreadInstance)thread).thread = Thread.currentThread();
tc.VMThread = thread;
}
return thread;
}

/* Exception related. */
public static void die_s_c(String msg, ThreadContext tc) {
// Construct exception object.
Expand Down
6 changes: 6 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/ThreadContext.java
Expand Up @@ -94,6 +94,12 @@ public class ThreadContext {
*/
public CallFrame dummyCaller;

/**
* Object with VMThread REPR used to represent this thread. May be null if we
* never got around to setting it up yet.
*/
public SixModelObject VMThread;

Object hllThreadData;
ContextKey<?,?> hllThreadKey;
HashMap<ContextKey<?,?>, Object> hllThreadAll;
Expand Down
Expand Up @@ -25,6 +25,7 @@ public static void bootstrap(ThreadContext tc)
tc.gc.CallCapture = bootType(tc, "CallCapture", "CallCapture");
tc.gc.BOOTException = bootType(tc, "BOOTException", "VMException");
tc.gc.BOOTIO = bootType(tc, "BOOTIO", "IOHandle");
tc.gc.Thread = bootType(tc, "Thread", "VMThread");

tc.gc.BOOTArray.st.hllRole = HLLConfig.ROLE_ARRAY;
tc.gc.BOOTHash.st.hllRole = HLLConfig.ROLE_HASH;
Expand Down
2 changes: 2 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/sixmodel/REPRRegistry.java
Expand Up @@ -30,6 +30,7 @@
import org.perl6.nqp.sixmodel.reprs.VMException;
import org.perl6.nqp.sixmodel.reprs.VMHash;
import org.perl6.nqp.sixmodel.reprs.VMIter;
import org.perl6.nqp.sixmodel.reprs.VMThread;

public class REPRRegistry {
private static HashMap<String, Integer> reprIdMap = new HashMap<String, Integer>();
Expand Down Expand Up @@ -84,5 +85,6 @@ private static void addREPR(String name, REPR REPR) {
addREPR("CArray", new CArray());
addREPR("CStr", new CStr());
addREPR("CStruct", new CStruct());
addREPR("VMThread", new VMThread());
}
}
34 changes: 34 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/VMThread.java
@@ -0,0 +1,34 @@
package org.perl6.nqp.sixmodel.reprs;

import org.perl6.nqp.runtime.ExceptionHandling;
import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.STable;
import org.perl6.nqp.sixmodel.SerializationReader;
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.TypeObject;

public class VMThread extends REPR {
public SixModelObject type_object_for(ThreadContext tc, SixModelObject HOW) {
STable st = new STable(this, HOW);
SixModelObject obj = new TypeObject();
obj.st = st;
st.WHAT = obj;
return st.WHAT;
}

public SixModelObject allocate(ThreadContext tc, STable st) {
VMThreadInstance obj = new VMThreadInstance();
obj.st = st;
return obj;
}

public SixModelObject deserialize_stub(ThreadContext tc, STable st) {
throw ExceptionHandling.dieInternal(tc, "Cannot deserialize a thread");
}

public void deserialize_finish(ThreadContext tc, STable st,
SerializationReader reader, SixModelObject obj) {
throw ExceptionHandling.dieInternal(tc, "Cannot deserialize a thread");
}
}
@@ -0,0 +1,9 @@
package org.perl6.nqp.sixmodel.reprs;

import java.lang.Thread;

import org.perl6.nqp.sixmodel.SixModelObject;

public class VMThreadInstance extends SixModelObject {
public Thread thread;
}

0 comments on commit 58e1b65

Please sign in to comment.