[Glibc-bsd-commits] r4559 - in trunk/glibc-ports/kfreebsd: fbtl x86_64/fbtl
Petr Salinger
ps-guest at alioth.debian.org
Mon Jul 8 12:42:38 UTC 2013
Author: ps-guest
Date: 2013-06-21 20:10:26 +0000 (Fri, 21 Jun 2013)
New Revision: 4559
Added:
trunk/glibc-ports/kfreebsd/fbtl/Makefile
trunk/glibc-ports/kfreebsd/fbtl/fork.c
trunk/glibc-ports/kfreebsd/fbtl/fork.h
trunk/glibc-ports/kfreebsd/fbtl/gai_misc.h
trunk/glibc-ports/kfreebsd/fbtl/libc_multiple_threads.c
trunk/glibc-ports/kfreebsd/fbtl/libc_pthread_init.c
trunk/glibc-ports/kfreebsd/fbtl/pt-fork.c
trunk/glibc-ports/kfreebsd/fbtl/pthread_mutex_cond_lock.c
trunk/glibc-ports/kfreebsd/fbtl/pthread_sigmask.c
trunk/glibc-ports/kfreebsd/fbtl/register-atfork.c
trunk/glibc-ports/kfreebsd/fbtl/sigprocmask.c
trunk/glibc-ports/kfreebsd/fbtl/syscalls.list
trunk/glibc-ports/kfreebsd/fbtl/unregister-atfork.c
Modified:
trunk/glibc-ports/kfreebsd/x86_64/fbtl/lowlevellock.h
Log:
bits of fbtl
Added: trunk/glibc-ports/kfreebsd/fbtl/Makefile
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/Makefile (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/Makefile 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,38 @@
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+ifeq ($(subdir),fbtl)
+sysdep_routines += register-atfork unregister-atfork libc_pthread_init \
+ libc_multiple_threads
+
+libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
+
+gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
+ lowlevelbarrier.sym unwindbuf.sym \
+ lowlevelrobustlock.sym pthread-pi-defines.sym \
+ structsem.sym
+endif
+
+ifeq ($(subdir),posix)
+CFLAGS-fork.c = $(libio-mtsafe)
+CFLAGS-getpid.o = -fomit-frame-pointer
+CFLAGS-getpid.os = -fomit-frame-pointer
+endif
+
+# Needed in both the signal and nptl subdir.
+CFLAGS-sigaction.c = -DWRAPPER_INCLUDE='<fbtl/sigaction.c>'
Added: trunk/glibc-ports/kfreebsd/fbtl/fork.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/fork.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/fork.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,219 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <libio/libioP.h>
+#include <tls.h>
+#include "fork.h"
+#include <hp-timing.h>
+#include <ldsodefs.h>
+#include <bits/stdio-lock.h>
+#include <atomic.h>
+#include <pthreadP.h>
+
+
+unsigned long int *__fork_generation_pointer;
+
+
+
+/* The single linked list of all currently registered fork handlers. */
+struct fork_handler *__fork_handlers;
+
+
+static void
+fresetlockfiles (void)
+{
+ _IO_ITER i;
+
+ for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i))
+ _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock));
+}
+
+
+pid_t
+__libc_fork (void)
+{
+ pid_t pid;
+ struct used_handler
+ {
+ struct fork_handler *handler;
+ struct used_handler *next;
+ } *allp = NULL;
+
+ /* Run all the registered preparation handlers. In reverse order.
+ While doing this we build up a list of all the entries. */
+ struct fork_handler *runp;
+ while ((runp = __fork_handlers) != NULL)
+ {
+ /* Make sure we read from the current RUNP pointer. */
+ atomic_full_barrier ();
+
+ unsigned int oldval = runp->refcntr;
+
+ if (oldval == 0)
+ /* This means some other thread removed the list just after
+ the pointer has been loaded. Try again. Either the list
+ is empty or we can retry it. */
+ continue;
+
+ /* Bump the reference counter. */
+ if (atomic_compare_and_exchange_bool_acq (&__fork_handlers->refcntr,
+ oldval + 1, oldval))
+ /* The value changed, try again. */
+ continue;
+
+ /* We bumped the reference counter for the first entry in the
+ list. That means that none of the following entries will
+ just go away. The unloading code works in the order of the
+ list.
+
+ While executing the registered handlers we are building a
+ list of all the entries so that we can go backward later on. */
+ while (1)
+ {
+ /* Execute the handler if there is one. */
+ if (runp->prepare_handler != NULL)
+ runp->prepare_handler ();
+
+ /* Create a new element for the list. */
+ struct used_handler *newp
+ = (struct used_handler *) alloca (sizeof (*newp));
+ newp->handler = runp;
+ newp->next = allp;
+ allp = newp;
+
+ /* Advance to the next handler. */
+ runp = runp->next;
+ if (runp == NULL)
+ break;
+
+ /* Bump the reference counter for the next entry. */
+ atomic_increment (&runp->refcntr);
+ }
+
+ /* We are done. */
+ break;
+ }
+
+ _IO_list_lock ();
+
+#ifndef NDEBUG
+ pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid);
+#endif
+
+ /* We need to prevent the getpid() code to update the PID field so
+ that, if a signal arrives in the child very early and the signal
+ handler uses getpid(), the value returned is correct. */
+ pid_t parentpid = THREAD_GETMEM (THREAD_SELF, pid);
+ THREAD_SETMEM (THREAD_SELF, pid, -parentpid);
+
+#ifdef ARCH_FORK
+ pid = ARCH_FORK ();
+#else
+# warning "ARCH_FORK must be defined so that the CLONE_SETTID flag is used"
+ pid = INLINE_SYSCALL (fork, 0);
+#endif
+
+
+ if (pid == 0)
+ {
+ struct pthread *self = THREAD_SELF;
+
+ assert (THREAD_GETMEM (self, tid) != ppid);
+
+ if (__fork_generation_pointer != NULL)
+ *__fork_generation_pointer += 4;
+
+ /* Adjust the PID field for the new process. */
+ THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid));
+
+#if HP_TIMING_AVAIL
+ /* The CPU clock of the thread and process have to be set to zero. */
+ hp_timing_t now;
+ HP_TIMING_NOW (now);
+ THREAD_SETMEM (self, cpuclock_offset, now);
+ GL(dl_cpuclock_offset) = now;
+#endif
+
+ /* Reset the file list. These are recursive mutexes. */
+ fresetlockfiles ();
+
+ /* Reset locks in the I/O code. */
+ _IO_list_resetlock ();
+
+ /* Reset the lock the dynamic loader uses to protect its data. */
+ __rtld_lock_initialize (GL(dl_load_lock));
+
+ /* Run the handlers registered for the child. */
+ while (allp != NULL)
+ {
+ if (allp->handler->child_handler != NULL)
+ allp->handler->child_handler ();
+
+ /* Note that we do not have to wake any possible waiter.
+ This is the only thread in the new process. The count
+ may have been bumped up by other threads doing a fork.
+ We reset it to 1, to avoid waiting for non-existing
+ thread(s) to release the count. */
+ allp->handler->refcntr = 1;
+
+ /* XXX We could at this point look through the object pool
+ and mark all objects not on the __fork_handlers list as
+ unused. This is necessary in case the fork() happened
+ while another thread called dlclose() and that call had
+ to create a new list. */
+
+ allp = allp->next;
+ }
+
+ /* Initialize the fork lock. */
+ __fork_lock = LLL_LOCK_INITIALIZER;
+ }
+ else
+ {
+ assert (THREAD_GETMEM (THREAD_SELF, tid) == ppid);
+
+ /* Restore the PID value. */
+ THREAD_SETMEM (THREAD_SELF, pid, parentpid);
+
+ /* We execute this even if the 'fork' call failed. */
+ _IO_list_unlock ();
+
+ /* Run the handlers registered for the parent. */
+ while (allp != NULL)
+ {
+ if (allp->handler->parent_handler != NULL)
+ allp->handler->parent_handler ();
+
+ if (atomic_decrement_and_test (&allp->handler->refcntr)
+ && allp->handler->need_signal)
+ lll_futex_wake (allp->handler->refcntr, 1, LLL_PRIVATE);
+
+ allp = allp->next;
+ }
+ }
+
+ return pid;
+}
+weak_alias (__libc_fork, __fork)
+libc_hidden_def (__fork)
+weak_alias (__libc_fork, fork)
Added: trunk/glibc-ports/kfreebsd/fbtl/fork.h
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/fork.h (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/fork.h 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,59 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <lowlevellock.h>
+
+/* The fork generation counter, defined in libpthread. */
+extern unsigned long int __fork_generation attribute_hidden;
+
+/* Pointer to the fork generation counter in the thread library. */
+extern unsigned long int *__fork_generation_pointer attribute_hidden;
+
+/* Lock to protect allocation and deallocation of fork handlers. */
+extern int __fork_lock attribute_hidden;
+
+/* Elements of the fork handler lists. */
+struct fork_handler
+{
+ struct fork_handler *next;
+ void (*prepare_handler) (void);
+ void (*parent_handler) (void);
+ void (*child_handler) (void);
+ void *dso_handle;
+ unsigned int refcntr;
+ int need_signal;
+};
+
+/* The single linked list of all currently registered for handlers. */
+extern struct fork_handler *__fork_handlers attribute_hidden;
+
+
+/* Function to call to unregister fork handlers. */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+
+/* C library side function to register new fork handlers. */
+extern int __register_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void),
+ void *dso_handle);
+libc_hidden_proto (__register_atfork)
+
+/* Add a new element to the fork list. */
+extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden;
Added: trunk/glibc-ports/kfreebsd/fbtl/gai_misc.h
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/gai_misc.h (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/gai_misc.h 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,119 @@
+/* Copyright (C) 2006-2013 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* We define a special synchronization primitive for AIO. POSIX
+ conditional variables would be ideal but the pthread_cond_*wait
+ operations do not return on EINTR. This is a requirement for
+ correct aio_suspend and lio_listio implementations. */
+
+#include <assert.h>
+#include <signal.h>
+#include <pthreadP.h>
+#include <lowlevellock.h>
+
+#define DONT_NEED_GAI_MISC_COND 1
+
+#define GAI_MISC_NOTIFY(waitlist) \
+ do { \
+ if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
+ lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE); \
+ } while (0)
+
+#warning have to check sign of return values from futex wait calls
+
+#define GAI_MISC_WAIT(result, futex, timeout, cancel) \
+ do { \
+ volatile int *futexaddr = &futex; \
+ int oldval = futex; \
+ \
+ if (oldval != 0) \
+ { \
+ pthread_mutex_unlock (&__gai_requests_mutex); \ \
+ int oldtype; \
+ if (cancel) \
+ oldtype = LIBC_CANCEL_ASYNC (); \
+ \
+ int status; \
+ do \
+ { \
+ status = lll_futex_timed_wait (futexaddr, oldval, timeout, \
+ LLL_PRIVATE); \
+ if (status != -EWOULDBLOCK) \
+ break; \
+ \
+ oldval = *futexaddr; \
+ } \
+ while (oldval != 0); \
+ \
+ if (cancel) \
+ LIBC_CANCEL_RESET (oldtype); \
+ \
+ if (status == -EINTR) \
+ result = EINTR; \
+ else if (status == -ETIMEDOUT) \
+ result = EAGAIN; \
+ else \
+ assert (status == 0 || status == -EWOULDBLOCK); \
+ \
+ pthread_mutex_lock (&__gai_requests_mutex); \
+ } \
+ } while (0)
+
+
+#define gai_start_notify_thread __gai_start_notify_thread
+#define gai_create_helper_thread __gai_create_helper_thread
+
+extern inline void
+__gai_start_notify_thread (void)
+{
+ sigset_t ss;
+ sigemptyset (&ss);
+ INLINE_SYSCALL (sigprocmask, 3, SIG_SETMASK, &ss, NULL);
+}
+
+extern inline int
+__gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
+ void *arg)
+{
+ pthread_attr_t attr;
+
+ /* Make sure the thread is created detached. */
+ pthread_attr_init (&attr);
+ pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+ /* The helper thread needs only very little resources. */
+ (void) pthread_attr_setstacksize (&attr,
+ __pthread_get_minstack (&attr)
+ + 4 * PTHREAD_STACK_MIN);
+
+ /* Block all signals in the helper thread. To do this thoroughly we
+ temporarily have to block all signals here. */
+ sigset_t ss;
+ sigset_t oss;
+ sigfillset (&ss);
+ INLINE_SYSCALL (sigprocmask, 3, SIG_SETMASK, &ss, &oss);
+
+ int ret = pthread_create (threadp, &attr, tf, arg);
+
+ /* Restore the signal mask. */
+ INLINE_SYSCALL (sigprocmask, 3, SIG_SETMASK, &oss, NULL);
+
+ (void) pthread_attr_destroy (&attr);
+ return ret;
+}
+
+#include <resolv/gai_misc.h>
Added: trunk/glibc-ports/kfreebsd/fbtl/libc_multiple_threads.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/libc_multiple_threads.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/libc_multiple_threads.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,28 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthreadP.h>
+
+#ifndef NOT_IN_libc
+# ifndef TLS_MULTIPLE_THREADS_IN_TCB
+/* Variable set to a nonzero value either if more than one thread runs or ran,
+ or if a single-threaded process is trying to cancel itself. See
+ nptl/descr.h for more context on the single-threaded process case. */
+int __libc_multiple_threads attribute_hidden;
+# endif
+#endif
Added: trunk/glibc-ports/kfreebsd/fbtl/libc_pthread_init.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/libc_pthread_init.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/libc_pthread_init.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,86 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <list.h>
+#include <fork.h>
+#include <dl-sysdep.h>
+#include <tls.h>
+#include <string.h>
+#include <pthreadP.h>
+#include <bits/libc-lock.h>
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
+void
+#else
+extern int __libc_multiple_threads attribute_hidden;
+
+int *
+#endif
+__libc_pthread_init (ptr, reclaim, functions)
+ unsigned long int *ptr;
+ void (*reclaim) (void);
+ const struct pthread_functions *functions;
+{
+ /* Remember the pointer to the generation counter in libpthread. */
+ __fork_generation_pointer = ptr;
+
+ /* Called by a child after fork. */
+ __register_atfork (NULL, NULL, reclaim, NULL);
+
+#ifdef SHARED
+ /* Copy the function pointers into an array in libc. This enables
+ access with just one memory reference but moreso, it prevents
+ hijacking the function pointers with just one pointer change. We
+ "encrypt" the function pointers since we cannot write-protect the
+ array easily enough. */
+ union ptrhack
+ {
+ struct pthread_functions pf;
+# define NPTRS (sizeof (struct pthread_functions) / sizeof (void *))
+ void *parr[NPTRS];
+ } __attribute__ ((may_alias)) const *src;
+ union ptrhack *dest;
+
+ src = (const void *) functions;
+ dest = (void *) &__libc_pthread_functions;
+
+ for (size_t cnt = 0; cnt < NPTRS; ++cnt)
+ {
+ void *p = src->parr[cnt];
+ PTR_MANGLE (p);
+ dest->parr[cnt] = p;
+ }
+ __libc_pthread_functions_init = 1;
+#endif
+
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+ return &__libc_multiple_threads;
+#endif
+}
+
+#ifdef SHARED
+libc_freeres_fn (freeres_libptread)
+{
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr_freeres, ());
+}
+#endif
Added: trunk/glibc-ports/kfreebsd/fbtl/pt-fork.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/pt-fork.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/pt-fork.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,27 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+
+
+pid_t
+__fork (void)
+{
+ return __libc_fork ();
+}
+strong_alias (__fork, fork)
Added: trunk/glibc-ports/kfreebsd/fbtl/pthread_mutex_cond_lock.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/pthread_mutex_cond_lock.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/pthread_mutex_cond_lock.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,14 @@
+#include <pthreadP.h>
+
+#define LLL_MUTEX_LOCK(mutex) \
+ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+#define LLL_MUTEX_TRYLOCK(mutex) \
+ lll_cond_trylock ((mutex)->__data.__lock)
+#define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+ lll_robust_cond_lock ((mutex)->__data.__lock, id, \
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
+#define __pthread_mutex_lock __pthread_mutex_cond_lock
+#define __pthread_mutex_lock_full __pthread_mutex_cond_lock_full
+#define NO_INCR
+
+#include <fbtl/pthread_mutex_lock.c>
Added: trunk/glibc-ports/kfreebsd/fbtl/pthread_sigmask.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/pthread_sigmask.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/pthread_sigmask.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define BUILD_AS_pthread_sigmask 1
+#include "sigprocmask.c"
Added: trunk/glibc-ports/kfreebsd/fbtl/register-atfork.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/register-atfork.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/register-atfork.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,145 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fork.h>
+#include <atomic.h>
+
+
+/* Lock to protect allocation and deallocation of fork handlers. */
+int __fork_lock = LLL_LOCK_INITIALIZER;
+
+
+/* Number of pre-allocated handler entries. */
+#define NHANDLER 48
+
+/* Memory pool for fork handler structures. */
+static struct fork_handler_pool
+{
+ struct fork_handler_pool *next;
+ struct fork_handler mem[NHANDLER];
+} fork_handler_pool;
+
+
+static struct fork_handler *
+fork_handler_alloc (void)
+{
+ struct fork_handler_pool *runp = &fork_handler_pool;
+ struct fork_handler *result = NULL;
+ unsigned int i;
+
+ do
+ {
+ /* Search for an empty entry. */
+ for (i = 0; i < NHANDLER; ++i)
+ if (runp->mem[i].refcntr == 0)
+ goto found;
+ }
+ while ((runp = runp->next) != NULL);
+
+ /* We have to allocate a new entry. */
+ runp = (struct fork_handler_pool *) calloc (1, sizeof (*runp));
+ if (runp != NULL)
+ {
+ /* Enqueue the new memory pool into the list. */
+ runp->next = fork_handler_pool.next;
+ fork_handler_pool.next = runp;
+
+ /* We use the last entry on the page. This means when we start
+ searching from the front the next time we will find the first
+ entry unused. */
+ i = NHANDLER - 1;
+
+ found:
+ result = &runp->mem[i];
+ result->refcntr = 1;
+ result->need_signal = 0;
+ }
+
+ return result;
+}
+
+
+int
+__register_atfork (prepare, parent, child, dso_handle)
+ void (*prepare) (void);
+ void (*parent) (void);
+ void (*child) (void);
+ void *dso_handle;
+{
+ /* Get the lock to not conflict with other allocations. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ struct fork_handler *newp = fork_handler_alloc ();
+
+ if (newp != NULL)
+ {
+ /* Initialize the new record. */
+ newp->prepare_handler = prepare;
+ newp->parent_handler = parent;
+ newp->child_handler = child;
+ newp->dso_handle = dso_handle;
+
+ __linkin_atfork (newp);
+ }
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ return newp == NULL ? ENOMEM : 0;
+}
+libc_hidden_def (__register_atfork)
+
+
+void
+attribute_hidden
+__linkin_atfork (struct fork_handler *newp)
+{
+ do
+ newp->next = __fork_handlers;
+ while (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ newp, newp->next) != 0);
+}
+
+
+libc_freeres_fn (free_mem)
+{
+ /* Get the lock to not conflict with running forks. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ /* No more fork handlers. */
+ __fork_handlers = NULL;
+
+ /* Free eventually alloated memory blocks for the object pool. */
+ struct fork_handler_pool *runp = fork_handler_pool.next;
+
+ memset (&fork_handler_pool, '\0', sizeof (fork_handler_pool));
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ /* We can free the memory after releasing the lock. */
+ while (runp != NULL)
+ {
+ struct fork_handler_pool *oldp = runp;
+ runp = runp->next;
+ free (oldp);
+ }
+}
Added: trunk/glibc-ports/kfreebsd/fbtl/sigprocmask.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/sigprocmask.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/sigprocmask.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,69 @@
+/* Copyright (C) 1997-2013 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+#include <pthreadP.h>
+
+/* Get and/or change the set of blocked signals. */
+int
+#if BUILD_AS_pthread_sigmask
+pthread_sigmask(how, set, oset)
+#else
+__sigprocmask (how, set, oset)
+#endif
+ int how;
+ const sigset_t *set;
+ sigset_t *oset;
+{
+ sigset_t local_newmask;
+ int rv;
+
+ /* The only thing we have to make sure here is that SIGCANCEL and
+ SIGSETXID are not blocked. */
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+ ))
+ {
+ local_newmask = *set;
+ __sigdelset (&local_newmask, SIGCANCEL);
+ __sigdelset (&local_newmask, SIGSETXID);
+ set = &local_newmask;
+ }
+
+ rv = INLINE_SYSCALL (sigprocmask, 3, how, set, oset);
+#if BUILD_AS_pthread_sigmask
+ return rv;
+}
+#else
+ if (rv)
+ {
+ errno = rv;
+ return -1;
+ }
+ return 0;
+}
+weak_alias (__sigprocmask, sigprocmask)
+#endif
Added: trunk/glibc-ports/kfreebsd/fbtl/syscalls.list
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/syscalls.list (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/syscalls.list 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,2 @@
+# File name Caller Syscall name # args Strong name Weak names
+sys_sigprocmask EXTRA sigprocmask Vi:iPP __syscall_sigprocmask
Added: trunk/glibc-ports/kfreebsd/fbtl/unregister-atfork.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/unregister-atfork.c (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/unregister-atfork.c 2013-06-21 20:10:26 UTC (rev 4559)
@@ -0,0 +1,121 @@
+/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <fork.h>
+#include <atomic.h>
+
+
+void
+__unregister_atfork (dso_handle)
+ void *dso_handle;
+{
+ /* Check whether there is any entry in the list which we have to
+ remove. It is likely that this is not the case so don't bother
+ getting the lock.
+
+ We do not worry about other threads adding entries for this DSO
+ right this moment. If this happens this is a race and we can do
+ whatever we please. The program will crash anyway seen. */
+ struct fork_handler *runp = __fork_handlers;
+ struct fork_handler *lastp = NULL;
+
+ while (runp != NULL)
+ if (runp->dso_handle == dso_handle)
+ break;
+ else
+ {
+ lastp = runp;
+ runp = runp->next;
+ }
+
+ if (runp == NULL)
+ /* Nothing to do. */
+ return;
+
+ /* Get the lock to not conflict with additions or deletions. Note
+ that there couldn't have been another thread deleting something.
+ The __unregister_atfork function is only called from the
+ dlclose() code which itself serializes the operations. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ /* We have to create a new list with all the entries we don't remove. */
+ struct deleted_handler
+ {
+ struct fork_handler *handler;
+ struct deleted_handler *next;
+ } *deleted = NULL;
+
+ /* Remove the entries for the DSO which is unloaded from the list.
+ It's a single linked list so readers are. */
+ do
+ {
+ again:
+ if (runp->dso_handle == dso_handle)
+ {
+ if (lastp == NULL)
+ {
+ /* We have to use an atomic operation here because
+ __linkin_atfork also uses one. */
+ if (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ runp->next, runp)
+ != 0)
+ {
+ runp = __fork_handlers;
+ goto again;
+ }
+ }
+ else
+ lastp->next = runp->next;
+
+ /* We cannot overwrite the ->next element now. Put the deleted
+ entries in a separate list. */
+ struct deleted_handler *newp = alloca (sizeof (*newp));
+ newp->handler = runp;
+ newp->next = deleted;
+ deleted = newp;
+ }
+ else
+ lastp = runp;
+
+ runp = runp->next;
+ }
+ while (runp != NULL);
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ /* Walk the list of all entries which have to be deleted. */
+ while (deleted != NULL)
+ {
+ /* We need to be informed by possible current users. */
+ deleted->handler->need_signal = 1;
+ /* Make sure this gets written out first. */
+ atomic_write_barrier ();
+
+ /* Decrement the reference counter. If it does not reach zero
+ wait for the last user. */
+ atomic_decrement (&deleted->handler->refcntr);
+ unsigned int val;
+ while ((val = deleted->handler->refcntr) != 0)
+ lll_futex_wait (&deleted->handler->refcntr, val, LLL_PRIVATE);
+
+ deleted = deleted->next;
+ }
+}
Modified: trunk/glibc-ports/kfreebsd/x86_64/fbtl/lowlevellock.h
===================================================================
--- trunk/glibc-ports/kfreebsd/x86_64/fbtl/lowlevellock.h 2013-06-21 16:48:17 UTC (rev 4558)
+++ trunk/glibc-ports/kfreebsd/x86_64/fbtl/lowlevellock.h 2013-06-21 20:10:26 UTC (rev 4559)
@@ -45,7 +45,7 @@
# endif
#endif
-#define SYS_futex __NR_futex
+#define SYS_futex 123456
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_CMP_REQUEUE 4
More information about the Glibc-bsd-commits
mailing list