| MAKECONTEXT(3C) | Standard C Library Functions | MAKECONTEXT(3C) |
makecontext,
swapcontext,
swapcontext_extd —
manipulate user contexts
#include
<ucontext.h>
void
makecontext(ucontext_t *ucp,
void (*ifunc)(), int argc,
...);
int
swapcontext(ucontext_t *restrict
oucp, const ucontext_t *restrict ucp);
int
swapcontext_extd(ucontext_t *restrict
oucp, uint32_t flags, const
ucontext_t *restrict ucp);
The
makecontext()
function modifies the context specified by ucp, which
has been initialized using getcontext(2) or
getcontext_extd(2). When this context is resumed using
swapcontext(),
swapcontext_extd(), or
setcontext(2), execution continues by calling the function
func, passing it the arguments that follow
argc in the makecontext()
call. The value of argc must match the number of
pointer-sized integer arguments passed to func,
otherwise the behavior is undefined.
Before a call is made to
makecontext(),
the context being modified should have a stack allocated for it. The stack
is assigned to the context by initializing the
uc_stack member.
The uc_link member is
used to determine the context that will be resumed when the context being
modified by
makecontext()
returns. The uc_link member should be initialized
prior to the call to makecontext(). If the
uc_link member is initialized to
NULL, the thread executing
func will exit when func
returns. See pthread_exit(3C).
The
swapcontext()
function saves the current context in the context structure pointed to by
oucp and sets the context to the context structure
pointed to by ucp.
If the ucp or oucp
argument points to an invalid address, the behavior is undefined and
errno may be set to
EFAULT.
The
swapcontext_extd()
function is similar to swapcontext() except that it
performs a call to getcontext_extd(2) to get and save the
current context, passing the flags argument to
getcontext_extd(2). Note, the same constraints around the
initialization of the ucontext_t that are discussed in
getcontext_extd(2) still apply. Mainly, the context must
either have originally come from ucontext_alloc(3C) or
prior to its first use been zeroed. See getcontext_extd(2)
for more information.
On successful completion, swapcontext()
and swapcontext_extd() return
0. Otherwise,
-1 is returned
and errno is set to indicate the error.
Example
1 Alternate execution context on a stack whose memory was allocated
using mmap().
#include <stdio.h>
#include <ucontext.h>
#include <sys/mman.h>
void
assign(long a, int *b)
{
*b = (int)a;
}
int
main(int argc, char **argv)
{
ucontext_t uc, back;
size_t sz = 0x10000;
int value = 0;
getcontext(&uc);
uc.uc_stack.ss_sp = mmap(0, sz,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
uc.uc_stack.ss_size = sz;
uc.uc_stack.ss_flags = 0;
uc.uc_link = &back;
makecontext(&uc, assign, 2, 100L, &value);
swapcontext(&back, &uc);
printf("done %d\n", value);
return (0);
}
The swapcontext() and
swapcontext_extd() function will fail if:
ENOMEMThe swapcontext() and
swapcontext_extd() functions may fail if:
EFAULTThe swapcontext_extd() function may
additionally fail if:
EINVALThese functions are useful for implementing user-level context switching between multiple threads of control within a process (co-processing). More effective multiple threads of control can be obtained by using native support for multithreading. See threads(7).
getcontext(2), getcontext_extd(2), mmap(2), sigaction(2), sigprocmask(2), pthread_exit(3C), ucontext_alloc(3C), ucontext.h(3HEAD), attributes(7), standards(7), threads(7)
The semantics of the uc_stack member of the
ucontext_t structure have changed as they apply to
inputs to
makecontext().
Prior to Solaris 10, the ss_sp member of the
uc_stack tructure represented the high memory address
of the area reserved for the stack. The ss_sp member
now represents the base (low memory address), in keeping with other uses of
ss_sp. This change in the meaning of
ss_sp is the default behavior.
Binary compatibility has been preserved with
releases prior to Solaris 10. Before recompiling, applications that use
makecontext()
must be updated to reflect this behavior change. The example below
demonstrates a typical change that must be applied:
--- example1_s9.c Thu Oct 3 11:58:17 2002
+++ example1.c Thu Jun 27 13:28:16 2002
@@ -27,12 +27,9 @@
uc.uc_stack.ss_sp = mmap(0, sz,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
- uc.uc_stack.ss_sp = (char *)uc.uc_stack.ss_sp + sz - 8;
uc.uc_stack.ss_size = sz;
uc.uc_stack.ss_flags = 0;
uc.uc_link = &back
makecontext(&uc, assign, 2, 100L, &value);
| March 20, 2023 | illumos |