(root)/
glibc-2.38/
stdlib/
tst-swapcontext1.c
       1  /* Check multiple makecontext calls.
       2     Copyright (C) 2018-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <ucontext.h>
      22  
      23  static ucontext_t uctx_main, uctx_func1, uctx_func2;
      24  const char *str1 = "\e[31mswapcontext(&uctx_func1, &uctx_main)\e[0m";
      25  const char *str2 = "\e[34mswapcontext(&uctx_func2, &uctx_main)\e[0m";
      26  const char *fmt1 = "\e[31m";
      27  const char *fmt2 = "\e[34m";
      28  
      29  #define handle_error(msg) \
      30    do { perror(msg); exit(EXIT_FAILURE); } while (0)
      31  
      32  __attribute__((noinline, noclone))
      33  static void
      34  func4(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
      35  {
      36    printf("      %sfunc4: %s\e[0m\n", fmt, str);
      37    if (swapcontext(uocp, ucp) == -1)
      38      handle_error("swapcontext");
      39    printf("      %sfunc4: returning\e[0m\n", fmt);
      40  }
      41  
      42  __attribute__((noinline, noclone))
      43  static void
      44  func3(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
      45  {
      46    printf("    %sfunc3: func4(uocp, ucp, str)\e[0m\n", fmt);
      47    func4(uocp, ucp, str, fmt);
      48    printf("    %sfunc3: returning\e[0m\n", fmt);
      49  }
      50  
      51  __attribute__((noinline, noclone))
      52  static void
      53  func1(void)
      54  {
      55    while ( 1 )
      56      {
      57        printf("  \e[31mfunc1: func3(&uctx_func1, &uctx_main, str1)\e[0m\n");
      58        func3( &uctx_func1, &uctx_main, str1, fmt1);
      59      }
      60  }
      61  
      62  __attribute__((noinline, noclone))
      63  static void
      64  func2(void)
      65  {
      66    while ( 1 )
      67      {
      68        printf("  \e[34mfunc2: func3(&uctx_func2, &uctx_main, str2)\e[0m\n");
      69        func3(&uctx_func2, &uctx_main, str2, fmt2);
      70      }
      71  }
      72  
      73  static int
      74  do_test (void)
      75  {
      76    char func1_stack[16384];
      77    char func2_stack[16384];
      78    int i;
      79  
      80    if (getcontext(&uctx_func1) == -1)
      81      handle_error("getcontext");
      82    uctx_func1.uc_stack.ss_sp = func1_stack;
      83    uctx_func1.uc_stack.ss_size = sizeof (func1_stack);
      84    uctx_func1.uc_link = &uctx_main;
      85    makecontext(&uctx_func1, func1, 0);
      86  
      87    if (getcontext(&uctx_func2) == -1)
      88      handle_error("getcontext");
      89    uctx_func2.uc_stack.ss_sp = func2_stack;
      90    uctx_func2.uc_stack.ss_size = sizeof (func2_stack);
      91    uctx_func2.uc_link = &uctx_func1;
      92    makecontext(&uctx_func2, func2, 0);
      93  
      94    for ( i = 0; i < 4; i++ )
      95      {
      96        if (swapcontext(&uctx_main, &uctx_func1) == -1)
      97  	handle_error("swapcontext");
      98        printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func2)\n\e[0m");
      99        if (swapcontext(&uctx_main, &uctx_func2) == -1)
     100  	handle_error("swapcontext");
     101        printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func1)\n\e[0m");
     102      }
     103  
     104    printf("main: exiting\n");
     105    exit(EXIT_SUCCESS);
     106  }
     107  
     108  #include <support/test-driver.c>