/* Test floating-point environment is thread-local.
   Copyright (C) 2013-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <fenv.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>

#define TEST_ONE_RM(RM)						\
  do								\
    {								\
      if (fesetround (RM) == 0)					\
	{							\
	  rm = fegetround ();					\
	  if (rm != RM)						\
	    {							\
	      printf ("expected " #RM ", got %d\n", rm);	\
	      ret = 1;						\
	    }							\
	}							\
    }								\
  while (0)

static void *
test_round (void *arg)
{
  intptr_t ret = 0;
  for (int i = 0; i < 10000; i++)
    {
      int rm;
#ifdef FE_DOWNWARD
      TEST_ONE_RM (FE_DOWNWARD);
#endif
#ifdef FE_TONEAREST
      TEST_ONE_RM (FE_TONEAREST);
#endif
#ifdef FE_TOWARDZERO
      TEST_ONE_RM (FE_TOWARDZERO);
#endif
#ifdef FE_UPWARD
      TEST_ONE_RM (FE_UPWARD);
#endif
    }
  return (void *) ret;
}

#define TEST_ONE_RAISE(EX)				\
  do							\
    {							\
      if (feraiseexcept (EX) == 0)			\
	if (fetestexcept (EX) != EX)			\
	  {						\
	    printf (#EX " not raised\n");		\
	    ret = 1;					\
	  }						\
      if (feclearexcept (FE_ALL_EXCEPT) == 0)		\
	if (fetestexcept (FE_ALL_EXCEPT) != 0)		\
	  {						\
	    printf ("exceptions not all cleared\n");	\
	    ret = 1;					\
	  }						\
    }							\
  while (0)

static void *
test_raise (void *arg)
{
  intptr_t ret = 0;
  for (int i = 0; i < 10000; i++)
    {
#ifdef FE_DIVBYZERO
      TEST_ONE_RAISE (FE_DIVBYZERO);
#endif
#ifdef FE_INEXACT
      TEST_ONE_RAISE (FE_INEXACT);
#endif
#ifdef FE_INVALID
      TEST_ONE_RAISE (FE_INVALID);
#endif
#ifdef FE_OVERFLOW
      TEST_ONE_RAISE (FE_OVERFLOW);
#endif
#ifdef UNDERFLOW
      TEST_ONE_RAISE (FE_UNDERFLOW);
#endif
    }
  return (void *) ret;
}

#define TEST_ONE_ENABLE(EX)				\
  do							\
    {							\
      if (feenableexcept (EX) != -1)			\
	if (fegetexcept () != EX)			\
	  {						\
	    printf (#EX " not enabled\n");		\
	    ret = 1;					\
	  }						\
      if (fedisableexcept (EX) != -1)			\
	if (fegetexcept () != 0)			\
	  {						\
	    printf ("exceptions not all disabled\n");	\
	    ret = 1;					\
	  }						\
    }							\
  while (0)

static void *
test_enable (void *arg)
{
  intptr_t ret = 0;
  for (int i = 0; i < 10000; i++)
    {
#ifdef FE_DIVBYZERO
      TEST_ONE_ENABLE (FE_DIVBYZERO);
#endif
#ifdef FE_INEXACT
      TEST_ONE_ENABLE (FE_INEXACT);
#endif
#ifdef FE_INVALID
      TEST_ONE_ENABLE (FE_INVALID);
#endif
#ifdef FE_OVERFLOW
      TEST_ONE_ENABLE (FE_OVERFLOW);
#endif
#ifdef UNDERFLOW
      TEST_ONE_ENABLE (FE_UNDERFLOW);
#endif
    }
  return (void *) ret;
}

static int
do_test (void)
{
  int ret = 0;
  void *vret;
  pthread_t thread_id;
  int pret;

  pret = pthread_create (&thread_id, NULL, test_round, NULL);
  if (pret != 0)
    {
      printf ("pthread_create failed: %d\n", pret);
      return 1;
    }
  vret = test_round (NULL);
  ret |= (intptr_t) vret;
  pret = pthread_join (thread_id, &vret);
  if (pret != 0)
    {
      printf ("pthread_join failed: %d\n", pret);
      return 1;
    }
  ret |= (intptr_t) vret;

  pret = pthread_create (&thread_id, NULL, test_raise, NULL);
  if (pret != 0)
    {
      printf ("pthread_create failed: %d\n", pret);
      return 1;
    }
  vret = test_raise (NULL);
  ret |= (intptr_t) vret;
  pret = pthread_join (thread_id, &vret);
  if (pret != 0)
    {
      printf ("pthread_join failed: %d\n", pret);
      return 1;
    }
  ret |= (intptr_t) vret;

  pret = pthread_create (&thread_id, NULL, test_enable, NULL);
  if (pret != 0)
    {
      printf ("pthread_create failed: %d\n", pret);
      return 1;
    }
  vret = test_enable (NULL);
  ret |= (intptr_t) vret;
  pret = pthread_join (thread_id, &vret);
  if (pret != 0)
    {
      printf ("pthread_join failed: %d\n", pret);
      return 1;
    }
  ret |= (intptr_t) vret;

  return ret;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
