@@ -21,10 +21,6 @@
#include <signal.h>
#include <sys/types.h>
-
-/* Nonzero if the system calls are not available. */
-extern int __no_posix_timers attribute_hidden;
-
/* Callback to start helper thread. */
extern void __start_helper_thread (void) attribute_hidden;
@@ -34,12 +30,6 @@ extern pthread_once_t __helper_once attribute_hidden;
/* TID of the helper thread. */
extern pid_t __helper_tid attribute_hidden;
-/* List of active SIGEV_THREAD timers. */
-extern struct timer *__active_timer_sigev_thread attribute_hidden;
-/* Lock for the __active_timer_sigev_thread. */
-extern pthread_mutex_t __active_timer_sigev_thread_lock attribute_hidden;
-
-
/* Type of timers in the kernel. */
typedef int kernel_timer_t;
@@ -64,3 +54,6 @@ struct timer
/* Next element in list of active SIGEV_THREAD timers. */
struct timer *next;
};
+
+void __add_active_timer_sigev (struct timer *tk) attribute_hidden;
+void __remove_active_timer_sigev (struct timer *tk) attribute_hidden;
@@ -16,17 +16,12 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include <pthread.h>
#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
#include <time.h>
-#include <sysdep.h>
-#include <internaltypes.h>
-#include <nptl/pthreadP.h>
-#include "kernel-posix-timers.h"
-#include "kernel-posix-cpu-timers.h"
+
+#include <kernel-posix-timers.h>
+#include <kernel-posix-cpu-timers.h>
+#include <internal-signals.h>
#ifdef timer_create_alias
@@ -38,17 +33,16 @@ int
timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
{
#undef timer_create
- {
- 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
- || __builtin_expect (evp->sigev_notify != SIGEV_THREAD, 1))
+ 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);
+
+ switch (evp != NULL ? evp->sigev_notify : SIGEV_SIGNAL)
+ {
+ case SIGEV_NONE:
+ case SIGEV_SIGNAL:
{
struct sigevent local_evp;
@@ -75,27 +69,22 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
}
kernel_timer_t ktimerid;
- int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
- &ktimerid);
-
- if (retval != -1)
- {
- newp->sigev_notify = (evp != NULL
- ? evp->sigev_notify : SIGEV_SIGNAL);
- newp->ktimerid = ktimerid;
-
- *timerid = (timer_t) newp;
- }
- else
+ int retval = INLINE_SYSCALL_CALL (timer_create, syscall_clockid, evp,
+ &ktimerid);
+ if (retval != 0)
{
/* Cannot allocate the timer, fail. */
free (newp);
- retval = -1;
+ return-1;
}
- return retval;
+ newp->sigev_notify = (evp != NULL ? evp->sigev_notify : SIGEV_SIGNAL);
+ newp->ktimerid = ktimerid;
+ *timerid = (timer_t) newp;
}
- else
+ break;
+
+ case SIGEV_THREAD:
{
/* Create the helper thread. */
pthread_once (&__helper_once, __start_helper_thread);
@@ -116,25 +105,10 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
newp->thrfunc = evp->sigev_notify_function;
newp->sigev_notify = SIGEV_THREAD;
- /* We cannot simply copy the thread attributes since the
- implementation might keep internal information for
- each instance. */
- (void) pthread_attr_init (&newp->attr);
if (evp->sigev_notify_attributes != NULL)
- {
- struct pthread_attr *nattr;
- struct pthread_attr *oattr;
-
- nattr = (struct pthread_attr *) &newp->attr;
- oattr = (struct pthread_attr *) evp->sigev_notify_attributes;
-
- nattr->schedparam = oattr->schedparam;
- nattr->schedpolicy = oattr->schedpolicy;
- nattr->flags = oattr->flags;
- nattr->guardsize = oattr->guardsize;
- nattr->stackaddr = oattr->stackaddr;
- nattr->stacksize = oattr->stacksize;
- }
+ newp->attr = *evp->sigev_notify_attributes;
+ else
+ pthread_attr_init (&newp->attr);
/* In any case set the detach flag. */
(void) pthread_attr_setdetachstate (&newp->attr,
@@ -148,29 +122,25 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
._sigev_un = { ._pad = { [0] = __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))
+ int res = INLINE_SYSCALL_CALL (timer_create, syscall_clockid, &sev,
+ &newp->ktimerid);
+ if (res != 0)
{
- /* Add to the queue of active timers with thread
- delivery. */
- pthread_mutex_lock (&__active_timer_sigev_thread_lock);
- newp->next = __active_timer_sigev_thread;
- __active_timer_sigev_thread = newp;
- pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
-
- *timerid = (timer_t) newp;
- return 0;
+ free (newp);
+ return -1;
}
- /* Free the resources. */
- free (newp);
+ /* Add to the queue of active timers with thread delivery. */
+ __add_active_timer_sigev (newp);
- __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
-
- return -1;
+ *timerid = (timer_t) newp;
}
- }
+ break;
+
+ default:
+ __set_errno (-1);
+ return -1;
+ }
+
+ return 0;
}
@@ -16,7 +16,6 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
-#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <sysdep.h>
@@ -35,38 +34,17 @@ timer_delete (timer_t timerid)
struct timer *kt = (struct timer *) timerid;
/* Delete the kernel timer object. */
- int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);
+ int r = INLINE_SYSCALL_CALL (timer_delete, kt->ktimerid);
+ if (r != 0)
+ /* The kernel timer is not known or something else bad happened.
+ Return the error. */
+ return -1;
- if (res == 0)
- {
- if (kt->sigev_notify == SIGEV_THREAD)
- {
- /* Remove the timer from the list. */
- pthread_mutex_lock (&__active_timer_sigev_thread_lock);
- if (__active_timer_sigev_thread == kt)
- __active_timer_sigev_thread = kt->next;
- else
- {
- struct timer *prevp = __active_timer_sigev_thread;
- while (prevp->next != NULL)
- if (prevp->next == kt)
- {
- prevp->next = kt->next;
- break;
- }
- else
- prevp = prevp->next;
- }
- pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
- }
+ if (kt->sigev_notify == SIGEV_THREAD)
+ __remove_active_timer_sigev (kt);
- /* Free the memory. */
- (void) free (kt);
+ /* Free the memory. */
+ free (kt);
- return 0;
- }
-
- /* The kernel timer is not known or something else bad happened.
- Return the error. */
- return -1;
+ return 0;
}
@@ -34,7 +34,7 @@ timer_getoverrun (timer_t timerid)
struct timer *kt = (struct timer *) timerid;
/* Get the information from the kernel. */
- int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid);
+ int res = INLINE_SYSCALL_CALL (timer_getoverrun, kt->ktimerid);
return res;
}
@@ -16,19 +16,20 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
-#include <errno.h>
-#include <setjmp.h>
+#include <pthread.h>
#include <signal.h>
-#include <stdbool.h>
-#include <sysdep-cancel.h>
+#include <stdlib.h>
+
+#include <kernel-posix-timers.h>
+#include <internal-signals.h>
#include <nptl/pthreadP.h>
-#include "kernel-posix-timers.h"
/* List of active SIGEV_THREAD timers. */
-struct timer *__active_timer_sigev_thread;
+static struct timer *__active_timer_sigev_thread;
/* Lock for the __active_timer_sigev_thread. */
-pthread_mutex_t __active_timer_sigev_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __active_timer_sigev_thread_lock
+ = PTHREAD_MUTEX_INITIALIZER;
struct thread_start_data
@@ -56,6 +57,41 @@ timer_sigev_thread (void *arg)
return NULL;
}
+/* Append a new time KT on the on the active list __active_timer_sigev_thread
+ list in a thread safe way. */
+void
+__add_active_timer_sigev (struct timer *kt)
+{
+ pthread_mutex_lock (&__active_timer_sigev_thread_lock);
+ kt->next = __active_timer_sigev_thread;
+ __active_timer_sigev_thread = kt;
+ pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
+}
+
+/* Remove the active timer KT on the active list __active_timer_sigev_thread
+ list in a thread safe way. */
+void
+__remove_active_timer_sigev (struct timer *kt)
+{
+ /* Remove the timer from the list. */
+ pthread_mutex_lock (&__active_timer_sigev_thread_lock);
+ if (__active_timer_sigev_thread == kt)
+ __active_timer_sigev_thread = kt->next;
+ else
+ {
+ struct timer *prevp = __active_timer_sigev_thread;
+ while (prevp->next != NULL)
+ if (prevp->next == kt)
+ {
+ prevp->next = kt->next;
+ break;
+ }
+ else
+ prevp = prevp->next;
+ }
+ pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
+}
+
/* Helper function to support starting threads for SIGEV_THREAD. */
static void *