// IfsCtxMgr.bcpl - Creates and destroys temporary contexts
// Copyright Xerox Corporation 1979, 1982

// Last modified September 5, 1982  1:55 PM by Taft

external
[
// outgoing procedures
CreateCtx; DestroyCtx

// incoming procedures
InitializeContext; Block; Allocate; Free; Enqueue; Unqueue

// incoming statics
ifsCtxQ; sysZone; CtxRunning
]

//----------------------------------------------------------------------------
let CreateCtx(lenCtx, Proc) = valof
//----------------------------------------------------------------------------
// Creates a context of length lenCtx running Proc.
// The context may destroy itself by calling DestroyCtx.
// Note: 2 words are reserved in the allocated storage ahead of the ctx
// so that the Free (in DestroyCtx) won't clobber the ctx until it gets
// a chance to Block.  We know that the standard allocator clobbers only
// the first 2 words of the freed block.
[
let ctx = InitializeContext(Allocate(sysZone, lenCtx+2)+2, lenCtx, Proc)
Enqueue(ifsCtxQ, ctx)
resultis ctx
]

//----------------------------------------------------------------------------
and DestroyCtx() be
//----------------------------------------------------------------------------
[
Free(sysZone, CtxRunning-2)
Unqueue(ifsCtxQ, CtxRunning)
CtxRunning!0 = 0  // so CallContextList will start over -- CtxRunning has no successor!
Block()  // never to return...
]