Things found in a git diff 1fcd93fd3c733eb19bcad8d03e65f13ec4b0e998..master-viengoos-on-bare-metal that are not specific to L4 or Viengoos, and may be worth having on master, too.

__pthread_alloc init with malloc or calloc

diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c
index 6af2da9..c63801f 100644
--- a/pthread/pt-alloc.c
+++ b/pthread/pt-alloc.c
@@ -123,7 +123,7 @@ __pthread_alloc (struct __pthread **pthread)
     }

   /* Allocate a new thread structure.  */
-  new = malloc (sizeof (struct __pthread));
+  new = calloc (sizeof (struct __pthread), 1);
   if (new == NULL)
     return ENOMEM;

atomic.h

Later on master, commit 608a12659f15d57abf42a972c1e56c6a24cfe244: Rename bits/atomic.h to bits/pt-atomic.h.

diff --git a/pthread/pt-create.c b/pthread/pt-create.c
index 8f62b78..504cacc 100644
--- a/pthread/pt-create.c
+++ b/pthread/pt-create.c
@@ -22,7 +22,7 @@
 #include <pthread.h>
 #include <signal.h>

-#include <bits/atomic.h>
+#include <atomic.h>

 #include <pt-internal.h>

@@ -33,7 +33,7 @@
 /* The total number of pthreads currently active.  This is defined
    here since it would be really stupid to have a threads-using
    program that doesn't call `pthread_create'.  */
-__atomic_t __pthread_total;
+atomic_fast32_t __pthread_total;

 
 /* The entry-point for new threads.  */
@@ -163,7 +163,7 @@ __pthread_create_internal (struct __pthread **thread,
      the number of threads from within the new thread isn't an option
      since this thread might return and call `pthread_exit' before the
      new thread runs.  */
-  __atomic_inc (&__pthread_total);
+  atomic_increment (&__pthread_total);

   /* Store a pointer to this thread in the thread ID lookup table.  We
      could use __thread_setid, however, we only lock for reading as no
@@ -190,7 +190,7 @@ __pthread_create_internal (struct __pthread **thread,

  failed_starting:
   __pthread_setid (pthread->thread, NULL);
-  __atomic_dec (&__pthread_total);
+  atomic_decrement (&__pthread_total);
  failed_sigstate:
   __pthread_sigstate_destroy (pthread);
  failed_setup:
diff --git a/pthread/pt-exit.c b/pthread/pt-exit.c
index 5fe0ba8..68c56d7 100644
--- a/pthread/pt-exit.c
+++ b/pthread/pt-exit.c
@@ -24,7 +24,7 @@

 #include <pt-internal.h>

-#include <bits/atomic.h>
+#include <atomic.h>


 /* Terminate the current thread and make STATUS available to any
@@ -57,7 +57,7 @@ pthread_exit (void *status)

   /* Decrease the number of threads.  We use an atomic operation to
      make sure that only the last thread calls `exit'.  */
-  if (__atomic_dec_and_test (&__pthread_total))
+  if (atomic_decrement_and_test (&__pthread_total))
     /* We are the last thread.  */
     exit (0);

diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h
index cb441d0..986ec6b 100644
--- a/pthread/pt-internal.h
+++ b/pthread/pt-internal.h
@@ -26,13 +26,15 @@
 #include <signal.h>
 #include <assert.h>

-#include <bits/atomic.h>
+#include <atomic.h>
[...]
@@ -136,7 +144,7 @@ __pthread_dequeue (struct __pthread *thread)
        )

 /* The total number of threads currently active.  */
-extern __atomic_t __pthread_total;
+extern atomic_fast32_t __pthread_total;

 /* The total number of thread IDs currently in use, or on the list of
    available thread IDs.  */
diff --git a/sysdeps/ia32/bits/atomic.h b/sysdeps/ia32/bits/atomic.h
deleted file mode 100644
index 0dfc1f6..0000000
--- a/sysdeps/ia32/bits/atomic.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Atomic operations.  i386 version.
-   Copyright (C) 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef _BITS_ATOMIC_H
-#define _BITS_ATOMIC_H 1
-
-typedef __volatile int __atomic_t;
-
-static inline void
-__atomic_inc (__atomic_t *__var)
-{
-  __asm__ __volatile ("lock; incl %0" : "=m" (*__var) : "m" (*__var));
-}
-
-static inline void
-__atomic_dec (__atomic_t *__var)
-{
-  __asm__ __volatile ("lock; decl %0" : "=m" (*__var) : "m" (*__var));
-}
-
-static inline int
-__atomic_dec_and_test (__atomic_t *__var)
-{
-  unsigned char __ret;
-
-  __asm__ __volatile ("lock; decl %0; sete %1"
-             : "=m" (*__var), "=qm" (__ret) : "m" (*__var));
-  return __ret != 0;
-}
-
-/* We assume that an __atomicptr_t is only used for pointers to
-   word-aligned objects, and use the lowest bit for a simple lock.  */
-typedef __volatile int * __atomicptr_t;
-
-/* Actually we don't implement that yet, and assume that we run on
-   something that has the i486 instruction set.  */
-static inline int
-__atomicptr_compare_and_swap (__atomicptr_t *__ptr, void *__oldval,
-                 void * __newval)
-{
-  char __ret;
-  int __dummy;
-
-  __asm__ __volatile ("lock; cmpxchgl %3, %1; sete %0"
-             : "=q" (__ret), "=m" (*__ptr), "=a" (__dummy)
-             : "r" (__newval), "m" (*__ptr), "a" (__oldval));
-  return __ret;
-}
-
-#endif

Memory Barries

diff --git a/sysdeps/generic/bits/memory.h b/sysdeps/generic/bits/memory.h
new file mode 100644
index 0000000..7b88a7e
--- /dev/null
+++ b/sysdeps/generic/bits/memory.h
@@ -0,0 +1,36 @@
+/* Memory barrier operations.  Generic version.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3 of the
+   License, or (at your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_MEMORY_H
+#define _BITS_MEMORY_H 1
+
+/* Prevent read and write reordering across this function.  */
+static inline void
+__memory_barrier (void)
+{
+  /* Any lock'ed instruction will do.  */
+  __sync_synchronize ();
+}
+
+/* Prevent read reordering across this function.  */
+#define __memory_read_barrier __memory_barrier
+
+/* Prevent write reordering across this function.  */
+#define __memory_write_barrier __memory_barrier
+
+#endif

Spin Locks

diff --git a/sysdeps/generic/bits/spin-lock-inline.h b/sysdeps/generic/bits/spin-lock-inline.h
new file mode 100644
index 0000000..6c3e06e
--- /dev/null
+++ b/sysdeps/generic/bits/spin-lock-inline.h
@@ -0,0 +1,99 @@
+/* Machine-specific definitions for spin locks.  Generic version.
+   Copyright (C) 2000, 2005, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_SPIN_LOCK_INLINE_H
+#define _BITS_SPIN_LOCK_INLINE_H   1
+
+#include <features.h>
+#include <bits/spin-lock.h>
+
+__BEGIN_DECLS
+
+#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES
+
+# if !defined (__EBUSY) || !defined (__EINVAL)
+#  include <errno.h>
+#  ifndef __EBUSY
+#   define __EBUSY EBUSY
+#  endif
+#  ifndef __EINVAL
+#   define __EINVAL EINVAL
+#  endif
+# endif
+
+# ifndef __PT_SPIN_INLINE
+#  define __PT_SPIN_INLINE __extern_inline
+# endif
+
+__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_destroy (__pthread_spinlock_t *__lock)
+{
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock,
+                     int __pshared);
+
+__PT_SPIN_INLINE int
+__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared)
+{
+  *__lock = __SPIN_LOCK_INITIALIZER;
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_trylock (__pthread_spinlock_t *__lock)
+{
+  int __locked = __sync_val_compare_and_swap (__lock, 0, 1);
+  return __locked ? __EBUSY : 0;
+}
+
+__extern_inline int __pthread_spin_lock (__pthread_spinlock_t *__lock);
+extern int _pthread_spin_lock (__pthread_spinlock_t *__lock);
+
+__extern_inline int
+__pthread_spin_lock (__pthread_spinlock_t *__lock)
+{
+  if (__pthread_spin_trylock (__lock))
+    return _pthread_spin_lock (__lock);
+  return 0;
+}
+
+__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_unlock (__pthread_spinlock_t *__lock)
+{
+  int __locked = __sync_val_compare_and_swap (__lock, 1, 0);
+  return __locked ? 0 : __EINVAL;
+}
+
+#endif /* Use extern inlines or force inlines.  */
+
+__END_DECLS
+
+#endif /* bits/spin-lock.h */
diff --git a/sysdeps/l4/bits/pthread-np.h b/sysdeps/generic/bits/spin-lock.h
similarity index 67%
rename from sysdeps/l4/bits/pthread-np.h
rename to sysdeps/generic/bits/spin-lock.h
index 6a02bdc..c2ba332 100644
--- a/sysdeps/l4/bits/pthread-np.h
+++ b/sysdeps/generic/bits/spin-lock.h
@@ -1,5 +1,5 @@
-/* Non-portable functions. L4 version.
-   Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+/* Machine-specific definitions for spin locks.  Generic version.
+   Copyright (C) 2000, 2005, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
@@ -21,15 +21,19 @@
  * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
  */

-#ifndef _BITS_PTHREAD_NP_H
-#define _BITS_PTHREAD_NP_H 1
+#ifndef _BITS_SPIN_LOCK_H
+#define _BITS_SPIN_LOCK_H  1

-#include <l4.h>
+#include <features.h>

-/* Add the thread TID to the internal kernel thread pool.  */
-extern int pthread_pool_add_np (l4_thread_id_t tid);
+__BEGIN_DECLS

-/* Get the first thread from the pool.  */
-extern l4_thread_id_t pthread_pool_get_np (void);
+/* The type of a spin lock object.  */
+typedef __volatile int __pthread_spinlock_t;

-#endif /* bits/pthread-np.h */
+/* Initializer for a spin lock object.  */
+# define __SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0)
+
+__END_DECLS
+
+#endif /* bits/spin-lock.h */

Signal Stuff

diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h
index cb441d0..986ec6b 100644
--- a/pthread/pt-internal.h
+++ b/pthread/pt-internal.h
@@ -26,13 +26,15 @@
[...]
 #include <pt-sysdep.h>
 #include <pt-machdep.h>

+#include <sig-internal.h>
+
 /* Thread state.  */
 enum pthread_state
 {
@@ -54,6 +56,10 @@ enum pthread_state
 # define PTHREAD_SYSDEP_MEMBERS
 #endif

+#ifndef PTHREAD_SIGNAL_MEMBERS
+# define PTHREAD_SIGNAL_MEMBERS
+#endif
+
 /* This structure describes a POSIX thread.  */
 struct __pthread
 {
@@ -89,6 +95,8 @@ struct __pthread

   PTHREAD_SYSDEP_MEMBERS

+  PTHREAD_SIGNAL_MEMBERS
+
   struct __pthread *next, **prevp;
 };

diff --git a/signal/kill.c b/signal/kill.c
index 27c9c32..c281640 100644
--- a/signal/kill.c
+++ b/signal/kill.c
@@ -20,6 +20,8 @@

 #include "sig-internal.h"

+#include <string.h>
+
 int
 kill (pid_t pid, int signo)
 {
@@ -65,6 +67,12 @@ kill (pid_t pid, int signo)
      current thread has blocked the signal, the correct thing to do is
      to iterate over all the other threads and find on that hasn't
      blocked it.  */
+
+  extern int __pthread_num_threads;
+  if (__pthread_num_threads == 0)
+    panic ("signal %d received before pthread library is able to handle it",
+      signo);
+
   return pthread_kill (pthread_self (), signo);
 }

diff --git a/signal/pt-kill-siginfo-np.c b/signal/pt-kill-siginfo-np.c
index 9bdf6cc..35642c3 100644
--- a/signal/pt-kill-siginfo-np.c
+++ b/signal/pt-kill-siginfo-np.c
@@ -75,7 +75,8 @@ pthread_kill_siginfo_np (pthread_t tid, siginfo_t si)
      || (ss->stack.ss_flags & SS_DISABLE)
      || (ss->stack.ss_flags & SS_ONSTACK)))
     /* We are sending a signal to ourself and we don't use an
-       alternate stack.  */
+       alternate stack.  (Recall: SA_ONSTACK means use the alt
+       stack.)  */
     signal_dispatch (ss, &si);
   else
     signal_dispatch_lowlevel (ss, tid, si);
diff --git a/signal/signal-dispatch.c b/signal/signal-dispatch.c
index 40440b7..6fafcc1 100644
--- a/signal/signal-dispatch.c
+++ b/signal/signal-dispatch.c
@@ -20,6 +20,8 @@

 #include "sig-internal.h"

+#include <viengoos/math.h>
+
 /* This is the signal handler entry point.  A thread is forced into
    this state when it receives a signal.  We need to save the thread's
    state and then invoke the high-level signal dispatcher.  SS->LOCK
@@ -107,7 +109,7 @@ signal_dispatch (struct signal_state *ss, siginfo_t *si)
       sigset_t pending = ~ss->blocked & ss->pending;
       if (! pending)
    pending = ~ss->blocked & process_pending;
-      signo = l4_lsb64 (pending);
+      signo = vg_lsb64 (pending);
     }
   while (signo);

diff --git a/signal/sigwaiter.c b/signal/sigwaiter.c
index 8d041ac..adc05ca 100644
--- a/signal/sigwaiter.c
+++ b/signal/sigwaiter.c
@@ -20,7 +20,7 @@

 #include "sig-internal.h"

-#include <hurd/futex.h>
+#include <viengoos/futex.h>

 struct sigwaiter *sigwaiters;

diff --git a/signal/sigwaitinfo.c b/signal/sigwaitinfo.c
index 1b47079..dea3ef4 100644
--- a/signal/sigwaitinfo.c
+++ b/signal/sigwaitinfo.c
@@ -43,7 +43,7 @@ sigwaitinfo (const sigset_t *restrict set, siginfo_t *restrict info)

       assert (extant);

-      int signo = l4_msb64 (extant);
+      int signo = vg_msb64 (extant);

       if (info)
    {

ALWAYS_TRACK_MUTEX_OWNER

diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c
index ee43219..265a453 100644
--- a/sysdeps/generic/pt-mutex-timedlock.c
+++ b/sysdeps/generic/pt-mutex-timedlock.c
@@ -36,7 +36,6 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
   if (__pthread_spin_trylock (&mutex->__held) == 0)
     /* Successfully acquired the lock.  */
     {
-#ifdef ALWAYS_TRACK_MUTEX_OWNER
 #ifndef NDEBUG
       self = _pthread_self ();
       if (self)
@@ -48,7 +47,6 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
      mutex->owner = _pthread_self ();
    }
 #endif
-#endif

       if (mutex->attr)
    switch (mutex->attr->mutex_type)
@@ -75,16 +73,14 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
   self = _pthread_self ();
   assert (self);

-  if (! mutex->attr || mutex->attr->mutex_type == PTHREAD_MUTEX_NORMAL)
-    {
-#if defined(ALWAYS_TRACK_MUTEX_OWNER)
-      assert (mutex->owner != self);
-#endif
-    }
-  else
+  if (mutex->attr)
     {
       switch (mutex->attr->mutex_type)
    {
+   case PTHREAD_MUTEX_NORMAL:
+     assert (mutex->owner != self);
+     break;
+
    case PTHREAD_MUTEX_ERRORCHECK:
      if (mutex->owner == self)
        {
@@ -106,10 +102,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
      LOSE;
    }
     }
+  else
+    assert (mutex->owner != self);

-#if !defined(ALWAYS_TRACK_MUTEX_OWNER)
-  if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL)
-#endif
     assert (mutex->owner);

   if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
@@ -146,12 +141,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
   else
     __pthread_block (self);

-#if !defined(ALWAYS_TRACK_MUTEX_OWNER)
-  if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL)
-#endif
-    {
+#ifndef NDEBUG
       assert (mutex->owner == self);
-    }
+#endif

   if (mutex->attr)
     switch (mutex->attr->mutex_type)
diff --git a/sysdeps/generic/pt-mutex-transfer-np.c b/sysdeps/generic/pt-mutex-transfer-np.c
index 7796ac4..bcb809d 100644
--- a/sysdeps/generic/pt-mutex-transfer-np.c
+++ b/sysdeps/generic/pt-mutex-transfer-np.c
@@ -45,12 +45,7 @@ __pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid)
     }

 #ifndef NDEBUG
-# if !defined(ALWAYS_TRACK_MUTEX_OWNER)
-  if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL)
-# endif
-    {
       mutex->owner = thread;
-    }
 #endif

   return 0;
diff --git a/sysdeps/generic/pt-mutex-unlock.c b/sysdeps/generic/pt-mutex-unlock.c
index 7645fd4..f299750 100644
--- a/sysdeps/generic/pt-mutex-unlock.c
+++ b/sysdeps/generic/pt-mutex-unlock.c
@@ -33,16 +33,19 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex)

   if (! mutex->attr || mutex->attr->mutex_type == PTHREAD_MUTEX_NORMAL)
     {
-#if defined(ALWAYS_TRACK_MUTEX_OWNER)
 # ifndef NDEBUG
       if (_pthread_self ())
    {
      assert (mutex->owner);
-     assert (mutex->owner == _pthread_self ());
+     assertx (mutex->owner == _pthread_self (),
+          "%p("VG_THREAD_ID_FMT") != %p("VG_THREAD_ID_FMT")",
+          mutex->owner,
+          ((struct __pthread *) mutex->owner)->threadid,
+          _pthread_self (),
+          _pthread_self ()->threadid);
      mutex->owner = NULL;
    }
 # endif
-#endif
     }
   else
     switch (mutex->attr->mutex_type)
@@ -81,12 +84,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex)
   __pthread_dequeue (wakeup);

 #ifndef NDEBUG
-# if !defined (ALWAYS_TRACK_MUTEX_OWNER)
-  if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL)
-# endif
-    {
       mutex->owner = wakeup;
-    }
 #endif

   /* We do not unlock MUTEX->held: we are transferring the ownership

t/fix_have_kernel_resources

See topic branch of that name.

diff --git a/sysdeps/mach/hurd/pt-sysdep.h b/sysdeps/mach/hurd/pt-sysdep.h
index f14a136..83bad96 100644
--- a/sysdeps/mach/hurd/pt-sysdep.h
+++ b/sysdeps/mach/hurd/pt-sysdep.h
@@ -1,5 +1,5 @@
 /* Internal defenitions for pthreads library.
-   Copyright (C) 2000, 2002, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
@@ -32,8 +32,7 @@

 #define PTHREAD_SYSDEP_MEMBERS \
   thread_t kernel_thread;      \
-  mach_msg_header_t wakeupmsg; \
-  int have_kernel_resources;
+  mach_msg_header_t wakeupmsg;

 #define _HURD_THREADVAR_THREAD _HURD_THREADVAR_DYNAMIC_USER

diff --git a/sysdeps/mach/pt-thread-alloc.c b/sysdeps/mach/pt-thread-alloc.c
index 3d7c046..1acba98 100644
--- a/sysdeps/mach/pt-thread-alloc.c
+++ b/sysdeps/mach/pt-thread-alloc.c
@@ -1,5 +1,5 @@
 /* Start thread.  Mach version.
-   Copyright (C) 2000, 2002, 2005, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
@@ -63,9 +63,6 @@ create_wakeupmsg (struct __pthread *thread)
 int
 __pthread_thread_alloc (struct __pthread *thread)
 {
-  if (thread->have_kernel_resources)
-    return 0;
-
   error_t err;

   err = create_wakeupmsg (thread);
@@ -100,7 +97,5 @@ __pthread_thread_alloc (struct __pthread *thread)
    return EAGAIN;
     }

-  thread->have_kernel_resources = 1;
-
   return 0;
 }

Miscellaneous

diff --git a/Makefile b/Makefile
index 04dfb26..a4c0c52 100644
--- a/Makefile
+++ b/Makefile
@@ -71,7 +71,6 @@ SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c          \
    pt-mutex-init.c pt-mutex-destroy.c                  \
    pt-mutex-lock.c pt-mutex-trylock.c pt-mutex-timedlock.c         \
    pt-mutex-unlock.c                           \
-   pt-mutex-transfer-np.c                          \
    pt-mutex-getprioceiling.c pt-mutex-setprioceiling.c         \
                                        \
    pt-rwlock-attr.c                            \
@@ -100,7 +99,6 @@ SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c         \
    pt-thread-dealloc.c                         \
    pt-thread-start.c                           \
    pt-thread-halt.c                            \
-   pt-startup.c                                \
                                        \
    pt-getconcurrency.c pt-setconcurrency.c                 \
                                        \
@@ -143,7 +141,6 @@ sysdeps_headers =               \
          semaphore.h           \
                        \
               bits/pthread.h           \
-              bits/pthread-np.h            \
               bits/mutex.h         \
               bits/condition.h         \
               bits/condition-attr.h        \
diff --git a/Makefile.am b/Makefile.am
index e59c946..e73d8d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,17 +20,18 @@
 if ARCH_IA32
   arch=ia32
 endif
+if ARCH_X86_64
+  arch=x86_64
+endif
 if ARCH_POWERPC
   arch=powerpc
 endif

 # The source files are scattered over several directories.  Add 
 # all these directories to the vpath.
-SYSDEP_PATH = $(srcdir)/sysdeps/l4/hurd/${arch}    \
-    $(srcdir)/sysdeps/l4/${arch}       \
+SYSDEP_PATH = $(srcdir)/sysdeps/viengoos/${arch} \
     $(srcdir)/sysdeps/${arch}      \
-    $(srcdir)/sysdeps/l4/hurd      \
-    $(srcdir)/sysdeps/l4           \
+    $(srcdir)/sysdeps/viengoos     \
     $(srcdir)/sysdeps/hurd         \
     $(srcdir)/sysdeps/generic      \
     $(srcdir)/sysdeps/posix        \
@@ -68,7 +69,6 @@ libpthread_a_SOURCES = pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
    pt-alloc.c                              \
    pt-create.c                             \
    pt-getattr.c                                \
-   pt-pool-np.c                                \
    pt-equal.c                              \
    pt-dealloc.c                                \
    pt-detach.c                             \
diff --git a/headers.m4 b/headers.m4
index 5a58b9b..7c73cf2 100644
--- a/headers.m4
+++ b/headers.m4
@@ -14,10 +14,9 @@ AC_CONFIG_LINKS([
   sysroot/include/pthread.h:libpthread/include/pthread.h
   sysroot/include/pthread/pthread.h:libpthread/include/pthread/pthread.h
   sysroot/include/pthread/pthreadtypes.h:libpthread/include/pthread/pthreadtypes.h
-  sysroot/include/bits/memory.h:libpthread/sysdeps/${arch}/bits/memory.h
-  sysroot/include/bits/spin-lock.h:libpthread/sysdeps/${arch}/bits/spin-lock.h
-  sysroot/include/bits/spin-lock-inline.h:libpthread/sysdeps/${arch}/bits/spin-lock-inline.h
-  sysroot/include/bits/pthreadtypes.h:libpthread/sysdeps/generic/bits/pthreadtypes.h
+  sysroot/include/bits/memory.h:libpthread/sysdeps/generic/bits/memory.h
+  sysroot/include/bits/spin-lock.h:libpthread/sysdeps/generic/bits/spin-lock.h
+  sysroot/include/bits/spin-lock-inline.h:libpthread/sysdeps/generic/bits/spin-lock-inline.h
   sysroot/include/bits/barrier-attr.h:libpthread/sysdeps/generic/bits/barrier-attr.h
   sysroot/include/bits/barrier.h:libpthread/sysdeps/generic/bits/barrier.h
   sysroot/include/bits/cancelation.h:libpthread/sysdeps/generic/bits/cancelation.h
@@ -30,9 +29,8 @@ AC_CONFIG_LINKS([
   sysroot/include/bits/rwlock-attr.h:libpthread/sysdeps/generic/bits/rwlock-attr.h
   sysroot/include/bits/rwlock.h:libpthread/sysdeps/generic/bits/rwlock.h
   sysroot/include/bits/thread-attr.h:libpthread/sysdeps/generic/bits/thread-attr.h
-  sysroot/include/bits/thread-barrier.h:libpthread/sysdeps/generic/bits/thread-barrier.h
   sysroot/include/bits/thread-specific.h:libpthread/sysdeps/generic/bits/thread-specific.h
-  sysroot/include/bits/pthread-np.h:libpthread/sysdeps/l4/hurd/bits/pthread-np.h
+  sysroot/include/bits/pthread-np.h:libpthread/sysdeps/viengoos/bits/pthread-np.h
   sysroot/include/semaphore.h:libpthread/include/semaphore.h
   sysroot/include/bits/semaphore.h:libpthread/sysdeps/generic/bits/semaphore.h
   sysroot/include/signal.h:libpthread/signal/signal.h
@@ -41,5 +39,5 @@ AC_CONFIG_LINKS([
 AC_CONFIG_COMMANDS_POST([
   mkdir -p sysroot/lib libpthread &&
   ln -sf ../../libpthread/libpthread.a sysroot/lib/ &&
-  touch libpthread/libpthread.a
+  echo '/* This file intentionally left blank.  */' >libpthread/libpthread.a
 ])
diff --git a/sysdeps/hurd/pt-setspecific.c b/sysdeps/hurd/pt-setspecific.c
index 89ca4d7..d2d1157 100644
--- a/sysdeps/hurd/pt-setspecific.c
+++ b/sysdeps/hurd/pt-setspecific.c
@@ -1,5 +1,5 @@
 /* pthread_setspecific.  Generic version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.

    The GNU C Library is free software; you can redistribute it and/or
@@ -30,7 +30,8 @@ pthread_setspecific (pthread_key_t key, const void *value)

   if (! self->thread_specifics)
     {
-      err = hurd_ihash_create (&self->thread_specifics, HURD_IHASH_NO_LOCP);
+      err = hurd_ihash_create (&self->thread_specifics, false,
+                  HURD_IHASH_NO_LOCP);
       if (err)
    return ENOMEM;
     }
diff --git a/sysdeps/mach/pt-thread-halt.c b/sysdeps/mach/pt-thread-halt.c
index 973cde1..9f86024 100644
--- a/sysdeps/mach/pt-thread-halt.c
+++ b/sysdeps/mach/pt-thread-halt.c
@@ -30,8 +30,14 @@
    being halted, thus the last action should be halting the thread
    itself.  */
 void
-__pthread_thread_halt (struct __pthread *thread)
+__pthread_thread_halt (struct __pthread *thread, int need_dealloc)
 {
-  error_t err = __thread_terminate (thread->kernel_thread);
+  error_t err;
+  thread_t tid = thread->kernel_thread;
+
+  if (need_dealloc)
+    __pthread_dealloc (thread);
+
+  err = __thread_terminate (tid);
   assert_perror (err);
 }