/* Copyright (c) 1993 Xerox Corporation. All rights reserved. */ /* $Id$ $Date$ * * PCR threads dynamic environment manipulation * */ #ifndef ←←PCR←ThDynEnv←h #define ←←PCR←ThDynEnv←h 1 #include <config/PCR←Arch.h> #include <config/PCR←StdTypes.h> #include <th/PCR←ThData.h> #define PCR←ThDynEnv←propIndex 0 typedef struct PCR←ThDynEnv←FrameRep *PCR←ThDynEnv←FramePtr; typedef struct PCR←ThDynEnv←FrameRep { PCR←ThDynEnv←FramePtr df←link; PCR←Any df←key; PCR←Any df←data[1 /* really depends on key */]; } PCR←ThDynEnv←Frame; extern PCR←ThDynEnv←FramePtr PCR←ThDynEnv←Get(void); #define PCR←ThDynEnv←←Get() ((PCR←ThDynEnv←FramePtr)(\ PCR←ThData←Get()->td←←propData[PCR←ThDynEnv←propIndex])) #ifndef PCR←ThDynEnv←NINLINE # define PCR←ThDynEnv←Get PCR←ThDynEnv←←Get #endif /* Return the dynamic environment of the current thread. */ extern void PCR←ThDynEnv←Set(PCR←ThDynEnv←FramePtr fp); #define PCR←ThDynEnv←←Set(fp) { \ PCR←ThData←Get()->td←←propData[PCR←ThDynEnv←propIndex] = \ ((void *)(fp)); } #ifndef PCR←ThDynEnv←NINLINE # define PCR←ThDynEnv←Set PCR←ThDynEnv←←Set #endif /* Set the dynamic environment of the current thread to fp. */ extern PCR←ThDynEnv←FramePtr PCR←ThDynEnv←Lookup(PCR←Any key, PCR←ThDynEnv←FramePtr fp); /* Return the first frame in de with the given key, or NIL if there is none. */ extern PCR←ThDynEnv←FramePtr PCR←ThDynEnv←FirstCommonParent( PCR←ThDynEnv←FramePtr fp1, PCR←ThDynEnv←FramePtr fp2 ); /* Return the first frame that is a tail of both arguments, or NIL if there is none. */ typedef PCR←ERes PCR←ThDynEnv←Unwinder(PCR←ThDynEnv←FramePtr fp, PCR←Any data); extern PCR←ERes PCR←ThDynEnv←Unwind( PCR←ThDynEnv←FramePtr target, PCR←Any key, PCR←ThDynEnv←Unwinder *unwinder, PCR←Any unwinderData ); /* Target must be a tail of the current dynamic environment. This call has the same effect as PCR←ThDynEnv←Set except that (*unwinder)(f, unwinderData) is called for each frame f in the difference between the current dynamic environment and the target such that f matches key (i.e., (f->df←key == key) or (key == NIL)). Before (*unwinder)(f, d) is called, the dynamic environment is set to what was in effect when the frame f was pushed. Returns EINVAL if target is not a tail of the current dynamic environment. If any of the unwinder calls returns an error, the unwinding terminates and that error is returned from the call to Unwind. NOTE that this call will not return at all if any of the unwinders that it calls does not do so. */ typedef PCR←ERes PCR←ThDynEnv←Rewinder(PCR←ThDynEnv←FramePtr fp, PCR←Any data); extern PCR←ERes PCR←ThDynEnv←Rewind( PCR←ThDynEnv←FramePtr target, PCR←Any key, PCR←ThDynEnv←Rewinder *rewinder, PCR←Any rewinderData ); /* The current dynamic environment must be a tail of target. This call has the same effect as PCR←ThDynEnv←Set except that (*rewinder)(f, rewinderData) is called for each frame f in the difference between target and the current dynamic environment such that f matches key (i.e., (f->df←key == key) or (key == NIL)). Before (*rewinder)(f, d) is called, the dynamic environment is set to what was in effect when the frame f was pushed. Returns okay if the current dynamic environment is a tail of target, and EINVAL otherwise. NOTE that this call will not return at all if any of the rewinders that it calls does not do so. */ extern const PCR←Any PCR←ThDynEnv←unwindFrameKey; typedef struct PCR←ThDynEnv←UnwindFrameRep *PCR←ThDynEnv←UnwindFramePtr; typedef struct PCR←ThDynEnv←UnwindFrameRep { PCR←ThDynEnv←UnwindFramePtr uf←link; PCR←Any uf←key; void (*uf←unwinder)(PCR←Any data); PCR←Any uf←unwinderData; void (*uf←rewinder)(PCR←Any data); PCR←Any uf←rewinderData; } PCR←ThDynEnv←UnwindFrame; extern PCR←ThDynEnv←Unwinder PCR←ThDynEnv←UnwinderTo; /* Assuming argument frame has type PCR←ThDynEnv←UnwindFrame, call its uf←unwinder. */ extern PCR←ERes PCR←ThDynEnv←UnwindTo(PCR←ThDynEnv←UnwindFramePtr target); /* return PCR←ThDynEnv←Unwind( target, PCR←ThDynEnv←unwindFrameKey, PCR←ThDynEnv←UnwinderTo, NIL ); */ extern PCR←ThDynEnv←Rewinder PCR←ThDynEnv←RewinderTo; /* Assuming argument frame has type PCR←ThDynEnv←UnwindFrame, call its uf←rewinder. */ extern PCR←ERes PCR←ThDynEnv←RewindTo(PCR←ThDynEnv←UnwindFramePtr target); /* return PCR←ThDynEnv←Unwind( target, PCR←ThDynEnv←unwindFrameKey, PCR←ThDynEnv←RewinderTo, NIL ); */ #endif /* ! ←←PCR←ThDynEnv←h */ /* $Log$ */