LWP_CTXINIT(3L)

NAME
lwp_ctxinit, lwp_ctxremove, lwp_ctxset, lwp_ctxmemget, lwp_ctxmemset, lwp_fpset, lwp_libcset - special LWP context operations

SYNOPSIS

#include <lwp/lwp.h>

int lwp_ctxset(save, restore, ctxsize, optimize)
void (*save)(/* caddr_t ctx, thread_t old, thread_t new */);
void (*restore)(/* caddr_t ctx, thread_t old, thread_t new */);
unsigned int ctxsize;
int optimize;

int lwp_ctxinit(tid, cookie)
thread_t tid;		/* thread with special contexts */
int cookie;		/* type of context */

int lwp_ctxremove(tid, cookie)
thread_t tid;
int cookie;

int lwp_ctxmemget(mem, tid, ctx)
caddr_t mem;
thread_t tid;
int ctx;

int lwp_ctxmemset(mem, tid, ctx)
caddr_t mem;
thread_t tid;
int ctx;

int lwp_fpset(tid)
thread_t tid;		/* thread utilizing floating point hardware */

int lwp_libcset(tid)
thread_t tid;		/* thread utilizing errno */

DESCRIPTION

Normally on a context switch, only machine registers are saved/restored to provide each thread its own virtual machine. However, there are other hardware and software resources which can be multiplexed in this way. For example, floating point registers can be used by several threads in a pod. As another example, the global value errno in the standard C library may be used by all threads making system calls.

To accommodate the variety of contexts that a thread may need without requiring all threads to pay for unneeded switching overhead, lwp_ctxinit() is provided. This primitive allows a client to specify that a given thread requires certain context to be saved and restored across context switches (by default just the machine registers are switched). More than one special context may be given to a thread.

To use lwp_ctxinit(), it is first necessary to define a special context. lwp_ctxset() specifies save and restore routines, as well as the size of the context that will be used to hold the switchable state. The save routine will automatically be invoked when an active thread is blocked and the restore routine will be invoked when a blocked thread is restarted. These routines will be passed a pointer to a buffer (initialized to all 0's) of size ctxsize which is allocated by the LWP library and used to hold the volatile state. In addition, the identity of the thread whose special context is being saved (old) and the identity of the thread being restarted (new) are passed in to the save and restore routines. lwp_ctxset() returns a cookie used by subsequent lwp_ctxinit() calls to refer to the kind of context just defined. If the optimize flag is TRUE, a special context switch action will not be invoked unless the thread resuming execution differs from the last thread to use the special context and also uses the special context. If the optimize flag is FALSE, the save routine will always be invoked immediately when the thread using this context is scheduled out and the restore routine will be invoked immediately when a new thread using this context is scheduled in. Note that an unoptimized special context is protected from threads which do not use the special context but which do affect the context state. lwp_ctxremove() can be used to remove a special context installed by lwp_ctxinit().

Because context switching is done by the scheduler on behalf of a thread, it is an error to use an LWP primitive in an action done at context switch time. Also, the stack used by the save and restore routines belongs to the scheduler, so care should be taken not to use lots of stack space. As a result of these restrictions, only knowledgeable users should write their own special context switching routines.

lwp_ctxmemget() and lwp_ctxmemset() are used to retrieve and set (respectively) the memory associated with a given special context (ctx) and a given thread (tid). mem is the address of client memory that will hold the context information being retrieved or set. Note that the special context save and restore routines may be NULL, so pure data may be associated with a given thread using these primitives.

Several kinds of special contexts are predefined. To allow a thread to share floating point hardware with other threads, the lwp_fpset() primitive is available. The floating-point hardware bound at compile-time is selected automatically. To multiplex the global variable errno, lwp_libcset() is used to have errno become part of the context of thread tid.

Special contexts can be used to assist in managing stacks. See lwp_newstk(3L) for details.

RETURN VALUES

On success, lwp_ctxset() returns a cookie to be used by subsequent calls to lwp_ctxinit(). If unable to define the context, it returns -1.

ERRORS
lwp_ctxinit() will fail if one or more of the following are true:

LE_INUSE
    This special context already set for this thread.

lwp_ctxremove() will fail if one or more of the following are true:

LE_NONEXIST
    The specified context is not set for this thread.

lwp_ctxset() will fail if one or more of the following are true:

LE_NOROOM
    Unable to allocate memory to define special context.

SEE ALSO
lwp_newstk(3L)

BUGS

The floating point contexts should be initialized implicitly for those threads that use floating point.