/* Copyright (c) 1993 Xerox Corporation. All rights reserved. */ /* $Id$ $Date$ * * PCR←ThCtl -- "Thread Control" interface. * * Nearly machine independent. * Mostly for use by GC and Debugger. * */ #ifndef ←←PCR←ThCtl←h #define ←←PCR←ThCtl←h 1 #include <config/PCR←StdTypes.h> #include <th/PCR←ThTypes.h> #include <th/PCR←ThCtlTypes.h> /* * RunExclusive * * Used to stop the world (briefly?) ... */ typedef enum { /* nonexclusive ... */ PCR←ThCtl←ExclusiveMode←null = 0, /* stop threads attempting to write clean pages (see PCR←VD.h) */ PCR←ThCtl←ExclusiveMode←stopWriters = 1, /* stop all threads not ignoring exclusive */ PCR←ThCtl←ExclusiveMode←stopNormal = 2, /* stop all threads except self */ PCR←ThCtl←ExclusiveMode←stopAll = 3, PCR←ThCtl←ExclusiveMode←last = LONG←MAX } PCR←ThCtl←ExclusiveMode; extern PCR←ThCtl←ExclusiveMode PCR←ThCtl←GetExclusiveMode(void); extern PCR←ERes PCR←ThCtl←SetExclusiveMode( PCR←ThCtl←ExclusiveMode mode, const PCR←sigset←t *sigMask, PCR←Msec wakeup ); /* Get/Set exclusive running mode. Setting mode non-null acquires a lock; setting mode to null releases the lock. Success: PCR←ERes←okay Failure: PCR←ETIMEDOUT EINVAL */ extern PCR←Bool PCR←ThCtl←GetIgnoreRunExclusive(void); extern void PCR←ThCtl←SetIgnoreRunExclusive(PCR←Bool ignore); /* Get/Set ignore-run-exclusive property for this thread WIZARDS ONLY: threads that ignore run-exclusive must be very well-behaved to avoid confusing the debugger (which would be annoying) and the GC (which would be catastrophic). In particular, they are expected never to write on pages that are being managed by any virtual dirty bits implementation. */ /* * Thread enumeration */ typedef PCR←ERes (PCR←ThCtl←EachThreadProc)(PCR←Th←T *t, PCR←Any data); /* Callback for PCR←ThCtl←ApplyToAllOtherThreads below. Called in critical section -- may not allocate, etc. */ extern PCR←ERes PCR←ThCtl←ApplyToAllOtherThreads( PCR←ThCtl←EachThreadProc *proc, PCR←Any data ); /* Enumerate all threads except current one. Apply (*proc)(thread, data) to each, in critical section. If that call returns a result other than PCR←ERes←okay, terminate the enumeration returning that result. Otherwise return PCR←ERes←okay. Note that proc is called in critical section, so it cannot wait, allocate, etc. This is inconvenient, but necessary to give a consistent snapshot of thread state. Most clients will want to use PCR←ThCtl←Enumerate, below. */ extern PCR←ERes PCR←ThCtl←GetThreads(PCR←Th←T ** t, unsigned nt); /* Enumerate all nonterminated threads, or as many as will fit, *not* including the current thread, into the supplied array of PCR←Th←T *'s. Return the total number of nonterminated threads, not counting the current thread. This may exceed nt. May be called in critical section, in which case state of thread table won't change until exit from the critical section. It is okay for t to be NIL if nt is 0. Success: number of threads to be stored. Failure: EFAULT -- bad t */ /* * * Querying thread state * */ extern PCR←ERes PCR←ThCtl←GetInfo( PCR←Th←T *t, PCR←ThCtl←TInfo *ti /* result */ ); /* Get thread info about specified thread. For a thread t other than the caller, the information reflects the state of t the last time it was switched away from. Thus, the information is guaranteed reliable if the caller can guarantee t won't be switched to again, e.g. the caller is holding the run-exclusive lock and t is not ignoring it. If t is the caller (or NIL), the information reflects the state at the point of the call. The state will change immediately, but in ways that are under the caller's control. May be called from a critical section. Success: 0 Failure: EFAULT or EINVAL if t not a valid thread pointer; */ extern PCR←ERes PCR←ThCtl←SetInfo( PCR←Th←T *t, PCR←ThCtl←TInfo *ti ); /* Set thread info about specified thread. WIZARDS AND DEBUGGER WRITERS ONLY! It is not legal to do this to yourself. May be called from a critical section. The fields that are set: pri ignoreRunExclusive state (if not null) stkLow (if not NIL) stkHi (if not NIL) mdContext (if not NIL) Success: 0 Failure: EFAULT or EINVAL */ #endif /* ! ←←PCR←ThCtl←h */ /* $Log$ */