Linux |
CentOS 5.3 |
|
swapcontext(3) |
makecontext, swapcontext − Manipulation du contexte utilisateur. |
#include <ucontext.h> void makecontext(ucontext_t *ucp, void
*func(), int argc, ...); |
Dans un environnement de type Système V, on dispose du type ucontext_t défini dans <ucontext.h> et des quatre fonctions getcontext(), setcontext(), makecontext() et swapcontext() qui permettent, au niveau utilisateur, des permutations de contextes entre plusieurs threads de contrôle au sein d’un processus. Pour le type et les deux premières fonctions, voir getcontext(2). La fonction makecontext() modifie le contexte pointé par ucp (qui a été obtenu par un appel à getcontext()). Avant d’appeler makecontext(), l’appelant doit allouer une nouvelle pile pour ce contexte, affecter son adresse à ucp->uc_stack, et définir un contexte successeur et affecter son adresse à ucp->uc_link. Lorsque ce contexte est activé par la suite (en utilisant setcontext() ou swapcontext()), la fonction func() est tout d’abord appelée avec les arguments de type entier (int) spécifiés à la suite de argc ; l’appelant doit spécifier le nombre de ces arguments dans argc . Lorsque cette fonction s’achève, le contexte successeur est activé. Quand le pointeur sur le contexte successeur vaut NULL, le thread se termine. La fonction swapcontext() sauvegarde le contexte actuel dans la structure pointée par oucp et active ensuite le contexte pointé par ucp. |
En cas de succès, swapcontext() ne rend pas la main à l’appelant. (On peut toutefois revenir à l’appelant en cas d’activation de oucp. Dans un tel cas, swapcontext() se comporte comme si elle renvoyait 0.) En cas d’erreur, swapcontext() renvoie −1 et remplit errno de façon appropriée. |
ENOMEM |
Espace de pile disponible insuffisant. |
L’interprétation de ucp->uc_stack est exactement la même que pour sigaltstack(2), à savoir, cette structure contient l’adresse de départ et la longueur d’une zone mémoire destinée à être utilisée comme pile, et ce, sans considération sur le sens d’expansion de la pile. Il n’est donc pas nécessaire pour le programme utilisateur de se soucier de ce sens. |
SUSv2, POSIX.1-2001. |
le programme exemple suivant montre l’utilisation de getcontext(), makecontext() et swapcontext(). Le lancement du programme produit la sortie suivante : |
$ ./a.out main: swapcontext(&uctx_main, &uctx_func2) func2: started func2: swapcontext(&uctx_func2, &uctx_func1) func1: started func1: swapcontext(&uctx_func1, &uctx_func2) func2: returning func1: returning main: exiting |
#include <ucontext.h> #include <stdio.h> #include <stdlib.h> static ucontext_t uctx_main, uctx_func1, uctx_func2; #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) static void func1(void) { printf("func1: started\n"); printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n"); if (swapcontext(&uctx_func1, &uctx_func2) == -1) die("swapcontext"); printf("func1: returning\n"); } static void func2(void) { printf("func2: started\n"); printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n"); if (swapcontext(&uctx_func2, &uctx_func1) == -1) die("swapcontext"); printf("func2: returning\n"); } int main(int argc, char *argv[]) { char func1_stack[16384]; char func2_stack[16384]; if (getcontext(&uctx_func1) == -1) die("getcontext"); uctx_func1.uc_stack.ss_sp = func1_stack; uctx_func1.uc_stack.ss_size = sizeof(func1_stack); uctx_func1.uc_link = &uctx_main; makecontext(&uctx_func1, func1, 0); if (getcontext(&uctx_func2) == -1) die("getcontext"); uctx_func2.uc_stack.ss_sp = func2_stack; uctx_func2.uc_stack.ss_size = sizeof(func2_stack); /* Successor context is f1(), unless argc > 1 */ uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1; makecontext(&uctx_func2, func2, 0); printf("main: swapcontext(&uctx_main, &uctx_func2)\n"); if (swapcontext(&uctx_main, &uctx_func2) == -1) die("swapcontext"); printf("main: exiting\n"); exit(EXIT_SUCCESS); } |
getcontext(2), sigaction(2), sigaltstack(2), sigprocmask(2), sigsetjmp(3) |
Ce document est une traduction réalisée par Stéphan Rafin <stephan DOT rafin AT laposte DOT net> le 14 mai 2002 et révisée le 14 août 2006. L’équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 3 makecontext ». N’hésitez pas à signaler à l’auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel. |
swapcontext(3) |