[Glibc-bsd-commits] r4167 - trunk/glibc-ports/kfreebsd/nptl
Robert Millan
rmh at alioth.debian.org
Mon Apr 2 05:25:13 UTC 2012
Author: rmh
Date: 2012-04-02 05:25:13 +0000 (Mon, 02 Apr 2012)
New Revision: 4167
Modified:
trunk/glibc-ports/kfreebsd/nptl/kernel-posix-timers.h
trunk/glibc-ports/kfreebsd/nptl/timer_create.c
trunk/glibc-ports/kfreebsd/nptl/timer_delete.c
trunk/glibc-ports/kfreebsd/nptl/timer_getoverr.c
trunk/glibc-ports/kfreebsd/nptl/timer_gettime.c
trunk/glibc-ports/kfreebsd/nptl/timer_routines.c
trunk/glibc-ports/kfreebsd/nptl/timer_settime.c
Log:
Misc portability fixes to make the imported code from NPTL work with kFreeBSD.
This is the first in a set of two commits to adapt code from NPTL/Linux to
LinuxThreads/kFreeBSD. I've split it in two commits so that the intermediate
step can be reused later when NPTL is ported to kFreeBSD.
Modified: trunk/glibc-ports/kfreebsd/nptl/kernel-posix-timers.h
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/kernel-posix-timers.h 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/kernel-posix-timers.h 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -21,6 +21,7 @@
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
+#include <sys/_types.h>
/* Nonzero if the system calls are not available. */
@@ -33,7 +34,7 @@
extern pthread_once_t __helper_once attribute_hidden;
/* TID of the helper thread. */
-extern pid_t __helper_tid attribute_hidden;
+extern __lwpid_t __helper_tid attribute_hidden;
/* List of active SIGEV_THREAD timers. */
extern struct timer *__active_timer_sigev_thread attribute_hidden;
@@ -66,3 +67,53 @@
/* Next element in list of active SIGEV_THREAD timers. */
struct timer *next;
};
+
+extern struct timer *__all_timers[TIMER_MAX];
+
+static inline struct timer *
+__kfreebsd_timer_alloc ()
+{
+ unsigned int i;
+ struct timer *timer = malloc (sizeof (struct timer));
+
+ /* Find a free slot (and reserve it atomically). */
+ for (i = 0; i < TIMER_MAX; i++)
+ if (atomic_compare_and_exchange_val_acq (&__all_timers[i],
+ timer, NULL) == NULL)
+ return timer;
+
+ errno = EAGAIN;
+ return NULL;
+}
+
+static inline struct timer *
+__kfreebsd_timer_id2ptr (timer_t id)
+{
+ void *ret = NULL;
+
+ if (id >= 0 && id < TIMER_MAX)
+ ret = __all_timers[id];
+
+ if (! ret)
+ errno = EINVAL;
+
+ return ret;
+}
+
+static inline timer_t
+__kfreebsd_timer_ptr2id (struct timer *ptr)
+{
+ unsigned int i;
+ for (i = 0; i < TIMER_MAX; i++)
+ if (__all_timers[i] == ptr)
+ return i;
+
+ return -1;
+}
+
+void static inline
+__kfreebsd_timer_free (struct timer *ptr)
+{
+ __all_timers[__kfreebsd_timer_ptr2id (ptr)] = NULL;
+ free (ptr);
+}
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_create.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_create.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_create.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003,2004, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2003,2004, 2007, 2009, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -31,7 +31,7 @@
#include "kernel-posix-cpu-timers.h"
-#ifdef __NR_timer_create
+#ifdef SYS_ktimer_create
# ifndef __ASSUME_POSIX_TIMERS
static int compat_timer_create (clockid_t clock_id, struct sigevent *evp,
timer_t *timerid);
@@ -59,12 +59,6 @@
if (__no_posix_timers >= 0)
# endif
{
- clockid_t syscall_clockid = (clock_id == CLOCK_PROCESS_CPUTIME_ID
- ? MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
- : clock_id == CLOCK_THREAD_CPUTIME_ID
- ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
- : clock_id);
-
/* If the user wants notification via a thread we need to handle
this special. */
if (evp == NULL
@@ -72,12 +66,8 @@
{
struct sigevent local_evp;
- /* We avoid allocating too much memory by basically
- using struct timer as a derived class with the
- first two elements being in the superclass. We only
- need these two elements here. */
- struct timer *newp = (struct timer *) malloc (offsetof (struct timer,
- thrfunc));
+ struct timer *newp = __kfreebsd_timer_alloc ();
+
if (newp == NULL)
/* No more memory. */
return -1;
@@ -95,7 +85,7 @@
}
kernel_timer_t ktimerid;
- int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
+ int retval = INLINE_SYSCALL (ktimer_create, 3, clock_id, evp,
&ktimerid);
# ifndef __ASSUME_POSIX_TIMERS
@@ -112,19 +102,19 @@
? evp->sigev_notify : SIGEV_SIGNAL);
newp->ktimerid = ktimerid;
- *timerid = (timer_t) newp;
+ *timerid = __kfreebsd_timer_ptr2id (newp);
}
else
{
/* Cannot allocate the timer, fail. */
- free (newp);
+ __kfreebsd_timer_free (newp);
retval = -1;
}
return retval;
}
- free (newp);
+ __kfreebsd_timer_free (newp);
# ifndef __ASSUME_POSIX_TIMERS
/* When we come here the syscall does not exist. Make sure we
@@ -138,13 +128,11 @@
/* Make sure we have the necessary kernel support. */
if (__no_posix_timers == 0)
{
- INTERNAL_SYSCALL_DECL (err);
struct timespec ts;
int res;
- res = INTERNAL_SYSCALL (clock_getres, err, 2,
- CLOCK_REALTIME, &ts);
- __no_posix_timers = (INTERNAL_SYSCALL_ERROR_P (res, err)
- ? -1 : 1);
+ res = INLINE_SYSCALL (clock_getres, 2,
+ CLOCK_REALTIME, &ts);
+ __no_posix_timers = (res == -1 ? -1 : 1);
}
if (__no_posix_timers > 0)
@@ -160,7 +148,7 @@
}
struct timer *newp;
- newp = (struct timer *) malloc (sizeof (struct timer));
+ newp = __kfreebsd_timer_alloc ();
if (newp == NULL)
return -1;
@@ -197,15 +185,15 @@
struct sigevent sev =
{ .sigev_value.sival_ptr = newp,
.sigev_signo = SIGTIMER,
- .sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID,
- ._sigev_un = { ._pad = { [0] = __helper_tid } } };
+ .sigev_notify = SIGEV_THREAD_ID,
+ .sigev_notify_thread_id = __helper_tid,
+ };
/* Create the timer. */
- INTERNAL_SYSCALL_DECL (err);
int res;
- res = INTERNAL_SYSCALL (timer_create, err, 3,
- syscall_clockid, &sev, &newp->ktimerid);
- if (! INTERNAL_SYSCALL_ERROR_P (res, err))
+ res = INLINE_SYSCALL (ktimer_create, 3,
+ clock_id, &sev, &newp->ktimerid);
+ if (res != -1)
{
/* Add to the queue of active timers with thread
delivery. */
@@ -214,15 +202,13 @@
__active_timer_sigev_thread = newp;
pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
- *timerid = (timer_t) newp;
+ *timerid = __kfreebsd_timer_ptr2id (newp);
return 0;
}
/* Free the resources. */
- free (newp);
+ __kfreebsd_timer_free (newp);
- __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
-
return -1;
}
}
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_delete.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_delete.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_delete.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -25,7 +25,7 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_delete
+#ifdef SYS_ktimer_delete
# ifndef __ASSUME_POSIX_TIMERS
static int compat_timer_delete (timer_t timerid);
# define timer_delete static compat_timer_delete
@@ -47,10 +47,12 @@
if (__no_posix_timers >= 0)
# endif
{
- struct timer *kt = (struct timer *) timerid;
+ struct timer *kt = __kfreebsd_timer_id2ptr (timerid);
+ if (! kt)
+ return -1;
/* Delete the kernel timer object. */
- int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);
+ int res = INLINE_SYSCALL (ktimer_delete, 1, kt->ktimerid);
if (res == 0)
{
@@ -81,7 +83,7 @@
# endif
/* Free the memory. */
- (void) free (kt);
+ (void) __kfreebsd_timer_free (kt);
return 0;
}
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_getoverr.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_getoverr.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_getoverr.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -24,7 +24,7 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_getoverrun
+#ifdef SYS_ktimer_getoverrun
# ifndef __ASSUME_POSIX_TIMERS
static int compat_timer_getoverrun (timer_t timerid);
# define timer_getoverrun static compat_timer_getoverrun
@@ -46,10 +46,12 @@
if (__no_posix_timers >= 0)
# endif
{
- struct timer *kt = (struct timer *) timerid;
+ struct timer *kt = __kfreebsd_timer_id2ptr (timerid);
+ if (! kt)
+ return -1;
/* Get the information from the kernel. */
- int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid);
+ int res = INLINE_SYSCALL (ktimer_getoverrun, 1, kt->ktimerid);
# ifndef __ASSUME_POSIX_TIMERS
if (res != -1 || errno != ENOSYS)
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_gettime.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_gettime.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_gettime.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -25,7 +25,7 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_gettime
+#ifdef SYS_ktimer_gettime
# ifndef __ASSUME_POSIX_TIMERS
static int compat_timer_gettime (timer_t timerid, struct itimerspec *value);
# define timer_gettime static compat_timer_gettime
@@ -48,10 +48,12 @@
if (__no_posix_timers >= 0)
# endif
{
- struct timer *kt = (struct timer *) timerid;
+ struct timer *kt = __kfreebsd_timer_id2ptr (timerid);
+ if (! kt)
+ return -1;
/* Delete the kernel timer object. */
- int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
+ int res = INLINE_SYSCALL (ktimer_gettime, 2, kt->ktimerid, value);
# ifndef __ASSUME_POSIX_TIMERS
if (res != -1 || errno != ENOSYS)
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_routines.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_routines.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_routines.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -22,10 +22,16 @@
#include <signal.h>
#include <stdbool.h>
#include <sysdep.h>
+#include <sys/_types.h> /* __lwpid_t */
+#include <atomic.h>
#include <kernel-features.h>
#include <nptl/pthreadP.h>
#include "kernel-posix-timers.h"
+/* NPTL/Linux simply casts "timer_t" to "struct timer *", but on
+ kFreeBSD timer_t may not be large enough to hold a pointer.
+ So we store the pointers here... (sigh) */
+struct timer *__all_timers[TIMER_MAX];
/* List of active SIGEV_THREAD timers. */
struct timer *__active_timer_sigev_thread;
@@ -40,7 +46,7 @@
};
-#ifdef __NR_timer_create
+#ifdef SYS_ktimer_create
/* Helper thread to call the user-provided function. */
static void *
timer_sigev_thread (void *arg)
@@ -50,8 +56,7 @@
signals. */
sigset_t ss;
sigemptyset (&ss);
- INTERNAL_SYSCALL_DECL (err);
- INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
+ sigprocmask (SIG_SETMASK, &ss, NULL);
struct thread_start_data *td = (struct thread_start_data *) arg;
@@ -91,8 +96,7 @@
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
- int result = INLINE_SYSCALL (rt_sigtimedwait, 4, &ss, &si, NULL,
- _NSIG / 8);
+ int result = sigtimedwait (&ss, &si, NULL);
LIBC_CANCEL_RESET (oldtype);
@@ -100,7 +104,7 @@
{
if (si.si_code == SI_TIMER)
{
- struct timer *tk = (struct timer *) si.si_ptr;
+ struct timer *tk = (struct timer *) si.si_value.sival_ptr;
/* Check the timer is still used and will not go away
while we are reading the values here. */
@@ -132,7 +136,9 @@
pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
}
- else if (si.si_code == SI_TKILL)
+ else if (si.si_code == SI_LWP
+ /* Backward compatibility (see rev 211732 in -CURRENT). */
+ || si.si_code == SI_USER)
/* The thread is canceled. */
pthread_exit (NULL);
}
@@ -145,7 +151,7 @@
/* TID of the helper thread. */
-pid_t __helper_tid attribute_hidden;
+__lwpid_t __helper_tid attribute_hidden;
/* Reset variables so that after a fork a new helper thread gets started. */
@@ -176,8 +182,7 @@
sigset_t oss;
sigfillset (&ss);
__sigaddset (&ss, SIGCANCEL);
- INTERNAL_SYSCALL_DECL (err);
- INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8);
+ sigprocmask (SIG_SETMASK, &ss, &oss);
/* Create the helper thread for this timer. */
pthread_t th;
@@ -187,8 +192,7 @@
__helper_tid = ((struct pthread *) th)->tid;
/* Restore the signal mask. */
- INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &oss, NULL,
- _NSIG / 8);
+ sigprocmask (SIG_SETMASK, &oss, NULL);
/* No need for the attribute anymore. */
(void) pthread_attr_destroy (&attr);
Modified: trunk/glibc-ports/kfreebsd/nptl/timer_settime.c
===================================================================
--- trunk/glibc-ports/kfreebsd/nptl/timer_settime.c 2012-04-02 05:21:55 UTC (rev 4166)
+++ trunk/glibc-ports/kfreebsd/nptl/timer_settime.c 2012-04-02 05:25:13 UTC (rev 4167)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper at redhat.com>, 2003.
@@ -25,7 +25,7 @@
#include "kernel-posix-timers.h"
-#ifdef __NR_timer_settime
+#ifdef SYS_ktimer_settime
# ifndef __ASSUME_POSIX_TIMERS
static int compat_timer_settime (timer_t timerid, int flags,
const struct itimerspec *value,
@@ -52,10 +52,12 @@
if (__no_posix_timers >= 0)
# endif
{
- struct timer *kt = (struct timer *) timerid;
+ struct timer *kt = __kfreebsd_timer_id2ptr (timerid);
+ if (! kt)
+ return -1;
/* Delete the kernel timer object. */
- int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
+ int res = INLINE_SYSCALL (ktimer_settime, 4, kt->ktimerid, flags,
value, ovalue);
# ifndef __ASSUME_POSIX_TIMERS
More information about the Glibc-bsd-commits
mailing list