From patchwork Tue Dec 10 18:32:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 1207205 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-107901-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="TjAQG6d/"; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="pjc5mQhN"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47XTGM6CxGz9sPK for ; Wed, 11 Dec 2019 05:33:31 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=hZ/l7xKk/HSvx+v2uVLU1DTPpIFVWRB 5T7kGz3oWSdo4PZIIXSDiOZ/3u/TWZwaFTbQtFHiaGAh3vYIIT4e7myCeUTpcBP0 9pUnrx+O1AJB/WlD/fZkyTPLhKG3TRRL/eqZqC9bp7rG+BIHOoRoxp+StSXQzaI0 zN3JmMo1UVjc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=t+mGM/WsKigS93MqKFuuQpuM3WU=; b=TjAQG 6d/ojBBu3IKL7pzbQA14roMugxpoLzyZLn59K4Rs9gYv3ZPxiCnokJVaDEkr7AYP 915YGzGcJJ0dMCJLoWgzapJWw+mVZbA644YUZrqUjl/dKClQ/L0WOLSWD9f3UwE6 bupyglQRzI++cjZApmWaZ4Uhfr38MrwEdZb2i0= Received: (qmail 40296 invoked by alias); 10 Dec 2019 18:32:41 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 40223 invoked by uid 89); 10 Dec 2019 18:32:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=11625, Lock, 1617 X-HELO: mail-vs1-f68.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=gqEcjCnYMjIIPch4ut8YDYRA+E/suF++kEaGZKdgeBo=; b=pjc5mQhNebLoZlLU3oa1rFTgRf/i3EuHYmN6tD05DDUMQM6FISr2LONGlgvaH8AbOa sYLtykiJbayTksBuZoPNtw3iw0R7jWLsJD7tFlFtuux6Tt8Npi+xztUZTYrg3S3YavqY +DwGnjLG9OpSF4KM7REeT7TLnf3EvLAYv2E0Zvu98ilsGQRB7CwcF3zrKpoiV8igB1en OQFHS51SiGdjLeEweti2OGA8aEMIDB58jmgGwjxK/gNQxxCy8eNMNPYLRO0PiZdZbcBp VJuf/nkNjiOH1ZlIdIMaDu9NPoNWLKP4BIT6j31CQuVi8QJF8TdlQFhvoVHCOis+OX3n agvw== From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 7/7] Cleanup timer_* routines Date: Tue, 10 Dec 2019 15:32:21 -0300 Message-Id: <20191210183221.26912-7-adhemerval.zanella@linaro.org> In-Reply-To: <20191210183221.26912-1-adhemerval.zanella@linaro.org> References: <20191210183221.26912-1-adhemerval.zanella@linaro.org> - Two function are added that manipulate the list of active timers, __{add,remove}_active_timer_sigev. This allows make both __active_timer_sigev_thread and __active_timer_sigev_thread_lock internal on timer_routine implementation. - Remove ununsed __no_posix_timers defition. - Use INLINE_SYSCALL_CALL on timer_* functions. - Simplify some code on timer_create and timer_routines, such as thread attribute handling and invalid notification method. Checked on x86_64-linux-gnu and i686-linux-gnu. --- sysdeps/unix/sysv/linux/kernel-posix-timers.h | 13 +- sysdeps/unix/sysv/linux/timer_create.c | 116 +++++++----------- sysdeps/unix/sysv/linux/timer_delete.c | 42 ++----- sysdeps/unix/sysv/linux/timer_getoverr.c | 2 +- sysdeps/unix/sysv/linux/timer_routines.c | 50 ++++++-- 5 files changed, 100 insertions(+), 123 deletions(-) diff --git a/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/sysdeps/unix/sysv/linux/kernel-posix-timers.h index d60cb95f80..bf17d8c915 100644 --- a/sysdeps/unix/sysv/linux/kernel-posix-timers.h +++ b/sysdeps/unix/sysv/linux/kernel-posix-timers.h @@ -21,10 +21,6 @@ #include #include - -/* 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; diff --git a/sysdeps/unix/sysv/linux/timer_create.c b/sysdeps/unix/sysv/linux/timer_create.c index 4e41ca011f..e5dcdaab65 100644 --- a/sysdeps/unix/sysv/linux/timer_create.c +++ b/sysdeps/unix/sysv/linux/timer_create.c @@ -16,17 +16,12 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, see . */ -#include -#include #include -#include -#include #include -#include -#include -#include -#include "kernel-posix-timers.h" -#include "kernel-posix-cpu-timers.h" + +#include +#include +#include #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; } diff --git a/sysdeps/unix/sysv/linux/timer_delete.c b/sysdeps/unix/sysv/linux/timer_delete.c index 3aec393132..ee5deb8739 100644 --- a/sysdeps/unix/sysv/linux/timer_delete.c +++ b/sysdeps/unix/sysv/linux/timer_delete.c @@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, see . */ -#include #include #include #include @@ -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; } diff --git a/sysdeps/unix/sysv/linux/timer_getoverr.c b/sysdeps/unix/sysv/linux/timer_getoverr.c index 04122a9878..82627e4ee3 100644 --- a/sysdeps/unix/sysv/linux/timer_getoverr.c +++ b/sysdeps/unix/sysv/linux/timer_getoverr.c @@ -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; } diff --git a/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c index 98bbe077fa..97882f036b 100644 --- a/sysdeps/unix/sysv/linux/timer_routines.c +++ b/sysdeps/unix/sysv/linux/timer_routines.c @@ -16,19 +16,20 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, see . */ -#include -#include +#include #include -#include -#include +#include + +#include +#include #include -#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 *