How goes the NPTL merge?

Denys Vlasenko vda.linux at googlemail.com
Wed Feb 25 11:49:09 UTC 2009


On Tuesday 17 February 2009 09:16:01 am Carmelo AMOROSO wrote:
> Rob Landley wrote:
> > Just noticed Denys checking more stuff into the nptl branch.  (Mirroring a
> > commit to mainline with a second commit to the branch.)
> Basiacally Denys is tryuing to make the merge easier doing this double
> commit when working on generic stuff (not tls neither nptl related)
> 
> > How much is left to
> > merge into mainline from there?
> >
> I'm trying to create, as explained times ago, single patches
> for TLS/futexes/NPTL part for step by step inclusion into the trunk,

As of now, uClibc-nptl source tree is 2.4 megabytes bigger than
uClibc trunk. This is suspiciously big, 20...25% growth, why?

I must admit that what I am seeing in not particularly encouraging.
My fear is that yet another pthread implementation will land,
without cleanup, without docs, with many hacks scattered
all across the tree.


For example, uClibc-nptl/libc/inet/socketcalls.c:

#ifdef __UCLIBC_HAS_THREADS_NATIVE__
#include <sysdep-cancel.h>
#include <pthreadP.h>
#else
#define SINGLE_THREAD_P 1
#endif

#ifdef L_accept
extern __typeof(accept) __libc_accept;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ why do you need this at all?
              wouldn't it compile just fine without this line?
#ifdef __NR_accept
#define __NR___libc_accept  __NR_accept
_syscall3(int, __libc_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen)
#elif defined(__NR_socketcall)
int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
{
        unsigned long args[3];

        args[0] = s;
        args[1] = (unsigned long) addr;
        args[2] = (unsigned long) addrlen;

        if (SINGLE_THREAD_P)
                return __socketcall(SYS_ACCEPT, args);

#ifdef __UCLIBC_HAS_THREADS_NATIVE__
        int oldtype = LIBC_CANCEL_ASYNC ();
        int result = __socketcall(SYS_ACCEPT, args);
        LIBC_CANCEL_RESET (oldtype);
        return result;
#endif

}
#endif
/* libc_hidden_proto(accept) */
weak_alias(__libc_accept,accept)
libc_hidden_weak(accept)
#endif


Comments:

(1) __libc_accept will exist even if no threading is requested in the .config.
For what purpose? We should avoid having any "secret interfaces" exposed.

Example for uClibc trunk:
this is how you avoid having it for functions with hidden aliases:

_syscall3(ssize_t, write, int, fd, const __ptr_t, buf, size_t, count)
#ifndef __LINUXTHREADS_OLD__
libc_hidden_def(write)
#else
libc_hidden_weak(write)
strong_alias(write,__libc_write)
#endif

   and for functions without hidden aliases:

#ifdef __LINUXTHREADS_OLD__
extern __typeof(pause) weak_function pause;
strong_alias(pause,__libc_pause)
#endif
_syscall0(int, pause)


(2) Some people will object to having "int oldtype" not
at the beginning of the block. This is C++ism.
Even though I am not one of them, I would prefer
to not alienate that group.


(3) Why some aliases are using __foo instead of __libc_foo? Foe example,
__writev, __clone. Can you make it uniform?


(4) Since glibc 2.8 manages to NOT create any __libc_accept or __accept,
can you avoid it too? Which leads to mey next comment...


(5) Can you create some rudimentary documentation about NPTL internals
and put it into docs/*? I do not understand what this "cancellation" stuff
is all about and why we need to bend over backwards to support it.
I imagine there is a very good reason for it, but "imagine" and "understand"
are two different things. Docs will really help here.
If you want them proof-read and discussed, the mailing list is the best place.

--
vda


More information about the uClibc mailing list