1 | #include <errno.h> |
2 | #include <limits.h> |
3 | #include <pthread.h> |
4 | #include <stdio.h> |
5 | #include <stdlib.h> |
6 | #include <string.h> |
7 | #include <unistd.h> |
8 | #include <sys/mman.h> |
9 | #include <sys/resource.h> |
10 | |
11 | static void use_stack (size_t needed); |
12 | |
13 | void (*use_stack_ptr) (size_t) = use_stack; |
14 | |
15 | static void |
16 | use_stack (size_t needed) |
17 | { |
18 | size_t sz = sysconf (_SC_PAGESIZE); |
19 | char *buf = alloca (sz); |
20 | memset (buf, '\0', sz); |
21 | |
22 | if (needed > sz) |
23 | use_stack_ptr (needed - sz); |
24 | } |
25 | |
26 | static void |
27 | use_up_memory (void) |
28 | { |
29 | struct rlimit rl; |
30 | getrlimit (RLIMIT_AS, rlimits: &rl); |
31 | rl.rlim_cur = 10 * 1024 * 1024; |
32 | setrlimit (RLIMIT_AS, rlimits: &rl); |
33 | |
34 | char *c; |
35 | int PAGESIZE = getpagesize (); |
36 | while (1) |
37 | { |
38 | c = mmap (NULL, len: PAGESIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, fd: -1, offset: 0); |
39 | if (c == MAP_FAILED) |
40 | break; |
41 | } |
42 | } |
43 | |
44 | static void * |
45 | child (void *arg) |
46 | { |
47 | sleep (seconds: 1); |
48 | return arg; |
49 | } |
50 | |
51 | static int |
52 | do_test (void) |
53 | { |
54 | int err; |
55 | pthread_t tid; |
56 | |
57 | /* Allocate the memory needed for the stack. */ |
58 | #ifdef PTHREAD_STACK_MIN |
59 | use_stack_ptr (PTHREAD_STACK_MIN); |
60 | #else |
61 | use_stack_ptr (4 * getpagesize ()); |
62 | #endif |
63 | |
64 | use_up_memory (); |
65 | |
66 | err = pthread_create (newthread: &tid, NULL, start_routine: child, NULL); |
67 | if (err != 0) |
68 | { |
69 | printf (format: "pthread_create returns %d: %s\n" , err, |
70 | err == EAGAIN ? "OK" : "FAIL" ); |
71 | return err != EAGAIN; |
72 | } |
73 | |
74 | /* We did not fail to allocate memory despite the preparation. Oh well. */ |
75 | return 0; |
76 | } |
77 | |
78 | #define TEST_FUNCTION do_test () |
79 | #include "../test-skeleton.c" |
80 | |