lwp_checkstkset, lwp_stkcswset, CHECK, lwp_setstkcache, lwp_newstk,
lwp_datastk, STKTOP - LWP stack management
int lwp_checkstkset(tid, limit)
int lwp_stkcswset(tid, limit)
int lwp_setstkcache(minstksz, numstks)
stkalign_t *lwp_datastk(data, size, addr)
Stacks are problematical with lightweight processes. What is desired
is that stacks for each thread are red-zone protected so that one
thread's stack does not unexpectedly grow into the stack of another.
In addition, stacks should be of infinite length, grown as needed. The
process stack is a maximum-sized segment (see getrlimit(2).) This
stack is redzone protected, and you can even try to extend it beyond
its initial maximum size in some cases. With SunOS 4.x, it is possible
to efficiently allocate large stacks that have red zone protection, and
the LWP library provides some support for this. For those systems that
do not have flexible memory management, the LWP library provides assis-
tance in dealing with the problems of maintaining multiple stacks.
The stack used by main() is the same stack that the system allocates
for a process on fork(2V). For allocating other thread stacks, the
client is free to use any statically or dynamically allocated memory
(using memory from main()'s stack is subject to the stack resource
limit for any process created by fork()). In addition, the LASTRITES
agent message is available to free allocated resources when a thread
dies. The size of any stack should be at least MINSTACKSZ * sizeof
(stkalign_t), because the LWP library will use the client stack to exe-
cute primitives. For very fast dynamically allocated stacks, a stack
cacheing mechanism is available. lwp_setstkcache() allocates a cache
of stacks. Each time the cache is empty, it is filled with numstks new
stacks, each containing at least minstksz bytes. minstksz will auto-
matically be augmented to take into account the stack needs of the LWP
library. lwp_newstk() returns a cached stack that is suitable for use
in an lwp_create() call. lwp_setstkcache() must be called (once) prior
to any use of lwp_newstk. If running under SunOS 4.x, the stacks allo-
cated by lwp_newstk() will be red-zone protected (an attempt to refer-
ence below the stack bottom will result in a SIGSEGV event).
Threads created with stacks from lwp_newstk() should not use the NOLAS-
TRITES flag. If they do, cached stacks will not be returned to the
cache when a thread dies.
lwp_datastk() also returns a red-zone protected stack like lwp_newstk()
does. It copies any amount of data (subject to the size limitations
imposed by lwp_setstkcache) onto the stack above the stack top that it
returns. data points to information of size bytes to be copied. The
exact location where the data is stored is returned in the reference
parameter addr. Because lwp_create() only passes simple types to the
newly-created thread, lwp_datastk() is useful to pass a more complex
argument: Call lwp_datastk() to get an initialized stack, and pass the
address of the data structure (addr) as an argument to the new thread.
A reaper thread running at the maximum pod priority is created by
lwp_setstkcache. It's action may be delayed by other threads running
at that priority, so it is suggested that the maximum pod priority not
be used for client-created threads when lwp_newstk() is being used.
Altering the maximum pod priority with pod_setmaxpri() will have the
side effect of increasing the reaper thread priority as well.
The stack address passed to lwp_create() represents the top of the
stack: the LWP library will not use any addresses at or above it.
Thus, it is safe to store information above the stack top if there is
For stacks that are not protected with hardware redzones, some protec-
tion is still possible. For any thread tid with stack boundary limit
made part of a special context with lwp_checkstkset(), the CHECK macro
may be used. This macro, if used at the beginning of each procedure
(and before local storage is initialized (it is all right to declare
locals though)), will check that the stack limit has not been violated.
If it has, the non-local location will be set to result and the proce-
dure will return. CHECK is not perfect, as it is possible to call a
procedure with many arguments after CHECK validates the stack, only to
have these arguments clobber the stack before the new procedure is
lwp_stkcswset() checks at context-switch time the stack belonging to
thread tid for passing stack boundary limit. In addition, a checksum
at the bottom of the stack is validated to ensure that the stack did
not temporarily grow beyond its limit. This is automated and more
efficient than using CHECK, but by the time a context switch occurs,
it's too late to do much but abort(3) if the stack was clobbered.
To portably use statically allocated stacks, the macros in <<lwp/stack-
dep.h>> should be used. Declare a stack s to be an array of stkalign_t,
and pass the stack to lwp_create() as STKTOP(s).
lwp_checkstkset() and lwp_stkcswset() return 0.
lwp_setstkcache() returns the actual size of the stacks allocated in
lwp_newstk() and lwp_datastk() return a valid new stack address on suc-
cess. On failure, they return 0.
lwp_datastk() should not be directly used in a lwp_create() call since
C does not guarantee the order in which arguments to a function are
C should provide support for heap-allocated stacks at procedure entry
time. The hardware should be segment-based to eliminate the problem
21 January 1990 LWP_NEWSTK(3L)