Skip to content

glibc/hard-float: math/test-fenv-tls sporadic failure #54

Closed
@vineetgarc

Description

@vineetgarc

When testing arc64 glibc hf support (on nSIM/FPGA) I observed sporadic failure of math/test-fenv-tls

cat build/glibc-arc64/build/math/test-fenv-tls.out
FE_INVALID not raised
exceptions not all cleared
FE_INEXACT not raised

It seems the issue was always FP exceptions related (test also checks rounding modes etc which works fine). So created a simple test.

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

static void * test_raise (void *arg)
{
  intptr_t ret = 0;
  char *p = arg;

  for (int i = 0; i < 10000; i++)
    {
      TEST_ONE_RAISE (FE_INEXACT);
    }
  return (void *) ret;
}

int main(void)
{
   int ret = 0;
   void *vret;
   vret = test_raise("direct");
   ret |= (intptr_t) vret;
   return ret;
}

This test would always passes.

Next as in original test, adding a thread doing this (in addition to main thread) and was able to hit the problem.

int main(void)
{
   int ret = 0;
   void *vret;
+ int pret;
+ pthread_t thread_id;
+ pret = pthread_create (&thread_id, NULL, test_raise, "pthread");
   vret = test_raise("direct");
   ret |= (intptr_t) vret;
+ pret = pthread_join (thread_id, &vret);
   return ret;
}

The issue turned out to be FPU_STATUS register which is poked by feraiseexcept / feclearexcept / fetestexcept was not retaining the right value across Linux task switch. This is despite CONFIG_ARC_FPU_SAVE_RESTORE=y in kernel.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions