patches/uClibc/0.9.29/180-linuxthreads.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jan 17 23:06:02 2010 +0100 (2010-01-17)
changeset 1740 c57458bb354d
parent 498 fc7db1806873
permissions -rw-r--r--
configure: do not require hg when configuring in an hg clone

When configuring in an hg clone, we need hg to compute the version string.
It can happen that users do not have Mercurial (eg. if they got a snapshot
rather that they did a full clone). In this case, we can still run, of
course, so simply fill the version string with a sufficiently explicit
value, that does not require hg. The date is a good candidate.
     1 --- a/libpthread/linuxthreads.old/attr.c	2006-01-24 12:41:01.000000000 -0500
     2 +++ b/libpthread/linuxthreads.old/attr.c	2008-02-10 11:35:32.000000000 -0500
     3 @@ -25,6 +25,14 @@
     4  #include "pthread.h"
     5  #include "internals.h"
     6  
     7 +#include <sys/resource.h>
     8 +#include <inttypes.h>
     9 +#include <stdio.h>
    10 +#include <stdio_ext.h>
    11 +#include <stdlib.h>
    12 +#include <sys/resource.h>
    13 +
    14 +
    15  /* NOTE: With uClibc I don't think we need this versioning stuff.
    16   * Therefore, define the function pthread_attr_init() here using
    17   * a strong symbol. */
    18 @@ -209,4 +217,94 @@ int __pthread_attr_getstacksize(const pt
    19    *stacksize = attr->__stacksize;
    20    return 0;
    21  }
    22 +
    23 +
    24 +extern int *__libc_stack_end;
    25 +
    26  weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
    27 +void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
    28 +{
    29 +    static void *stackBase = 0;
    30 +    static size_t stackSize = 0;
    31 +    int ret = 0;
    32 +    /* Stack size limit.  */
    33 +    struct rlimit rl;
    34 +
    35 +    /* The safest way to get the top of the stack is to read
    36 +    /proc/self/maps and locate the line into which
    37 +    __libc_stack_end falls.  */
    38 +    FILE *fp = fopen("/proc/self/maps", "rc");
    39 +    if (fp == NULL)
    40 +        ret = errno;
    41 +    /* We need the limit of the stack in any case.  */
    42 +    else if (getrlimit (RLIMIT_STACK, &rl) != 0)
    43 +        ret = errno;
    44 +    else {
    45 +        /* We need no locking.  */
    46 +        __fsetlocking (fp, FSETLOCKING_BYCALLER);
    47 +
    48 +        /* Until we found an entry (which should always be the case)
    49 +        mark the result as a failure.  */
    50 +        ret = ENOENT;
    51 +
    52 +        char *line = NULL;
    53 +        size_t linelen = 0;
    54 +        uintptr_t last_to = 0;
    55 +
    56 +        while (! feof_unlocked (fp)) {
    57 +            if (getdelim (&line, &linelen, '\n', fp) <= 0)
    58 +                break;
    59 +
    60 +            uintptr_t from;
    61 +            uintptr_t to;
    62 +            if (sscanf (line, "%x-%x", &from, &to) != 2)
    63 +                continue;
    64 +            if (from <= (uintptr_t) __libc_stack_end
    65 +            && (uintptr_t) __libc_stack_end < to) {
    66 +                /* Found the entry.  Now we have the info we need.  */
    67 +                attr->__stacksize = rl.rlim_cur;
    68 +#ifdef _STACK_GROWS_UP
    69 +                /* Don't check to enforce a limit on the __stacksize */
    70 +                attr->__stackaddr = (void *) from;
    71 +#else
    72 +                attr->__stackaddr = (void *) to;
    73 +
    74 +                /* The limit might be too high.  */
    75 +                if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr - last_to)
    76 +                    attr->__stacksize = (size_t) attr->__stackaddr - last_to;
    77 +#endif
    78 +
    79 +                /* We succeed and no need to look further.  */
    80 +                ret = 0;
    81 +                break;
    82 +            }
    83 +            last_to = to;
    84 +        }
    85 +
    86 +        fclose (fp);
    87 +        free (line);
    88 +    }
    89 +#ifndef _STACK_GROWS_UP
    90 +    stackBase = (char *) attr->__stackaddr - attr->__stacksize;
    91 +#else
    92 +    stackBase = attr->__stackaddr;
    93 +#endif
    94 +    stackSize = attr->__stacksize;
    95 +    return (void*)(stackBase + stackSize);
    96 +}
    97 +
    98 +int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
    99 +			     size_t *stacksize)
   100 +{
   101 +  /* XXX This function has a stupid definition.  The standard specifies
   102 +     no error value but what is if no stack address was set?  We simply
   103 +     return the value we have in the member.  */
   104 +#ifndef _STACK_GROWS_UP
   105 +  *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
   106 +#else
   107 +  *stackaddr = attr->__stackaddr;
   108 +#endif
   109 +  *stacksize = attr->__stacksize;
   110 +  return 0;
   111 +}
   112 +weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
   113 
   114 --- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h	2006-12-07 22:19:36.000000000 -0500
   115 +++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h	2008-02-10 11:42:35.000000000 -0500
   116 @@ -288,15 +288,11 @@ extern int pthread_attr_getstacksize (__
   117  				      __attr, size_t *__restrict __stacksize)
   118       __THROW;
   119  
   120 -#if 0
   121 -/* Not yet implemented in uClibc! */
   122 -
   123  #ifdef __USE_GNU
   124  /* Initialize thread attribute *ATTR with attributes corresponding to the
   125     already running thread TH.  It shall be called on unitialized ATTR
   126     and destroyed with pthread_attr_destroy when no longer needed.  */
   127 -extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
   128 -#endif
   129 +extern void* pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
   130  #endif
   131  
   132  /* Functions for scheduling control.  */
   133 @@ -599,6 +595,11 @@ extern int pthread_cancel (pthread_t __c
   134     cancelled.  */
   135  extern void pthread_testcancel (void);
   136  
   137 +/* Return the previously set address for the stack.  */
   138 +extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
   139 +				  void **__restrict __stackaddr,
   140 +				  size_t *__restrict __stacksize) __THROW;
   141 +
   142  
   143  /* Install a cleanup handler: ROUTINE will be called with arguments ARG
   144     when the thread is cancelled or calls pthread_exit.  ROUTINE will also
   145