Copyright (C) 1994, Digital Equipment Corp.
UNSAFE MODULE--------------------------------------------------------- thread stacks ---; IMPORT Word, Usignal, Unix, Umman, RTMisc; CONST SP_pos = 32; PROCEDURE RTThread SP (READONLY s: State): ADDRESS = BEGIN RETURN LOOPHOLE (s [SP_pos], ADDRESS); END SP;
VAR page_bytes : CARDINAL := 0; VAR stack_slop : CARDINAL; PROCEDURE-------------------------------------------------- modifying the models ---NewStack (size: INTEGER; VAR(*OUT*)s: Stack) = VAR i: INTEGER; start: ADDRESS; BEGIN IF (page_bytes = 0) THEN page_bytes := Unix.getpagesize (); stack_slop := 2 * (page_bytes DIV BYTESIZE (INTEGER)); END; (* allocate enough so that we're guaranteed to get a full, aligned page *) INC (size, stack_slop); s.words := NEW (StackSpace, size); (* find the aligned page and unmap it *) start := RTMisc.Align (ADR (s.words[0]), page_bytes); i := Umman.mprotect (start, page_bytes, Umman.PROT_READ); <* ASSERT i = page_bytes *> (* The protection should be 0, but a bug in MIPS/Ultrix 4.2 (vmdup) causes kernel panics when it is. Making the page read-only is good enough to prevent unchecked runtime errors *) (* finally, set the bounds of the usable region *) s.first := start + page_bytes; s.last := ADR (s.words[0]) + size * ADRSIZE (s.words[0]); END NewStack; PROCEDUREDisposeStack (VAR s: Stack) = VAR i: INTEGER; start := RTMisc.Align (ADR (s.words[0]), page_bytes); BEGIN (* find the aligned page and re-map it *) i := Umman.mprotect (start, page_bytes, Umman.PROT_READ+Umman.PROT_WRITE); <* ASSERT i = page_bytes *> (* and finally, free the storage *) DISPOSE (s.words); s.words := NIL; s.first := NIL; s.last := NIL; END DisposeStack; PROCEDUREFlushStackCache () = VAR d: State; BEGIN Transfer (d, d); END FlushStackCache;
PROCEDURE------------------------------------ manipulating the SIGVTALRM handler ---UpdateStateForNewSP (VAR s: State; offset: INTEGER) = BEGIN INC (s [SP_pos], offset); END UpdateStateForNewSP; PROCEDUREUpdateFrameForNewSP (<*UNUSED*> a: ADDRESS; <*UNUSED*> offset: INTEGER) = BEGIN END UpdateFrameForNewSP;
PROCEDUREsetup_sigvtalrm (handler: Usignal.SignalHandler) = VAR sv, osv: Usignal.struct_sigvec; i: INTEGER; BEGIN sv.sv_handler := handler; sv.sv_mask := Usignal.empty_sv_mask; sv.sv_flags := 0; i := Usignal.sigvec (Usignal.SIGVTALRM, sv, osv); <*ASSERT i = 0*> END setup_sigvtalrm; PROCEDUREallow_sigvtalrm () = VAR i : Word.T; BEGIN i := Usignal.sigsetmask (0); i := Word.And (i, Word.Not (Usignal.sigmask (Usignal.SIGVTALRM))); EVAL Usignal.sigsetmask (i); END allow_sigvtalrm; PROCEDUREdisallow_sigvtalrm () = VAR i : Word.T; BEGIN i := Usignal.sigsetmask (0); i := Word.Or (i, Usignal.sigmask (Usignal.SIGVTALRM)); EVAL Usignal.sigsetmask (i); END disallow_sigvtalrm; BEGIN END RTThread.