swapcontext() — Save and restore user context
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
XPG4.2 |
both | POSIX(ON) |
Format
#define _XOPEN_SOURCE_EXTENDED 1
#include <ucontext.h>
int swapcontext(ucontext_t *__restrict__ oucp, const ucontext_t *__restrict__ ucp);
General description
The swapcontext() function saves the current user context in the context structure pointed to by oucp and restores the user context structure pointed to by ucp. swapcontext() is equivalent to getcontext() with the oucp argument followed by setcontext() with the ucp argument.
Control does not return from the initial invocation of swapcontext(). However, if the saved context is not modified using makecontext(), and a subsequent setcontext() or swapcontext() is issued using the saved context, swapcontext() returns with a 0 return value.
- If the ucontext pointed to by ucp that is input to swapcontext(), has not been modified by makecontext(), you must ensure that the function that saved that context by calling either getcontext() or swapcontext() does not return before you call swapcontext() to restore that context. Calling swapcontext() after the function that saved the context returns causes unpredictable program behavior.
- If swapcontext() is used to jump back into an XPLINK routine, any alloca() requests issued by the XPLINK routine after the earlier getcontext() was called and before swapcontext() is called are backed out. All storage obtained by these alloca() requests is freed before the XPLINK routine is resumed.
- If swapcontext() is used to jump back into a non-XPLINK routine, alloca() requests made after getcontext() and before swapcontext() are not backed out.
- Do not issue swapcontext() from any type of condition handling routine (for eample, a signal catcher, a Language Environment® user condition handler or an exception handler).
- If ucp is pointing to a user context of a different execution stack from the current, the user context should be either a freshly modified one (by makecontext()) or the most recently saved one (by getcontext() or swapcontext()) when running on its stack.
- If ucp is pointing to a user context of a different execution stack from the current, the current stack is never collapsed and any resource associated with it is never freed after swapcontext() being called.
This function is supported only in a POSIX program.
mcontext_t uc_mcontext A machine-specific representation
of the saved context.
ucontext_t *uc_link Pointer to the context that will
be resumed when this context returns.
sigset_t uc_sigmask The set of signals that are blocked
when this context is active.
stack_t uc_stack The stack used by this context.
Special behavior for C++: If getcontext() and swapcontext() are used to transfer control in a z/OS® XL C++ program, the behavior in terms of the destruction of automatic objects is undefined. This applies to both z/OS XL C++ and z/OS XL C++ ILC modules. The use of getcontext() and swapcontext() in conjunction with try(), catch(), and throw() is also undefined.
Do not issue getcontext() in a C++ constructor or destructor, since the saved context would not be usable in a subsequent setcontext() or swapcontext() after the constructor or destructor returns.
- All XPLINK programs compiled with the V2R10 or later C compilers that are to run with Language Environment V2R10 or later libraries and use the jmp_buf, sigjmp_buf or ucontext_t types must not be compiled with C headers from Language Environment V2R9 or earlier.
- Non-XPLINK functions compiled with any level of Language Environment headers must not define jmp_buf, sigjmp_buf or ucontext_t data items and pass them to XPLINK functions that call getcontext(), longjmp(), _longjmp(), setjmp(), _setjmp(), setcontext(), sigsetjmp(), or swapcontext() with these passed-in data items.
- When __XPLINK__ is defined, the Language Environment V2R10 and later headers define a larger jmp_buf, sigjmp_buf or ucontext_t area that is required by setjmp(), getcontext(), and related functions when they are called from an XPLINK routine. If __XPLINK__ is not defined, the Language Environment V2R10 and later headers define a shorter jmp_buf, sigjmp_buf or ucontext_t area. The Language Environment headers before V2R10 also define the shorter version of these data areas. If an XPLINK function calls setjmp(), getcontext() or similar functions with a short jmp_buf, sigjmp_buf or ucontext_t area, a storage overlay or program check may occur when the C library tries to store past the end of the passed-in (too short) data area.
Returned value
If successful, swapcontext() does not return from the initial invocation. If the unmodified saved context is later restored, swapcontext() returns 0.
If unsuccessful, swapcontext() returns -1.
There are no errno values defined.
Example
/* This example shows the usage of swapcontext(). */
#define _XOPEN_SOURCE_EXTENDED 1
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
#include <errno.h>
#ifdef _LP64
#define STACK_SIZE 2097152+16384 /* large enough value for AMODE 64 */
#else
#define STACK_SIZE 16384 /* AMODE 31 addressing*/
#endif
void func(int);
ucontext_t fcontext,mcontext;
int x = 0;
int main(void) {
int value = 1;
getcontext(&fcontext);
if ((fcontext.uc_stack.ss_sp = (char *) malloc(STACK_SIZE)) != NULL) {
fcontext.uc_stack.ss_size = STACK_SIZE;
fcontext.uc_stack.ss_flags = 0;
errno = 0;
makecontext(&fcontext,func,1,value);
if (errno != 0){
perror("Error reported by makecontext()");
return -1; /* Error occurred exit */
}
}
else {
perror("not enough storage for stack");
abort();
}
printf("context has been built\n");
swapcontext(&mcontext,&fcontext);
if (!x) {
perror("incorrect return from swapcontext");
abort();
}
else {
printf("returned from function\n");
}
}
void func(int arg) {
printf("function called with value %d\n",arg);
x++;
printf("function returning to main\n");
setcontext(&mcontext);
}
context has been built
function called with value 1
function returning to main
returned from function
Related information
- ucontext.h
- getcontext() — Get user context
- longjmp() — Restore stack environment
- _longjmp() — Nonlocal goto
- makecontext() — Modify user context
- setcontext() — Restore user context
- setjmp() — Preserve stack environment
- _setjmp() — Set jump point for a nonlocal goto
- siglongjmp() — Restore the stack environment and signal mask
- sigsetjmp() — Save stack environment and signal mask