Blame stdlib/tst-makecontext3.c

Packit Service 82fcde
/* Copyright (C) 2001-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <ucontext.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
Packit Service 82fcde
static ucontext_t ctx[3];
Packit Service 82fcde
Packit Service 82fcde
static int was_in_f1;
Packit Service 82fcde
static int was_in_f2;
Packit Service 82fcde
Packit Service 82fcde
static char st2[32768];
Packit Service 82fcde
Packit Service 82fcde
static volatile int flag;
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
f1 (int a00, int a01, int a02, int a03, int a04, int a05, int a06, int a07,
Packit Service 82fcde
    int a08, int a09, int a10, int a11, int a12, int a13, int a14, int a15,
Packit Service 82fcde
    int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23,
Packit Service 82fcde
    int a24, int a25, int a26, int a27, int a28, int a29, int a30, int a31,
Packit Service 82fcde
    int a32)
Packit Service 82fcde
{
Packit Service 82fcde
  printf ("start f1(a00=%08x,a01=%08x,a02=%08x,a03=%08x,\n"
Packit Service 82fcde
	  "         a04=%08x,a05=%08x,a06=%08x,a07=%08x,\n"
Packit Service 82fcde
	  "         a08=%08x,a09=%08x,a10=%08x,a11=%08x,\n"
Packit Service 82fcde
	  "         a12=%08x,a13=%08x,a14=%08x,a15=%08x,\n"
Packit Service 82fcde
	  "         a16=%08x,a17=%08x,a18=%08x,a19=%08x,\n"
Packit Service 82fcde
	  "         a20=%08x,a21=%08x,a22=%08x,a23=%08x,\n"
Packit Service 82fcde
	  "         a24=%08x,a25=%08x,a26=%08x,a27=%08x,\n"
Packit Service 82fcde
	  "         a28=%08x,a29=%08x,a30=%08x,a31=%08x,\n"
Packit Service 82fcde
	  "         a32=%08x) [%d]\n",
Packit Service 82fcde
	  a00, a01, a02, a03, a04, a05, a06, a07,
Packit Service 82fcde
	  a08, a09, a10, a11, a12, a13, a14, a15,
Packit Service 82fcde
	  a16, a17, a18, a19, a20, a21, a22, a23,
Packit Service 82fcde
	  a24, a25, a26, a27, a28, a29, a30, a31,
Packit Service 82fcde
	  a32, flag);
Packit Service 82fcde
Packit Service 82fcde
  if (a00 != (0x00000001 << flag) || a01 != (0x00000004 << flag)
Packit Service 82fcde
      || a02 != (0x00000012 << flag) || a03 != (0x00000048 << flag)
Packit Service 82fcde
      || a04 != (0x00000123 << flag) || a05 != (0x0000048d << flag)
Packit Service 82fcde
      || a06 != (0x00001234 << flag) || a07 != (0x000048d1 << flag)
Packit Service 82fcde
      || a08 != (0x00012345 << flag) || a09 != (0x00048d15 << flag)
Packit Service 82fcde
      || a10 != (0x00123456 << flag) || a11 != (0x0048d159 << flag)
Packit Service 82fcde
      || a12 != (0x01234567 << flag) || a13 != (0x048d159e << flag)
Packit Service 82fcde
      || a14 != (0x12345678 << flag) || a15 != (0x48d159e2 << flag)
Packit Service 82fcde
      || a16 != (0x23456789 << flag) || a17 != (0x8d159e26 << flag)
Packit Service 82fcde
      || a18 != (0x3456789a << flag) || a19 != (0xd159e26a << flag)
Packit Service 82fcde
      || a20 != (0x456789ab << flag) || a21 != (0x159e26af << flag)
Packit Service 82fcde
      || a22 != (0x56789abc << flag) || a23 != (0x59e26af3 << flag)
Packit Service 82fcde
      || a24 != (0x6789abcd << flag) || a25 != (0x9e26af37 << flag)
Packit Service 82fcde
      || a26 != (0x789abcde << flag) || a27 != (0xe26af37b << flag)
Packit Service 82fcde
      || a28 != (0x89abcdef << flag) || a29 != (0x26af37bc << flag)
Packit Service 82fcde
      || a30 != (0x9abcdef0 << flag) || a31 != (0x6af37bc3 << flag)
Packit Service 82fcde
      || a32 != (0xabcdef0f << flag))
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("arg mismatch");
Packit Service 82fcde
      exit (-1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (flag && swapcontext (&ctx[1], &ctx[2]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: swapcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  printf ("finish f1 [%d]\n", flag);
Packit Service 82fcde
  flag++;
Packit Service 82fcde
  was_in_f1++;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
f2 (void)
Packit Service 82fcde
{
Packit Service 82fcde
  puts ("start f2");
Packit Service 82fcde
  if (swapcontext (&ctx[2], &ctx[1]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: swapcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  puts ("finish f2");
Packit Service 82fcde
  was_in_f2 = 1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
volatile int global;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static int back_in_main;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
check_called (void)
Packit Service 82fcde
{
Packit Service 82fcde
  if (back_in_main == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("program did not reach main again");
Packit Service 82fcde
      _exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
main (void)
Packit Service 82fcde
{
Packit Service 82fcde
  atexit (check_called);
Packit Service 82fcde
Packit Service 82fcde
  char st1[32768];
Packit Service 82fcde
Packit Service 82fcde
  puts ("making contexts");
Packit Service 82fcde
  if (getcontext (&ctx[0]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (errno == ENOSYS)
Packit Service 82fcde
	{
Packit Service 82fcde
	  back_in_main = 1;
Packit Service 82fcde
	  exit (0);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      printf ("%s: getcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (getcontext (&ctx[1]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: getcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  ctx[1].uc_stack.ss_sp = st1;
Packit Service 82fcde
  ctx[1].uc_stack.ss_size = sizeof st1;
Packit Service 82fcde
  ctx[1].uc_link = &ctx[0];
Packit Service 82fcde
  errno = 0;
Packit Service 82fcde
  makecontext (&ctx[1], (void (*) (void)) f1, 33,
Packit Service 82fcde
	       0x00000001 << flag, 0x00000004 << flag,
Packit Service 82fcde
	       0x00000012 << flag, 0x00000048 << flag,
Packit Service 82fcde
	       0x00000123 << flag, 0x0000048d << flag,
Packit Service 82fcde
	       0x00001234 << flag, 0x000048d1 << flag,
Packit Service 82fcde
	       0x00012345 << flag, 0x00048d15 << flag,
Packit Service 82fcde
	       0x00123456 << flag, 0x0048d159 << flag,
Packit Service 82fcde
	       0x01234567 << flag, 0x048d159e << flag,
Packit Service 82fcde
	       0x12345678 << flag, 0x48d159e2 << flag,
Packit Service 82fcde
	       0x23456789 << flag, 0x8d159e26 << flag,
Packit Service 82fcde
	       0x3456789a << flag, 0xd159e26a << flag,
Packit Service 82fcde
	       0x456789ab << flag, 0x159e26af << flag,
Packit Service 82fcde
	       0x56789abc << flag, 0x59e26af3 << flag,
Packit Service 82fcde
	       0x6789abcd << flag, 0x9e26af37 << flag,
Packit Service 82fcde
	       0x789abcde << flag, 0xe26af37b << flag,
Packit Service 82fcde
	       0x89abcdef << flag, 0x26af37bc << flag,
Packit Service 82fcde
	       0x9abcdef0 << flag, 0x6af37bc3 << flag,
Packit Service 82fcde
	       0xabcdef0f << flag);
Packit Service 82fcde
Packit Service 82fcde
  /* Without this check, a stub makecontext can make us spin forever.  */
Packit Service 82fcde
  if (errno == ENOSYS)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("makecontext not implemented");
Packit Service 82fcde
      back_in_main = 1;
Packit Service 82fcde
      return 0;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Play some tricks with this context.  */
Packit Service 82fcde
  if (++global == 1)
Packit Service 82fcde
    if (setcontext (&ctx[1]) != 0)
Packit Service 82fcde
      {
Packit Service 82fcde
	printf ("%s: setcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
	exit (1);
Packit Service 82fcde
      }
Packit Service 82fcde
  if (global != 2)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: 'global' not incremented twice\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (getcontext (&ctx[2]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: second getcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  ctx[2].uc_stack.ss_sp = st2;
Packit Service 82fcde
  ctx[2].uc_stack.ss_size = sizeof st2;
Packit Service 82fcde
  ctx[2].uc_link = &ctx[1];
Packit Service 82fcde
  makecontext (&ctx[2], f2, 0);
Packit Service 82fcde
Packit Service 82fcde
  puts ("swapping contexts");
Packit Service 82fcde
  if (swapcontext (&ctx[0], &ctx[2]) != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("%s: swapcontext: %m\n", __FUNCTION__);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  puts ("back at main program");
Packit Service 82fcde
  back_in_main = 1;
Packit Service 82fcde
Packit Service 82fcde
  if (was_in_f1 < 2)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("didn't reach f1 twice");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  if (was_in_f2 == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      puts ("didn't reach f2");
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  puts ("test succeeded");
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}