bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gnulib's `lock' module v.s. the Hurd's libpthread


From: Bruno Haible
Subject: Re: gnulib's `lock' module v.s. the Hurd's libpthread
Date: Fri, 23 Mar 2007 01:13:23 +0100
User-agent: KMail/1.5.4

Hello,

Thomas Schwinge wrote:
> I'd like to have some input on the following issue.  This is the
> underlying problem of recent (newer than 0.14.5, I think) versions of GNU
> gettext failing to build for us.

Could you please have shown an error log with a precise error message?
I found [1] and [2] but it's nicer if you give all the info.

> #v+
> $ git clone git://git.sv.gnu.org/gnulib.git
> $ cd gnulib
> $ ./gnulib-tool --dir=test-lock --create-testdir lock
> [...]
> $ mkdir test-lock/build
> $ cd test-lock/build
> $ ../configure
> [...]
> checking whether imported symbols can be declared weak... yes
> checking pthread.h usability... yes
> checking pthread.h presence... yes
> checking for pthread.h... yes
> checking for pthread_kill in -lpthread... yes
> checking for pthread_rwlock_t... yes
> checking for multithread API to use... posix
> [...]
> $ make
> [...]
> $ cat > t.c
> #include "config.h"
> #include "lock.h"
> 
> int main()
> {
>   gl_rwlock_t foo;
>   gl_rwlock_destroy (foo);
> 
>   return 0;
> }
> #v-
> 
> #v+
> $ uname -a
> GNU flubber 0.3 GNU-Mach 1.3.99/Hurd-0.3 i686-AT386 GNU
> $ gcc -Wall t.c -I../gllib -Lgllib -lgnu
> gllib/libgnu.a(lock.o): In function `pthread_rwlock_destroy':
> /usr/include/bits/rwlock.h:68: undefined reference to 
> `_pthread_rwlock_destroy'
> collect2: ld returned 1 exit status
> #v-
> 
> #v+
> $ uname -a
> Linux dirichlet 2.6.20-12-generic #2 SMP Sun Mar 18 03:07:14 UTC 2007 i686 
> GNU/Linux
> $ gcc -Wall t.c -I../gllib -Lgllib -lgnu
> $ echo $?
> 0
> #v-
> 
> 
> So, where does this stem from?  The Hurd's libpthread has an optimization
> (provided in the header files), looking as follows:
> 
> #v+
> _EXTERN_INLINE int
> pthread_rwlock_destroy (struct __pthread_rwlock *__rwlock)
> {
>   extern int _pthread_rwlock_destroy (struct __pthread_rwlock *);
> 
>   if (__rwlock->__attr || __rwlock->__data)
>     return _pthread_rwlock_destroy (__rwlock);
> 
>   return 0;
> }
> #v-
> 
> The symbol `_pthread_rwlock_destroy' is provided in the pthread library
> file, which is not linked against by default, so our current libpthread
> implementation in fact asserts that if <pthread.h> is included,
> `-lpthread' will also be given when linking.

That explains where the link error comes from. Now, what to do about it?

If we were talking about systems other than GNU, I would say, I need to
fix the lock.m4 macro to add -lpthread to the link dependencies.

But this is about a glibc system. glibc - at least with LinuxThreads and
with NPTL - has the following design choice: There are programs which
use pthreads, and there are programs which don't. They link to the same
libraries. I.e. there are no two flavours of a library libfoo: libfoo.so
and libfoo_thread.so; there is only one ABI, also for libraries. But
the programs which don't use threads should not spend startup time and
memory for a loaded copy of libpthread.

How is this implemented? There are two possible approaches:
  1) libpthread and libc each contains all pthread symbols. The symbol in
     libc is just a stub, for example the pthread_mutex_init does nothing
     and just returns 0, and the pthread_create always returns an error.
     (But careful, in case libpthread gets dynamically loaded, the functions
     perform an indirection to libpthread!)
  2) The symbols are declared weak in the header files, so that their
     address evaluates to 0 when libpthread has not been loaded.

So, I would say, what you need to do is to ensure that
  - either libc has a function _pthread_rwlock_destroy() that just returns
    0 or makes an indirection to libpthread's _pthread_rwlock_destroy(),
  - or write your header file like this:

__extern_inline int
pthread_rwlock_destroy (struct __pthread_rwlock *__rwlock)
{
  extern int _pthread_rwlock_destroy (struct __pthread_rwlock *);
  #pragma weak _pthread_rwlock_destroy

  if (__rwlock->__attr || __rwlock->__data)
    {
      int (*func) (struct __pthread_rwlock *) = _pthread_rwlock_destroy;

      if (func)
        return func (__rwlock);
    }

  return 0;
}

> So, should the Hurd's libpthread be changed or which other possibilities
> are there?

I don't know which of the two approaches is preferrable. Maybe it's
obvious from the glibc/Hurd sources (where are they? in the savannah
project 'hurd' I see sources for libpthread but not for libc), maybe you
need to ask some elder statesman like Roland McGrath.

> I might also note that if replacing the `rwlock' with, e.g., a `lock'
> (i.e. `pthread_mutex_destroy') this problem does not occur.  (Why?)

On Linux too, the pthread_rwlock_* symbols are treated differently than
the pthread_mutex_* symbols. I have no idea why.

Bruno


[1] http://kibi.sysif.net/2006/09/26/
[2] http://kibi.sysif.net/pub/patches/gettext-build.log





reply via email to

[Prev in Thread] Current Thread [Next in Thread]