MAKECONTEXT(3)

NOM
makecontext, swapcontext - Manipulation du contexte utilisateur

SYNOPSIS
#include <ucontext.h>

void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

int swapcontext(ucontext_t *oucp, ucontext_t *ucp);

DESCRIPTION
Dans un environnement de type System V, on dispose du type ucontext_t défini dans <ucontext.h> et des quatre fonctions getcontext(2), setcontext(2), 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(2)). 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(2) 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 préciser le nombre de ces arguments dans argc. Lorsque cette fonction s'achève, le contexte successeur est activé. Lorsque 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.

VALEUR RENVOYÉE
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 renseigne errno en conséquence.

ERREURS

ENOMEM
    Espace de pile disponible insuffisant.

VERSIONS
makecontext() et swapcontext() sont fournies par la glibc depuis la version 2.1.

CONFORMITÉ
SUSv2, POSIX.1-2001.

NOTES
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.

EXEMPLE

Le programme exemple suivant montre l'utilisation de getcontext(2), makecontext() et swapcontext(). L'exécution de ce 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 handle_error(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)
        handle_error("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)
        handle_error("swapcontext");
    printf("func2: returning\n");
}
int
main(int argc, char *argv[])
{
    char func1_stack[16384];
    char func2_stack[16384];
    if (getcontext(&uctx_func1) == -1)
        handle_error("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)
        handle_error("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)
        handle_error("swapcontext");
    printf("main: exiting\n");
    exit(EXIT_SUCCESS);
}

VOIR AUSSI
getcontext(2), sigaction(2), sigaltstack(2), sigprocmask(2), sigsetjmp(3)

TRADUCTION

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 17 juillet 2008.

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.