yann@498: --- a/libpthread/linuxthreads.old/attr.c 2006-01-24 12:41:01.000000000 -0500 yann@498: +++ b/libpthread/linuxthreads.old/attr.c 2008-02-10 11:35:32.000000000 -0500 yann@498: @@ -25,6 +25,14 @@ yann@498: #include "pthread.h" yann@498: #include "internals.h" yann@498: yann@498: +#include yann@498: +#include yann@498: +#include yann@498: +#include yann@498: +#include yann@498: +#include yann@498: + yann@498: + yann@498: /* NOTE: With uClibc I don't think we need this versioning stuff. yann@498: * Therefore, define the function pthread_attr_init() here using yann@498: * a strong symbol. */ yann@498: @@ -209,4 +217,94 @@ int __pthread_attr_getstacksize(const pt yann@498: *stacksize = attr->__stacksize; yann@498: return 0; yann@498: } yann@498: + yann@498: + yann@498: +extern int *__libc_stack_end; yann@498: + yann@498: weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize) yann@498: +void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) yann@498: +{ yann@498: + static void *stackBase = 0; yann@498: + static size_t stackSize = 0; yann@498: + int ret = 0; yann@498: + /* Stack size limit. */ yann@498: + struct rlimit rl; yann@498: + yann@498: + /* The safest way to get the top of the stack is to read yann@498: + /proc/self/maps and locate the line into which yann@498: + __libc_stack_end falls. */ yann@498: + FILE *fp = fopen("/proc/self/maps", "rc"); yann@498: + if (fp == NULL) yann@498: + ret = errno; yann@498: + /* We need the limit of the stack in any case. */ yann@498: + else if (getrlimit (RLIMIT_STACK, &rl) != 0) yann@498: + ret = errno; yann@498: + else { yann@498: + /* We need no locking. */ yann@498: + __fsetlocking (fp, FSETLOCKING_BYCALLER); yann@498: + yann@498: + /* Until we found an entry (which should always be the case) yann@498: + mark the result as a failure. */ yann@498: + ret = ENOENT; yann@498: + yann@498: + char *line = NULL; yann@498: + size_t linelen = 0; yann@498: + uintptr_t last_to = 0; yann@498: + yann@498: + while (! feof_unlocked (fp)) { yann@498: + if (getdelim (&line, &linelen, '\n', fp) <= 0) yann@498: + break; yann@498: + yann@498: + uintptr_t from; yann@498: + uintptr_t to; yann@498: + if (sscanf (line, "%x-%x", &from, &to) != 2) yann@498: + continue; yann@498: + if (from <= (uintptr_t) __libc_stack_end yann@498: + && (uintptr_t) __libc_stack_end < to) { yann@498: + /* Found the entry. Now we have the info we need. */ yann@498: + attr->__stacksize = rl.rlim_cur; yann@498: +#ifdef _STACK_GROWS_UP yann@498: + /* Don't check to enforce a limit on the __stacksize */ yann@498: + attr->__stackaddr = (void *) from; yann@498: +#else yann@498: + attr->__stackaddr = (void *) to; yann@498: + yann@498: + /* The limit might be too high. */ yann@498: + if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr - last_to) yann@498: + attr->__stacksize = (size_t) attr->__stackaddr - last_to; yann@498: +#endif yann@498: + yann@498: + /* We succeed and no need to look further. */ yann@498: + ret = 0; yann@498: + break; yann@498: + } yann@498: + last_to = to; yann@498: + } yann@498: + yann@498: + fclose (fp); yann@498: + free (line); yann@498: + } yann@498: +#ifndef _STACK_GROWS_UP yann@498: + stackBase = (char *) attr->__stackaddr - attr->__stacksize; yann@498: +#else yann@498: + stackBase = attr->__stackaddr; yann@498: +#endif yann@498: + stackSize = attr->__stacksize; yann@498: + return (void*)(stackBase + stackSize); yann@498: +} yann@498: + yann@498: +int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, yann@498: + size_t *stacksize) yann@498: +{ yann@498: + /* XXX This function has a stupid definition. The standard specifies yann@498: + no error value but what is if no stack address was set? We simply yann@498: + return the value we have in the member. */ yann@498: +#ifndef _STACK_GROWS_UP yann@498: + *stackaddr = (char *) attr->__stackaddr - attr->__stacksize; yann@498: +#else yann@498: + *stackaddr = attr->__stackaddr; yann@498: +#endif yann@498: + *stacksize = attr->__stacksize; yann@498: + return 0; yann@498: +} yann@498: +weak_alias (__pthread_attr_getstack, pthread_attr_getstack) yann@498: yann@498: --- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h 2006-12-07 22:19:36.000000000 -0500 yann@498: +++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h 2008-02-10 11:42:35.000000000 -0500 yann@498: @@ -288,15 +288,11 @@ extern int pthread_attr_getstacksize (__ yann@498: __attr, size_t *__restrict __stacksize) yann@498: __THROW; yann@498: yann@498: -#if 0 yann@498: -/* Not yet implemented in uClibc! */ yann@498: - yann@498: #ifdef __USE_GNU yann@498: /* Initialize thread attribute *ATTR with attributes corresponding to the yann@498: already running thread TH. It shall be called on unitialized ATTR yann@498: and destroyed with pthread_attr_destroy when no longer needed. */ yann@498: -extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW; yann@498: -#endif yann@498: +extern void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr); yann@498: #endif yann@498: yann@498: /* Functions for scheduling control. */ yann@498: @@ -599,6 +595,11 @@ extern int pthread_cancel (pthread_t __c yann@498: cancelled. */ yann@498: extern void pthread_testcancel (void); yann@498: yann@498: +/* Return the previously set address for the stack. */ yann@498: +extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr, yann@498: + void **__restrict __stackaddr, yann@498: + size_t *__restrict __stacksize) __THROW; yann@498: + yann@498: yann@498: /* Install a cleanup handler: ROUTINE will be called with arguments ARG yann@498: when the thread is cancelled or calls pthread_exit. ROUTINE will also yann@498: