1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#pragma once
#include "Core/Object.h"
#include "Core/EnginePtr.h"
#include "OS/UThread.h"
#include "Gc/Gc.h"
namespace storm {
STORM_PKG(core.unsafe);
/**
* Stores a copy of a UThread's stack alongside a reference to the thread itself.
*
* This makes it possible to restore the state of that UThread to the state when it was saved.
* This makes it possible to implement continuations and effects.
*/
class StackMirror : public Object {
STORM_CLASS;
public:
// Copy. Note: DeepCopy is not needed.
StackMirror(const StackMirror &o);
// Destroy, free memory.
~StackMirror();
// Assign.
StackMirror &operator =(const StackMirror &o);
// Early destruction of the stack mirror.
void STORM_FN clear();
// Create a copy of the current state of an UThread. 'threadId' is expected to be the value
// returned from 'currentUThread', and the thread is expected to be alive and currently not
// running. Ideally, the thread should be waiting for some synchronization event, like a
// semaphore.
static StackMirror *STORM_FN save(EnginePtr e, Word threadId);
// Restore the stack to the previously saved UThread. Assumes that the thread is not
// currently running. If the thread is not currently present in a ready-queue, then the
// thread is immediately placed there.
Bool STORM_FN restore();
private:
// Create.
StackMirror(os::UThreadData *thread);
// UThread that the stack was copied from.
// We hold a reference to this thread.
UNKNOWN(PTR_NOGC) os::UThreadData *thread;
// Registered GC root.
UNKNOWN(PTR_NOGC) Gc::Root *root;
// Copied stack contents, from the base of the stack.
UNKNOWN(PTR_NOGC) size_t *stackContents;
// Number of words in the stack contents.
size_t stackCount;
// Allocate memory for 'stackContents'. Assumes that it was previously empty.
void allocContents(size_t count);
// Free memory in 'stackContents'.
void freeContents();
};
}
|