7
/* Set by the signal handler. */
8
static volatile int expired;
11
static ucontext_t uc[3];
13
/* We do only a certain number of switches. */
17
/* This is the function doing the work. It is just a
18
skeleton, real code has to be filled in. */
25
/* This is where the work would be done. */
32
/* Regularly the @var{expire} variable must be checked. */
35
/* We do not want the program to run forever. */
39
printf ("\nswitching from %d to %d\n", n, 3 - n);
41
/* Switch to the other context, saving the current one. */
42
swapcontext (&uc[n], &uc[3 - n]);
47
/* This is the signal handler which simply set the variable. */
63
/* Initialize the data structures for the interval timer. */
64
sa.sa_flags = SA_RESTART;
65
sigfillset (&sa.sa_mask);
66
sa.sa_handler = handler;
67
it.it_interval.tv_sec = 0;
68
it.it_interval.tv_usec = 1;
69
it.it_value = it.it_interval;
71
/* Install the timer and get the context we can manipulate. */
72
if (sigaction (SIGPROF, &sa, NULL) < 0
73
|| setitimer (ITIMER_PROF, &it, NULL) < 0
74
|| getcontext (&uc[1]) == -1
75
|| getcontext (&uc[2]) == -1)
78
/* Create a context with a separate stack which causes the
79
function @code{f} to be call with the parameter @code{1}.
80
Note that the @code{uc_link} points to the main context
81
which will cause the program to terminate once the function
83
uc[1].uc_link = &uc[0];
84
uc[1].uc_stack.ss_sp = st1;
85
uc[1].uc_stack.ss_size = sizeof st1;
86
makecontext (&uc[1], (void (*) (void)) f, 1, 1);
88
/* Similarly, but @code{2} is passed as the parameter to @code{f}. */
89
uc[2].uc_link = &uc[0];
90
uc[2].uc_stack.ss_sp = st2;
91
uc[2].uc_stack.ss_size = sizeof st2;
92
makecontext (&uc[2], (void (*) (void)) f, 1, 2);
95
swapcontext (&uc[0], &uc[1]);