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(3),
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, consultez
getcontext(3).
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¶
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.
ATTRIBUTS¶
Multithreading (voir pthreads(7))¶
Les fonctions
makecontext() et
swapcontext() sont sûres
dans un contexte multithread.
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).
EXEMPLE¶
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 3.65 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¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Stéphan Rafin (2002), Alain Portal
<
http://manpagesfr.free.fr/> (2006). Florentin Duneau et
l'équipe francophone de traduction de Debian (2006-2009).
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> ».