2 nptl/allocatestack.c | 24 ++++++++++++++++--------
3 nptl/pthread_attr_getstack.c | 6 +++++-
4 nptl/pthread_attr_setstack.c | 10 +++++++++-
5 nptl/pthread_create.c | 14 ++++++++++----
6 nptl/pthread_getattr_np.c | 15 ++++++++++++++-
7 5 files changed, 54 insertions(+), 15 deletions(-)
9 --- a/nptl/allocatestack.c
10 +++ b/nptl/allocatestack.c
12 if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0))
15 +#if _STACK_GROWS_DOWN
16 + char * stackaddr = (char *) attr->stackaddr;
18 + /* Assume the same layout as the _STACK_GROWS_DOWN case,
19 + with struct pthread at the top of the stack block.
20 + Later we adjust the guard location and stack address
21 + to match the _STACK_GROWS_UP case. */
22 + char * stackaddr = (char *) attr->stackaddr + attr->stacksize;
25 /* If the user also specified the size of the stack make sure it
29 /* Adjust stack size for alignment of the TLS block. */
31 - adj = ((uintptr_t) attr->stackaddr - TLS_TCB_SIZE)
32 + adj = ((uintptr_t) stackaddr - TLS_TCB_SIZE)
33 & __static_tls_align_m1;
34 assert (size > adj + TLS_TCB_SIZE);
36 - adj = ((uintptr_t) attr->stackaddr - __static_tls_size)
37 + adj = ((uintptr_t) stackaddr - __static_tls_size)
38 & __static_tls_align_m1;
42 the stack. It is the user's responsibility to do this if it
45 - pd = (struct pthread *) ((uintptr_t) attr->stackaddr
46 + pd = (struct pthread *) ((uintptr_t) stackaddr
47 - TLS_TCB_SIZE - adj);
49 - pd = (struct pthread *) (((uintptr_t) attr->stackaddr
50 + pd = (struct pthread *) (((uintptr_t) stackaddr
51 - __static_tls_size - adj)
55 pd->specific[0] = pd->specific_1stblock;
57 /* Remember the stack-related values. */
58 - pd->stackblock = (char *) attr->stackaddr - size;
59 + pd->stackblock = (char *) stackaddr - size;
60 pd->stackblock_size = size;
62 /* This is a user-provided stack. It will not be queued in the
64 char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
65 #elif _STACK_GROWS_DOWN
67 -# elif _STACK_GROWS_UP
68 +#elif _STACK_GROWS_UP
69 char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1);
71 if (mprotect (guard, guardsize, PROT_NONE) != 0)
75 *stack = pd->stackblock;
76 - assert (*stack > 0);
80 --- a/nptl/pthread_attr_getstack.c
81 +++ b/nptl/pthread_attr_getstack.c
83 -/* Copyright (C) 2002 Free Software Foundation, Inc.
84 +/* Copyright (C) 2002, 2010 Free Software Foundation, Inc.
85 This file is part of the GNU C Library.
86 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
89 iattr = (struct pthread_attr *) attr;
91 /* Store the result. */
92 +#ifdef _STACK_GROWS_DOWN
93 *stackaddr = (char *) iattr->stackaddr - iattr->stacksize;
95 + *stackaddr = (char *) iattr->stackaddr;
97 *stacksize = iattr->stacksize;
100 --- a/nptl/pthread_attr_setstack.c
101 +++ b/nptl/pthread_attr_setstack.c
103 -/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
104 +/* Copyright (C) 2002, 2003, 2006, 2010 Free Software Foundation, Inc.
105 This file is part of the GNU C Library.
106 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
111 iattr->stacksize = stacksize;
112 +#if _STACK_GROWS_DOWN
113 iattr->stackaddr = (char *) stackaddr + stacksize;
115 + iattr->stackaddr = (char *) stackaddr;
117 iattr->flags |= ATTR_FLAG_STACKADDR;
123 iattr->stacksize = stacksize;
124 +#if _STACK_GROWS_DOWN
125 iattr->stackaddr = (char *) stackaddr + stacksize;
127 + iattr->stackaddr = (char *) stackaddr;
129 iattr->flags |= ATTR_FLAG_STACKADDR;
132 --- a/nptl/pthread_create.c
133 +++ b/nptl/pthread_create.c
135 -/* Copyright (C) 2002-2007,2008,2009 Free Software Foundation, Inc.
136 +/* Copyright (C) 2002-2007,2008,2009,2010 Free Software Foundation, Inc.
137 This file is part of the GNU C Library.
138 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
140 @@ -388,12 +388,18 @@
141 #ifdef _STACK_GROWS_DOWN
142 char *sp = CURRENT_STACK_FRAME;
143 size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
147 assert (freesize < pd->stackblock_size);
148 if (freesize > PTHREAD_STACK_MIN)
149 madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
151 + char *sp = CURRENT_STACK_FRAME;
152 + size_t freesize = ((char *) pd->stackblock + pd->stackblock_size - sp)
154 + void *freeblock = (void *) (sp + PTHREAD_STACK_MIN);
155 + assert (freesize < pd->stackblock_size);
156 + if (freesize > PTHREAD_STACK_MIN)
157 + madvise (freeblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
160 /* If the thread is detached free the TCB. */
161 if (IS_DETACHED (pd))
162 --- a/nptl/pthread_getattr_np.c
163 +++ b/nptl/pthread_getattr_np.c
165 -/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
166 +/* Copyright (C) 2002, 2003, 2004, 2006, 2007,
167 + 2010 Free Software Foundation, Inc.
168 This file is part of the GNU C Library.
169 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
172 if (__builtin_expect (thread->stackblock != NULL, 1))
174 iattr->stacksize = thread->stackblock_size;
175 +#ifdef _STACK_GROWS_DOWN
176 iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
178 + iattr->stackaddr = (char *) thread->stackblock;
183 @@ -110,13 +115,21 @@
185 /* Found the entry. Now we have the info we need. */
186 iattr->stacksize = rl.rlim_cur;
187 +#ifdef _STACK_GROWS_DOWN
188 iattr->stackaddr = (void *) to;
190 /* The limit might be too high. */
191 if ((size_t) iattr->stacksize
192 > (size_t) iattr->stackaddr - last_to)
193 iattr->stacksize = (size_t) iattr->stackaddr - last_to;
195 + iattr->stackaddr = (void *) from;
197 + /* The limit might be too high. */
198 + if ((size_t) iattr->stacksize
199 + > to - (size_t) iattr->stackaddr)
200 + iattr->stacksize = to - (size_t) iattr->stackaddr;
202 /* We succeed and no need to look further. */