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 *restrict oucp,
                const ucontext_t *restrict ucp);

DESCRIPTION
In a System V-like environment, one has the type ucontext_t (defined in <ucontext.h> and described in getcontext(3)) and the four functions getcontext(3), setcontext(3), makecontext(), and swapcontext() that allow user-level context switching between multiple threads of control within a process.

La fonction makecontext() modifie le contexte pointé par ucp (qui a été obtenu par un appel à getcontext(3)). Avant d'appeler makecontext(), l'appelant doit allouer une nouvelle pile pour ce contexte et l'affecter à ucp->uc_stack et définir un contexte successeur et l'affecter à ucp->uc_link.

Lorsque ce contexte est activé par la suite (avec setcontext(3) ou swapcontext()), alors la fonction func() est tout d'abord appelée avec la série d'arguments de type 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
When successful, swapcontext() does not return. (But we may return later, in case oucp is activated, in which case it looks like swapcontext() returns 0.) On error, swapcontext() returns -1 and sets errno to indicate the error.

ERREURS

ENOMEM
    Espace de pile disponible insuffisant.

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

ATTRIBUTS
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur
makecontext() | Sécurité des threads | MT-Safe race:ucp
swapcontext() | Sécurité des threads | MT-Safe race:oucp race:ucp

CONFORMITÉ
SUSv2, POSIX.1-2001. POSIX.1-2008 supprime les spécifications de makecontext() et swapcontext() à cause de problèmes de portabilité, et recommande que les applications soient réécrites avec des processus légers POSIX à la place.

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.

Sur les architectures où le type int et les types « pointeur » sont de même taille (par exemple, pour x86-32, leur taille est de 32 bits), vous pouvez passer outre en passant des pointeurs comme paramètres à makecontext() suivi de argc. Cependant, sachez que cela n'est pas forcément portable, et indéfini selon les standards, et ne fonctionnera pas sur les architectures où la taille des pointeurs est supérieure à la taille des entiers int. Néanmoins, avec la version 2.8, la glibc a effectué quelques changements à makecontext(), afin de permettre cela sur certaines architecture 64 bits (par exemple, x86-64).

EXEMPLES
Le programme d'exemple ci-dessous décrit l'utilisation de getcontext(3), makecontext() et swapcontext(). 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

  Source du programme
    #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
sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3), sigsetjmp(3)

COLOPHON
Cette page fait partie de la publication 5.13 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Frédéric Hantrais <fhantrais@gmail.com> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.