Each KSE has a unique mailbox for user-kernel communication defined in
.In sys/kse.h . Some of the fields there are:
km_version describes the version of this structure and must be equal to KSE_VER_0. km_udata is an opaque pointer ignored by the kernel.
km_func points to the KSEs upcall function; it will be invoked using km_stack, which must remain valid for the lifetime of the KSE.
km_curthread always points to the thread that is currently assigned to this KSE if any, or NULL otherwise. This field is modified by both the kernel and the user process as follows.
When km_curthread is not NULL, it is assumed to be pointing at the mailbox for the currently executing thread, and the KSE may be unassigned, e.g., if the thread blocks in the kernel. The kernel will then save the contents of km_curthread with the blocked thread, set km_curthread to NULL, and upcall to invoke km_func.
When km_curthread is NULL, the kernel will never perform any upcalls with this KSE; in other words, the KSE remains assigned to the thread even if it blocks. km_curthread must be NULL while the KSE is executing critical user thread scheduler code that would be disrupted by an intervening upcall; in particular, while km_func itself is executing.
Before invoking km_func in any upcall, the kernel always sets km_curthread to NULL. Once the user thread scheduler has chosen a new thread to run, it should point km_curthread at the threads mailbox, re-enabling upcalls, and then resume the thread. Note: modification of km_curthread by the user thread scheduler must be atomic with the loading of the context of the new thread, to avoid the situation where the thread context area may be modified by a blocking async operation, while there is still valid information to be read out of it.
km_completed points to a linked list of user threads that have completed their work in the kernel since the last upcall. The user thread scheduler should put these threads back into its own runnable queue. Each thread in a KSE group that completes a kernel operation (synchronous or asynchronous) that results in an upcall is guaranteed to be linked into exactly one KSEs km_completed list; which KSE in the group, however, is indeterminate. Furthermore, the completion will be reported in only one upcall.
km_sigscaught contains the list of signals caught by this process since the previous upcall to any KSE in the process. As long as there exists one or more KSEs with an associated mailbox in the user process, signals are delivered this way rather than the traditional way. (This has not been implemented and may change.)
km_timeofday is set by the kernel to the current system time before performing each upcall.
km_flags may contain any of the following bits ORed together: