Patchwork PATCH RFA: Split stack [7/7]: tests

login
register
mail settings
Submitter Ian Taylor
Date Sept. 22, 2010, 10:05 p.m.
Message ID <mcriq1x77sw.fsf@google.com>
Download mbox | patch
Permalink /patch/65468/
State New
Headers show

Comments

Ian Taylor - Sept. 22, 2010, 10:05 p.m.
This is the seventh and last of the -fsplit-stack patches.  This patch
provides four test cases for different aspects of the functionality.

I will commit this patch when the other patches are approved.  Comments
welcome.

Ian


2010-09-21  Ian Lance Taylor  <iant@google.com>

	* lib/target-supports.exp (check_effective_target_split_stack):
	New procedure.
	* gcc.dg/split-1.c: New test.
	* gcc.dg/split-2.c: New test.
	* gcc.dg/split-3.c: New test.
	* gcc.dg/split-4.c: New test.
Richard Guenther - Sept. 23, 2010, 9:49 a.m.
On Thu, Sep 23, 2010 at 12:05 AM, Ian Lance Taylor <iant@google.com> wrote:
> This is the seventh and last of the -fsplit-stack patches.  This patch
> provides four test cases for different aspects of the functionality.
>
> I will commit this patch when the other patches are approved.  Comments
> welcome.

Did you check if we can bootstrap with -fsplit-stack and, say,
ulimit -s 4 (a single page of stack)?  How is the amount of stack
allocated at split points controlled?

Thanks,
Richard.

> Ian
>
>
> 2010-09-21  Ian Lance Taylor  <iant@google.com>
>
>        * lib/target-supports.exp (check_effective_target_split_stack):
>        New procedure.
>        * gcc.dg/split-1.c: New test.
>        * gcc.dg/split-2.c: New test.
>        * gcc.dg/split-3.c: New test.
>        * gcc.dg/split-4.c: New test.
>
>
>

Patch

Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 164490)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -3664,6 +3664,15 @@  proc check_effective_target_lto { } {
     return [info exists ENABLE_LTO]
 }
 
+# Return 1 if this target supports the -fsplit-stack option, 0
+# otherwise.
+
+proc check_effective_target_split_stack {} {
+    return [check_no_compiler_messages split_stack object {
+	void foo (void) { }
+    } "-fsplit-stack"]
+}
+
 # Return 1 if the language for the compiler under test is C.
 
 proc check_effective_target_c { } {
Index: gcc/testsuite/gcc.dg/split-1.c
===================================================================
--- gcc/testsuite/gcc.dg/split-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/split-1.c	(revision 0)
@@ -0,0 +1,49 @@ 
+/* This test needs to use setrlimit to set the stack size, so it can
+   only run on Unix.  */
+/* { dg-do run { target *-*-linux* *-*-solaris* *-*-darwin* } } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack" } */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+   from the stack.  */
+static void use_buffer (char *buf) __attribute__ ((noinline));
+static void
+use_buffer (char *buf)
+{
+  buf[0] = '\0';
+}
+
+/* Each recursive call uses 10,000 bytes.  We call it 1000 times,
+   using a total of 10,000,000 bytes.  If -fsplit-stack is not
+   working, that will overflow our stack limit.  */
+
+static void
+down (int i)
+{
+  char buf[10000];
+
+  if (i > 0)
+    {
+      use_buffer (buf);
+      down (i - 1);
+    }
+}
+
+int
+main (void)
+{
+  struct rlimit r;
+
+  /* We set a stack limit because we are usually invoked via make, and
+     make sets the stack limit to be as large as possible.  */
+  r.rlim_cur = 8192 * 1024;
+  r.rlim_max = 8192 * 1024;
+  if (setrlimit (RLIMIT_STACK, &r) != 0)
+    abort ();
+  down (1000);
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/split-2.c
===================================================================
--- gcc/testsuite/gcc.dg/split-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/split-2.c	(revision 0)
@@ -0,0 +1,55 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-require-effective-target pthread_h } */
+/* { dg-options "-pthread -fsplit-stack" } */
+
+#include <stdlib.h>
+#include <pthread.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+   from the stack.  */
+static void use_buffer (char *buf) __attribute__ ((noinline));
+static void
+use_buffer (char *buf)
+{
+  buf[0] = '\0';
+}
+
+/* Each recursive call uses 10,000 bytes.  We call it 1000 times,
+   using a total of 10,000,000 bytes.  If -fsplit-stack is not
+   working, that will overflow our stack limit.  */
+
+static void
+down (int i)
+{
+  char buf[10000];
+
+  if (i > 0)
+    {
+      use_buffer (buf);
+      down (i - 1);
+    }
+}
+
+static void *
+thread_routine (void *arg __attribute__ ((unused)))
+{
+  down (1000);
+  return NULL;
+}
+
+int
+main (void)
+{
+  int i;
+  pthread_t tid;
+  void *dummy;
+
+  i = pthread_create (&tid, NULL, thread_routine, NULL);
+  if (i != 0)
+    abort ();
+  i = pthread_join (tid, &dummy);
+  if (i != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/split-3.c
===================================================================
--- gcc/testsuite/gcc.dg/split-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/split-3.c	(revision 0)
@@ -0,0 +1,64 @@ 
+/* This test needs to use setrlimit to set the stack size, so it can
+   only run on Unix.  */
+/* { dg-do run { target *-*-linux* *-*-solaris* *-*-darwin* } } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack" } */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+   from the stack.  */
+static void use_buffer (char *buf) __attribute__ ((noinline));
+static void
+use_buffer (char *buf)
+{
+  buf[0] = '\0';
+}
+
+/* Each recursive call uses 10,000 bytes.  We call it 1000 times,
+   using a total of 10,000,000 bytes.  If -fsplit-stack is not
+   working, that will overflow our stack limit.  */
+
+static void
+down (int i, ...)
+{
+  char buf[10000];
+  va_list ap;
+
+  va_start (ap, i);
+  if (va_arg (ap, int) != 1
+      || va_arg (ap, int) != 2
+      || va_arg (ap, int) != 3
+      || va_arg (ap, int) != 4
+      || va_arg (ap, int) != 5
+      || va_arg (ap, int) != 6
+      || va_arg (ap, int) != 7
+      || va_arg (ap, int) != 8
+      || va_arg (ap, int) != 9
+      || va_arg (ap, int) != 10)
+    abort ();
+
+  if (i > 0)
+    {
+      use_buffer (buf);
+      down (i - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    }
+}
+
+int
+main (void)
+{
+  struct rlimit r;
+
+  /* We set a stack limit because we are usually invoked via make, and
+     make sets the stack limit to be as large as possible.  */
+  r.rlim_cur = 8192 * 1024;
+  r.rlim_max = 8192 * 1024;
+  if (setrlimit (RLIMIT_STACK, &r) != 0)
+    abort ();
+  down (1000, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/split-4.c
===================================================================
--- gcc/testsuite/gcc.dg/split-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/split-4.c	(revision 0)
@@ -0,0 +1,68 @@ 
+/* This test needs to use setrlimit to set the stack size, so it can
+   only run on Unix.  */
+/* { dg-do run { target *-*-linux* *-*-solaris* *-*-darwin* } } */
+/* { dg-require-effective-target split_stack } */
+/* { dg-options "-fsplit-stack" } */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+/* Use a noinline function to ensure that the buffer is not removed
+   from the stack.  */
+static void use_buffer (char *buf, size_t) __attribute__ ((noinline));
+static void
+use_buffer (char *buf, size_t c)
+{
+  size_t i;
+
+  for (i = 0; i < c; ++i)
+    buf[i] = (char) i;
+}
+
+/* Each recursive call uses 10 * i bytes.  We call it 1000 times,
+   using a total of 5,000,000 bytes.  If -fsplit-stack is not working,
+   that will overflow our stack limit.  */
+
+static void
+down1 (int i)
+{
+  char buf[10 * i];
+
+  if (i > 0)
+    {
+      use_buffer (buf, 10 * i);
+      down1 (i - 1);
+    }
+}
+
+/* Same thing, using alloca.  */
+
+static void
+down2 (int i)
+{
+  char *buf = alloca (10 * i);
+
+  if (i > 0)
+    {
+      use_buffer (buf, 10 * i);
+      down2 (i - 1);
+    }
+}
+
+int
+main (void)
+{
+  struct rlimit r;
+
+  /* We set a stack limit because we are usually invoked via make, and
+     make sets the stack limit to be as large as possible.  */
+  r.rlim_cur = 8192 * 1024;
+  r.rlim_max = 8192 * 1024;
+  if (setrlimit (RLIMIT_STACK, &r) != 0)
+    abort ();
+  down1 (1000);
+  down2 (1000);
+  return 0;
+}