Loading

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);

       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  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(2) 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

       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  positionne  errno  de  façon
       appropriée.

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.  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 (p. ex., pour x86-32,   leur  taille  est  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
       effectue quelques changements à makecontext(), afin de  permettre  cela
       sur certaines architecture 64 bits (p. ex., x86-64).

EXEMPLE

       Le    programme    d’exemple   ci-dessous   décrit   l’utilisation   de
       getcontext(2), 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

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

COLOPHON

       Cette page fait partie de  la  publication  3.23  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l’adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Cette  page  de  manuel  a  été traduite par Stéphan Rafin <stephan DOT
       rafin AT laposte DOT net> en 2002, puis a été mise  à  jour  par  Alain
       Portal  <aportal  AT  univ-montp2  DOT  fr>  jusqu’en  2006,  et mise à
       disposition sur http://manpagesfr.free.fr/.

       Les mises à jour et corrections de la version présente dans Debian sont
       directement gérées par Florentin Duneau <fduneau@gmail.com> et l’équipe
       francophone de traduction de Debian.

       Veuillez  signaler  toute  erreur   de   traduction   en   écrivant   à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de  ce  document
       en utilisant la commande « man -L C <section> <page_de_man> ».