/* * File: thread.h * -------------- * This interface exports a platform-independent thread abstraction, along * with simple functions for concurrency control. */ #ifndef _thread_h #define _thread_h #include <setjmp.h> #include "cslib.h" #ifdef __macosx__ # define getCurrentThread XgetCurrentThread #endif/* * Type: Thread * ------------ * The Thread type is used to represent a thread, which is a lightweight * process running in the same address space as the creator. */ typedef struct ThreadCDT *Thread;/* * Type: Lock * ---------- * The Lock type is used to manage concurrent access to some data structure * within an application. Only one thread can hold a lock at any point in * time; other threads seeking to gain access queue on the lock until it is * released by the thread that originally obtained it. The general * strategy for using a lock is to use the synchronized statement to * protect a critical region of code, as illustrated in the discussion of * synchronized later in this file. */ typedef struct LockCDT *Lock;/* Exported entries */ /* * Function: forkThread * Usage: thread = forkThread(fn, data); * ------------------------------------- * Forks a new thread to invokes the specified function, passing data as an * argument. Threads created by forkThread become dormant on completion * and wait for the client to synchronize with them using a joinThread * operation. */ Thread forkThread(proc fn, void *data);/* * Function: joinThread * Usage: joinThread(thread); * -------------------------- * Waits for the specified thread to finish before proceeding. */ void joinThread(Thread thread);/* * Function: yield * Usage: yield(); * --------------- * Yields the processor to allow another thread to run. */ void yield(void);/* * Function: getCurrentThread * Usage: self = getCurrentThread(); * --------------------------------- * Returns the currently executing thread. */ Thread getCurrentThread(void);/* * Function: setThreadName * Usage: setThreadName(thread, name); * ----------------------------------- * Sets the name of a thread to the given string. This name is used * primarily for debugging purposes. */ void setThreadName(Thread thread, string name);/* * Function: getThreadName * Usage: name = getThreadName(thread); * ------------------------------------ * Returns the name of the specified thread. If no name has been set for * the thread, this function returns a string in the form Thread<xxx>, * where xxx is an integer uniquely identifying the thread. */ string getThreadName(Thread thread);/* * Function: newLock * Usage: lock = newLock(); * ------------------------ * Creates a new Lock object. */ Lock newLock(void);/* * Macro: synchronized * Usage: synchronized (lock) { . . . } * ------------------------------------ * Defines a critical section protected by the specified lock. The general * strategy for using this facility is shown in the following paradigmatic * pattern: * * synchronized (lock) { * . . . statements in the critical section . . . * } */ #define synchronized(lock) for ( ; startSync(lock) ; endSync(lock))/* * Function: waitThread * Usage: waitThread(lock); * ------------------------ * Waits for some other thread to issue a call to signalThread on this * lock. This call requires that the lock be owned by the calling thread. * The effect of this function is to release the lock and then wait until * the desired signalThread operation occurs, at which point the lock is * reacquired and control passes to the statement following the waitThread. * * The waitThread function is useful only if the call is embedded inside a * while loop that checks a condition before proceeding. That while * statement must itself be embedded inside a synchronized statement that * acquires the lock. Thus, the standard paradigm for using the waitThread * function looks like this: * * synchronized (lock) { * while (conditional test) { * waitThread(lock); * } * . . . code to manipulate the locked resource . . . * } */ void waitThread(Lock lock);/* * Function: signalThread * Usage: signalThread(lock); * -------------------------- * Signals all threads waiting on the lock so that they wake up and recheck * the corresponding condition. */ void signalThread(Lock lock);/* Internal entry points -- see implementation for details */ bool startSync(Lock lock); void endSync(Lock lock); void lockInternal(Lock lock); void unlockInternal(Lock lock); #endif