about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog8
-rw-r--r--nptl/Makefile1
-rw-r--r--nptl/allocatestack.c7
-rw-r--r--nptl/tst-basic7.c56
4 files changed, 71 insertions, 1 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index c92e6abf45..bc4d43ce5b 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-07  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5245]
+	* allocatestack.c (allocate_stack): Change ENOMEM error in case
+	mmap failed to EAGAIN.
+	* Makefile (tests): Add tst-basic7.
+	* tst-basic7.c: New file.
+
 2007-11-05  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/register-atfork.c (__register_atfork):
diff --git a/nptl/Makefile b/nptl/Makefile
index f239846fb7..00cf40d695 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -222,6 +222,7 @@ tests = tst-typesizes \
 	tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
 	tst-align tst-align2 tst-align3 \
 	tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
+	tst-basic7 \
 	tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
 	tst-raise1 \
 	tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index c894e96a28..f75599c668 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -462,7 +462,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	      mem = ARCH_RETRY_MMAP (size);
 	      if (__builtin_expect (mem == MAP_FAILED, 0))
 #endif
-		return errno;
+		{
+		  if (errno == ENOMEM)
+		    errno = EAGAIN;
+
+		  return errno;
+		}
 	    }
 
 	  /* SIZE is guaranteed to be greater than zero.
diff --git a/nptl/tst-basic7.c b/nptl/tst-basic7.c
new file mode 100644
index 0000000000..da461e43df
--- /dev/null
+++ b/nptl/tst-basic7.c
@@ -0,0 +1,56 @@
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+
+static void
+use_up_memory (void)
+{
+  struct rlimit rl;
+  getrlimit (RLIMIT_AS, &rl);
+  rl.rlim_cur = 10 * 1024 * 1024;
+  setrlimit (RLIMIT_AS, &rl);
+
+  char *c;
+  int PAGESIZE = getpagesize ();
+  while (1)
+    {
+      c = mmap (NULL, PAGESIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
+      if (c == MAP_FAILED)
+	break;
+    }
+}
+
+static void *
+child (void *arg)
+{
+  sleep (1);
+  return arg;
+}
+
+static int
+do_test (void)
+{
+  int err;
+  pthread_t tid;
+
+  use_up_memory ();
+
+  err = pthread_create (&tid, NULL, child, NULL);
+  if (err != 0)
+    {
+      printf ("pthread_create returns %d: %s\n", err,
+	      err == EAGAIN ? "OK" : "FAIL");
+      return err != EAGAIN;
+    }
+
+  /* We did not fail to allocate memory despite the preparation.  Oh well.  */
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"