Files
ldc/druntime/import/core/thread.di

793 lines
8.7 KiB
D

// D import file generated from 'core/thread.d'
module core.thread;
version = StackGrowsDown;
class ThreadException : Exception
{
this(string msg)
{
super(msg);
}
}
class FiberException : Exception
{
this(string msg)
{
super(msg);
}
}
private
{
extern (C)
{
void* rt_stackBottom();
}
extern (C)
{
void* rt_stackTop();
}
void* getStackBottom()
{
return rt_stackBottom();
}
void* getStackTop();
}
version (Windows)
{
private
{
import stdc.stdint;
import sys.windows.windows;
const
{
DWORD TLS_OUT_OF_INDEXES = -1u;
}
extern (Windows)
{
alias uint function(void*) btex_fptr;
}
extern (C)
{
uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*);
}
extern (Windows)
{
uint thread_entryPoint(void* arg);
}
HANDLE GetCurrentThreadHandle()
{
const uint DUPLICATE_SAME_ACCESS = 2;
HANDLE curr = GetCurrentThread();
HANDLE proc = GetCurrentProcess();
HANDLE hndl;
DuplicateHandle(proc,curr,proc,&hndl,0,TRUE,DUPLICATE_SAME_ACCESS);
return hndl;
}
}
}
else
{
version (Posix)
{
private
{
import stdc.posix.semaphore;
import stdc.posix.pthread;
import stdc.posix.signal;
import stdc.posix.time;
import stdc.errno;
extern (C)
{
int getErrno();
}
version (GNU)
{
import gcc.builtins;
}
extern (C)
{
void* thread_entryPoint(void* arg);
}
sem_t suspendCount;
extern (C)
{
void thread_suspendHandler(int sig);
}
extern (C)
{
void thread_resumeHandler(int sig)
in
{
assert(sig == SIGUSR2);
}
body
{
}
}
}
}
else
{
static assert(false,"Unknown threading implementation.");
}
}
class Thread
{
this(void function() fn, size_t sz = 0)
in
{
assert(fn);
}
body
{
m_fn = fn;
m_sz = sz;
m_call = Call.FN;
m_curr = &m_main;
}
this(void delegate() dg, size_t sz = 0)
in
{
assert(dg);
}
body
{
m_dg = dg;
m_sz = sz;
m_call = Call.DG;
m_curr = &m_main;
}
final
{
void start();
}
final
{
Object join(bool rethrow = true);
}
final
{
char[] name();
}
final
{
void name(char[] val);
}
final
{
bool isDaemon();
}
final
{
void isDaemon(bool val);
}
final
{
bool isRunning();
}
static const
{
int PRIORITY_MIN;
}
static const
{
int PRIORITY_MAX;
}
final
{
int priority();
}
final
{
void priority(int val);
}
static
{
void sleep(long period);
}
static
{
void yield();
}
static
{
Thread getThis();
}
static
{
Thread[] getAll();
}
static
{
int opApply(int delegate(ref Thread) dg);
}
static const
{
uint LOCAL_MAX = 64;
}
static
{
uint createLocal();
}
static
{
void deleteLocal(uint key);
}
static
{
void* getLocal(uint key)
{
return getThis().m_local[key];
}
}
static
{
void* setLocal(uint key, void* val)
{
return getThis().m_local[key] = val;
}
}
static this();
private
{
this()
{
m_call = Call.NO;
m_curr = &m_main;
}
final
{
void run();
}
private
{
enum Call
{
NO,
FN,
DG,
}
version (Win32)
{
alias uint TLSKey;
alias uint ThreadAddr;
}
else
{
version (Posix)
{
alias pthread_key_t TLSKey;
alias pthread_t ThreadAddr;
}
}
static
{
bool[LOCAL_MAX] sm_local;
}
static
{
TLSKey sm_this;
}
void*[LOCAL_MAX] m_local;
version (Win32)
{
HANDLE m_hndl;
}
ThreadAddr m_addr;
Call m_call;
char[] m_name;
union
{
void function() m_fn;
void delegate() m_dg;
}
size_t m_sz;
version (Posix)
{
bool m_isRunning;
}
bool m_isDaemon;
Object m_unhandled;
private
{
static
{
void setThis(Thread t);
}
private
{
final
{
void pushContext(Context* c)
in
{
assert(!c.within);
}
body
{
c.within = m_curr;
m_curr = c;
}
}
final
{
void popContext()
in
{
assert(m_curr && m_curr.within);
}
body
{
Context* c = m_curr;
m_curr = c.within;
c.within = null;
}
}
final
{
Context* topContext()
in
{
assert(m_curr);
}
body
{
return m_curr;
}
}
static
{
struct Context
{
void* bstack;
void* tstack;
Context* within;
Context* next;
Context* prev;
}
}
Context m_main;
Context* m_curr;
bool m_lock;
version (Win32)
{
uint[8] m_reg;
}
private
{
static
{
Object slock()
{
return Thread.classinfo;
}
}
static
{
Context* sm_cbeg;
}
static
{
size_t sm_clen;
}
static
{
Thread sm_tbeg;
}
static
{
size_t sm_tlen;
}
Thread prev;
Thread next;
static
{
void add(Context* c);
}
static
{
void remove(Context* c);
}
static
{
void add(Thread t);
}
static
{
void remove(Thread t);
}
}
}
}
}
}
}
extern (C)
{
void thread_init();
}
extern (C)
{
void thread_attachThis();
}
extern (C)
{
void thread_detachThis()
{
Thread.remove(Thread.getThis());
}
}
extern (C)
{
void thread_joinAll();
}
private
{
bool multiThreadedFlag = false;
}
extern (C)
{
bool thread_needLock()
{
return multiThreadedFlag;
}
}
private
{
uint suspendDepth = 0;
}
extern (C)
{
void thread_suspendAll();
}
extern (C)
{
void thread_resumeAll();
}
private
{
alias void delegate(void*, void*) scanAllThreadsFn;
}
extern (C)
{
void thread_scanAll(scanAllThreadsFn scan, void* curStackTop = null);
}
template ThreadLocal(T)
{
class ThreadLocal
{
this(T def = T.init)
{
m_def = def;
m_key = Thread.createLocal();
}
T val()
{
Wrap* wrap = cast(Wrap*)Thread.getLocal(m_key);
return wrap ? wrap.val : m_def;
}
T val(T newval)
{
Wrap* wrap = cast(Wrap*)Thread.getLocal(m_key);
if (wrap is null)
{
wrap = new Wrap;
Thread.setLocal(m_key,wrap);
}
wrap.val = newval;
return newval;
}
private
{
struct Wrap
{
T val;
}
T m_def;
uint m_key;
}
}
}
class ThreadGroup
{
final
{
Thread create(void function() fn);
}
final
{
Thread create(void delegate() dg);
}
final
{
void add(Thread t);
}
final
{
void remove(Thread t);
}
final
{
int opApply(int delegate(ref Thread) dg);
}
final
{
void joinAll(bool rethrow = true);
}
private
{
Thread[Thread] m_all;
}
}
private
{
version (D_InlineAsm_X86)
{
version (X86_64)
{
}
else
{
version (Win32)
{
version = AsmX86_Win32;
}
else
{
version (Posix)
{
version = AsmX86_Posix;
}
}
}
}
else
{
version (PPC)
{
version (Posix)
{
version = AsmPPC_Posix;
}
}
}
version (LLVM_InlineAsm_X86)
{
version (Win32)
{
version = LLVM_AsmX86_Win32;
}
else
{
version (Posix)
{
version = LLVM_AsmX86_Posix;
}
}
}
else
{
version (LLVM_InlineAsm_X86_64)
{
version (Posix)
{
version = LLVM_AsmX86_64_Posix;
}
}
}
version (Posix)
{
import stdc.posix.unistd;
import stdc.posix.sys.mman;
import stdc.posix.stdlib;
version (AsmX86_Win32)
{
}
else
{
version (AsmX86_Posix)
{
}
else
{
version (AsmPPC_Posix)
{
}
else
{
version (LLVM_AsmX86_Win32)
{
}
else
{
version (LLVM_AsmX86_Posix)
{
}
else
{
import stdc.posix.ucontext;
}
}
}
}
}
}
const
{
size_t PAGESIZE;
}
}
static this();
private
{
extern (C)
{
void fiber_entryPoint();
}
version (AsmPPC_Posix)
{
extern (C)
{
void fiber_switchContext(void** oldp, void* newp);
}
}
else
{
extern (C)
{
void fiber_switchContext(void** oldp, void* newp);
}
}
}
class Fiber
{
this(void function() fn, size_t sz = PAGESIZE)
in
{
assert(fn);
}
body
{
m_fn = fn;
m_call = Call.FN;
m_state = State.HOLD;
allocStack(sz);
initStack();
}
this(void delegate() dg, size_t sz = PAGESIZE)
in
{
assert(dg);
}
body
{
m_dg = dg;
m_call = Call.DG;
m_state = State.HOLD;
allocStack(sz);
initStack();
}
final
{
Object call(bool rethrow = true);
}
final
{
void reset()
in
{
assert(m_state == State.TERM);
assert(m_ctxt.tstack == m_ctxt.bstack);
}
body
{
m_state = State.HOLD;
initStack();
m_unhandled = null;
}
}
enum State
{
HOLD,
EXEC,
TERM,
}
final
{
State state()
{
return m_state;
}
}
static
{
void yield();
}
static
{
void yieldAndThrow(Object obj);
}
static
{
Fiber getThis();
}
static this();
private
{
this()
{
m_call = Call.NO;
}
final
{
void run();
}
private
{
enum Call
{
NO,
FN,
DG,
}
Call m_call;
union
{
void function() m_fn;
void delegate() m_dg;
}
bool m_isRunning;
Object m_unhandled;
State m_state;
private
{
final
{
void allocStack(size_t sz);
}
final
{
void freeStack();
}
final
{
void initStack();
}
Thread.Context* m_ctxt;
size_t m_size;
void* m_pmem;
static if(is(ucontext_t))
{
static
{
ucontext_t sm_utxt = void;
}
ucontext_t m_utxt = void;
ucontext_t* m_ucur = null;
}
private
{
static
{
void setThis(Fiber f);
}
static
{
Thread.TLSKey sm_this;
}
private
{
final
{
void switchIn();
}
final
{
void switchOut();
}
}
}
}
}
}
}