Skip to content

Commit

Permalink
Implement missing Thread methods
Browse files Browse the repository at this point in the history
  • Loading branch information
layus committed Nov 6, 2020
1 parent d4e6d89 commit 0aa4989
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 15 deletions.
11 changes: 4 additions & 7 deletions lib/main/base/Thread.oz
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,16 @@ in
getThisPriority: GetThisPriority
this: ThisThread
is: IsThread
/*suspend: Boot_Thread.suspend
resume: Boot_Thread.resume*/
preempt: proc {$ T}
% TODO
skip
end
suspend: Boot_Thread.suspend
resume: Boot_Thread.resume
preempt: Boot_Thread.preempt
terminate: proc {$ T}
{Thread.injectException T
{Exception.system
kernel(terminate)}}
end
injectException: Boot_Thread.injectException
state: Boot_Thread.state
/*isSuspended: Boot_Thread.isSuspended*/)
isSuspended: Boot_Thread.isSuspended)

end
12 changes: 12 additions & 0 deletions vm/boostenv/main/cached/ReifiedThread-implem-decl-after.hh
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,16 @@ public:

inline
void injectException(mozart::VM vm, mozart::RichNode exception);

inline
void suspend(mozart::VM vm);

inline
void resume(mozart::VM vm);

inline
void preempt(mozart::VM vm);

inline
bool isSuspended(mozart::VM vm);
};
20 changes: 20 additions & 0 deletions vm/boostenv/main/cached/ReifiedThread-implem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,23 @@ inline
void TypedRichNode<ReifiedThread>::injectException(mozart::VM vm, mozart::RichNode exception) {
_self.access<ReifiedThread>().injectException(vm, exception);
}

inline
void TypedRichNode<ReifiedThread>::suspend(mozart::VM vm) {
_self.access<ReifiedThread>().suspend(vm);
}

inline
void TypedRichNode<ReifiedThread>::resume(mozart::VM vm) {
_self.access<ReifiedThread>().resume(vm);
}

inline
void TypedRichNode<ReifiedThread>::preempt(mozart::VM vm) {
_self.access<ReifiedThread>().preempt(vm);
}

inline
bool TypedRichNode<ReifiedThread>::isSuspended(mozart::VM vm) {
return _self.access<ReifiedThread>().isSuspended(vm);
}
49 changes: 49 additions & 0 deletions vm/vm/main/cached/ModThread-builtin.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,55 @@
"kind": "Out"
}
]
},
{
"fullCppName": "mozart::builtins::ModThread::Suspend",
"fullCppGetter": "mozart::builtins::biref::ModThread::Suspend::get",
"name": "suspend",
"inlineable": false,
"params": [
{
"name": "thread",
"kind": "In"
}
]
},
{
"fullCppName": "mozart::builtins::ModThread::Resume",
"fullCppGetter": "mozart::builtins::biref::ModThread::Resume::get",
"name": "resume",
"inlineable": false,
"params": [
{
"name": "thread",
"kind": "In"
}
]
},
{
"fullCppName": "mozart::builtins::ModThread::IsSuspended",
"fullCppGetter": "mozart::builtins::biref::ModThread::IsSuspended::get",
"name": "isSuspended",
"inlineable": false,
"params": [
{
"name": "thread",
"kind": "In"
},
{
"name": "result",
"kind": "Out"
}
]
},
{
"fullCppName": "mozart::builtins::ModThread::Preempt",
"fullCppGetter": "mozart::builtins::biref::ModThread::Preempt::get",
"name": "preempt",
"inlineable": false,
"params": [

]
}
]
}
12 changes: 12 additions & 0 deletions vm/vm/main/cached/ReifiedThread-implem-decl-after.hh
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,16 @@ public:

inline
void injectException(mozart::VM vm, mozart::RichNode exception);

inline
void suspend(mozart::VM vm);

inline
void resume(mozart::VM vm);

inline
void preempt(mozart::VM vm);

inline
bool isSuspended(mozart::VM vm);
};
20 changes: 20 additions & 0 deletions vm/vm/main/cached/ReifiedThread-implem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,23 @@ inline
void TypedRichNode<ReifiedThread>::injectException(mozart::VM vm, mozart::RichNode exception) {
_self.access<ReifiedThread>().injectException(vm, exception);
}

inline
void TypedRichNode<ReifiedThread>::suspend(mozart::VM vm) {
_self.access<ReifiedThread>().suspend(vm);
}

inline
void TypedRichNode<ReifiedThread>::resume(mozart::VM vm) {
_self.access<ReifiedThread>().resume(vm);
}

inline
void TypedRichNode<ReifiedThread>::preempt(mozart::VM vm) {
_self.access<ReifiedThread>().preempt(vm);
}

inline
bool TypedRichNode<ReifiedThread>::isSuspended(mozart::VM vm) {
return _self.access<ReifiedThread>().isSuspended(vm);
}
20 changes: 18 additions & 2 deletions vm/vm/main/cached/mozartbuiltins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1390,8 +1390,12 @@ class ModThread: public BuiltinModule {
instanceSetPriority.setModuleName("Thread");
instanceInjectException.setModuleName("Thread");
instanceState.setModuleName("Thread");
instanceSuspend.setModuleName("Thread");
instanceResume.setModuleName("Thread");
instanceIsSuspended.setModuleName("Thread");
instancePreempt.setModuleName("Thread");

UnstableField fields[7];
UnstableField fields[11];
fields[0].feature = build(vm, "create");
fields[0].value = build(vm, instanceCreate);
fields[1].feature = build(vm, "is");
Expand All @@ -1406,8 +1410,16 @@ class ModThread: public BuiltinModule {
fields[5].value = build(vm, instanceInjectException);
fields[6].feature = build(vm, "state");
fields[6].value = build(vm, instanceState);
fields[7].feature = build(vm, "suspend");
fields[7].value = build(vm, instanceSuspend);
fields[8].feature = build(vm, "resume");
fields[8].value = build(vm, instanceResume);
fields[9].feature = build(vm, "isSuspended");
fields[9].value = build(vm, instanceIsSuspended);
fields[10].feature = build(vm, "preempt");
fields[10].value = build(vm, instancePreempt);
UnstableNode label = build(vm, "export");
UnstableNode module = buildRecordDynamic(vm, label, 7, fields);
UnstableNode module = buildRecordDynamic(vm, label, 11, fields);
initModule(vm, std::move(module));
}
private:
Expand All @@ -1418,6 +1430,10 @@ class ModThread: public BuiltinModule {
mozart::builtins::ModThread::SetPriority instanceSetPriority;
mozart::builtins::ModThread::InjectException instanceInjectException;
mozart::builtins::ModThread::State instanceState;
mozart::builtins::ModThread::Suspend instanceSuspend;
mozart::builtins::ModThread::Resume instanceResume;
mozart::builtins::ModThread::IsSuspended instanceIsSuspended;
mozart::builtins::ModThread::Preempt instancePreempt;
};
void registerBuiltinModThread(VM vm) {
auto module = std::make_shared<ModThread>(vm);
Expand Down
5 changes: 5 additions & 0 deletions vm/vm/main/emulate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,11 @@ void Thread::run() {
case OpCallBuiltin0: {
BuiltinCallable(KPC(1)).callBuiltin(vm);
advancePC(1);

// Test for preemption, because Thread.preempt is a nullary builtin.
if (vm->testPreemption())
preempted = true;

break;
}

Expand Down
44 changes: 44 additions & 0 deletions vm/vm/main/modules/modthread.hh
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,50 @@ public:
result = build(vm, "blocked");
}
};

class Suspend: public Builtin<Suspend> {
public:
Suspend(): Builtin("suspend") {}

static void call(VM vm, In thread) {
Runnable* runnable = getArgument<Runnable*>(vm, thread);

runnable->suspend();
}
};

class Resume: public Builtin<Resume> {
public:
Resume(): Builtin("resume") {}

static void call(VM vm, In thread) {
Runnable* runnable = getArgument<Runnable*>(vm, thread);

runnable->resume();
}
};

class IsSuspended: public Builtin<IsSuspended> {
public:
IsSuspended(): Builtin("isSuspended") {}

static void call(VM vm, In thread, Out result) {
Runnable* runnable = getArgument<Runnable*>(vm, thread);

// FIXME: This is O(threads scheduled).
// Consider adding a field to the Runnable class.
result = build(vm, vm->getThreadPool().isScheduled(runnable));
}
};

class Preempt: public Builtin<Preempt> {
public:
Preempt(): Builtin("preempt") {}

static void call(VM vm) {
vm->requestPreempt();
}
};
};

}
Expand Down
12 changes: 12 additions & 0 deletions vm/vm/main/reifiedthread-decl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ public:
inline
void injectException(VM vm, RichNode exception);

inline
void suspend(VM vm);

inline
void resume(VM vm);

inline
void preempt(VM vm);

inline
bool isSuspended(VM vm);

private:
Runnable* _runnable;
};
Expand Down
18 changes: 18 additions & 0 deletions vm/vm/main/reifiedthread.hh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ void ReifiedThread::injectException(VM vm, RichNode exception) {
_runnable->injectException(exception.getStableRef(vm));
}

void ReifiedThread::suspend(VM vm) {
_runnable->suspend();
}

void ReifiedThread::resume(VM vm) {
_runnable->resume();
}

void ReifiedThread::preempt(VM vm) {
if (_runnable == vm->getCurrentThread()) {
vm->requestPreempt();
}
}

bool ReifiedThread::isSuspended(VM vm) {
return !vm->getThreadPool().isScheduled(_runnable);
}

}

#endif // MOZART_GENERATOR
Expand Down
12 changes: 6 additions & 6 deletions vm/vm/main/threadpool-decl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ public:
schedule(thread);
}

bool isScheduled(Runnable* thread) {
return queues[tpMiddle].isScheduled(thread) ||
queues[tpHi].isScheduled(thread) ||
queues[tpLow].isScheduled(thread);
}

void gCollect(GC gc) {
queues[tpLow].gCollect(gc);
queues[tpMiddle].gCollect(gc);
Expand All @@ -128,12 +134,6 @@ private:
inline
Runnable* popNext(ThreadPriority priority);

bool isScheduled(Runnable* thread) {
return queues[tpMiddle].isScheduled(thread) ||
queues[tpHi].isScheduled(thread) ||
queues[tpLow].isScheduled(thread);
}

ThreadQueue queues[tpCount];
int remainings[tpCount];
};
Expand Down

0 comments on commit 0aa4989

Please sign in to comment.