This is an automated email from the ASF dual-hosted git repository. pkarashchenko pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 717bb04cb7 Increase the number of real time signals. Two is not enough. 717bb04cb7 is described below commit 717bb04cb7c6f1efb179d40a464e43e7cd13c7d8 Author: Gregory Nutt <gn...@nuttx.org> AuthorDate: Thu Mar 23 14:36:14 2023 -0600 Increase the number of real time signals. Two is not enough. Refer to issue #8867 for details and rational. Convert sigset_t to an array type so that more than 32 signals can be supported. Why not use a uin64_t? - Using a uin32_t is more flexible if we decide to increase the number of signals beyound 64. - 64-bit accesses are not atomic, at least not on 32-bit ARMv7-M and similar - Keeping the base type as uint32_t does not introduce additional overhead due to padding to achieve 64-bit alignment of uin64_t - Some architectures still supported by NuttX do not support uin64_t types, Increased the number of signals to 64. This matches Linux. This will support all xsignals defined by Linux and also 32 real time signals (also like Linux). This is is a work in progress; a draft PR that you are encouraged to comment on. --- fs/procfs/fs_procfsproc.c | 5 +- include/limits.h | 4 +- include/nuttx/signal.h | 63 ++++++++++++++++++- include/signal.h | 70 +++++++--------------- libs/libc/signal/Make.defs | 2 + libs/libc/signal/sig_addset.c | 5 +- libs/libc/signal/{sig_emptyset.c => sig_andset.c} | 32 +++++++--- libs/libc/signal/sig_delset.c | 3 +- libs/libc/signal/sig_emptyset.c | 11 +++- libs/libc/signal/sig_fillset.c | 11 +++- .../signal/{sig_emptyset.c => sig_isemptyset.c} | 38 +++++++++--- libs/libc/signal/sig_ismember.c | 2 +- libs/libc/signal/{sig_emptyset.c => sig_nandset.c} | 30 +++++++--- libs/libc/signal/{sig_emptyset.c => sig_orset.c} | 32 +++++++--- libs/libc/signal/sig_wait.c | 2 +- libs/libc/signal/{sig_emptyset.c => sig_xorset.c} | 30 +++++++--- libs/libc/spawn/lib_psa_dump.c | 3 +- libs/libc/spawn/lib_psa_init.c | 2 +- sched/misc/assert.c | 5 +- sched/pthread/pthread_exit.c | 3 +- sched/signal/sig_action.c | 4 +- sched/signal/sig_cleanup.c | 4 +- sched/signal/sig_deliver.c | 13 ++-- sched/signal/sig_dispatch.c | 11 ++-- sched/signal/sig_pending.c | 2 +- sched/signal/sig_ppoll.c | 2 +- sched/signal/sig_procmask.c | 5 +- sched/signal/sig_pselect.c | 2 +- sched/signal/sig_suspend.c | 2 +- sched/signal/sig_timedwait.c | 7 ++- sched/signal/sig_unmaskpendingsignal.c | 7 ++- sched/task/task_restart.c | 2 +- 32 files changed, 281 insertions(+), 133 deletions(-) diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 0fb6db8c8e..61531ac8e6 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -48,6 +48,7 @@ #include <nuttx/sched.h> #include <nuttx/kmalloc.h> #include <nuttx/environ.h> +#include <nuttx/signal.h> #include <nuttx/fs/fs.h> #include <nuttx/fs/procfs.h> #include <nuttx/fs/ioctl.h> @@ -637,8 +638,8 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile, /* Show the signal mask. Note: sigset_t is uint32_t on NuttX. */ linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, - "%-12s%08" PRIx32 "\n", - "SigMask:", tcb->sigprocmask); + "%-12s" SIGSET_FMT "\n", + "SigMask:", SIGSET_ELEM(&tcb->sigprocmask)); copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); diff --git a/include/limits.h b/include/limits.h index e5ae7a379c..f86fcc3fa8 100644 --- a/include/limits.h +++ b/include/limits.h @@ -146,7 +146,7 @@ /* Required for sigqueue */ -#define _POSIX_RTSIG_MAX 2 /* Number of reserved realtime signals */ +#define _POSIX_RTSIG_MAX 8 /* Number of reserved realtime signals */ #define _POSIX_SIGQUEUE_MAX 32 /* Required for symbolic links */ @@ -220,7 +220,7 @@ #define TZ_MAX_TIMES CONFIG_LIBC_TZ_MAX_TIMES #define TZ_MAX_TYPES CONFIG_LIBC_TZ_MAX_TYPES -#define RTSIG_MAX _POSIX_RTSIG_MAX +#define RTSIG_MAX 32 #define SIGQUEUE_MAX _POSIX_SIGQUEUE_MAX #define SYMLOOP_MAX _POSIX_SYMLOOP_MAX diff --git a/include/nuttx/signal.h b/include/nuttx/signal.h index 76afe2e22d..5db446b218 100644 --- a/include/nuttx/signal.h +++ b/include/nuttx/signal.h @@ -44,6 +44,19 @@ #define sigwork_init(work) (void)(work) #endif +/* Internal signal set definitions */ + +#define _NO_SIGNALS ((uint32_t)0x00000000) +#define _ALL_SIGNALS ((uint32_t)0xffffffff) +#define _SIGSET_NDX(s) ((s) >> 5) /* Get array index from signal number */ +#define _SIGSET_BIT(s) ((s) & 0x1f) /* Get bit number from signal number */ +#define _SIGNO2SET(s) ((uint32_t)1 << _SIGSET_BIT(s)) + +/* Helper macros for printing signal sets. */ + +#define SIGSET_FMT "%08" PRIx32 "%08" PRIx32 +#define SIGSET_ELEM(s) (s)->_elem[1], (s)->_elem[0] + /**************************************************************************** * Public Type Definitions ****************************************************************************/ @@ -175,7 +188,7 @@ int nxsig_addset(FAR sigset_t *set, int signo); * set specified by the 'set' argument. * * Input Parameters: - * set - Signal set to delete the signal from + * set - Signal set to delete the signal from * signo - Signal to delete * * Returned Value: @@ -191,6 +204,54 @@ int nxsig_addset(FAR sigset_t *set, int signo); int nxsig_delset(FAR sigset_t *set, int signo); +/**************************************************************************** + * Name: nxsig_nandset + * + * Description: + * This function returns the intersection of the left set and the + * complement of the right set in dest. + * + * Input Parameters: + * dest - The location to store the result + * left - The uncomplemented set used in the intersection + * right - The set that will be complemented and used in the intersection + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int nxsig_nandset(FAR sigset_t *dest, FAR const sigset_t *left, + FAR const sigset_t *right); + +/**************************************************************************** + * Name: nxsig_xorset + * + * Description: + * This function returns the xor of right and left in dest. + * + * Input Parameters: + * dest - Location to return the union + * left, right - The two sets to use in the union + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * 0 on success or -1 on failure + * + * Assumptions: + * + ****************************************************************************/ + +int nxsig_xorset(FAR sigset_t *dest, FAR const sigset_t *left, + FAR const sigset_t *right); + /**************************************************************************** * Name: nxsig_pendingset * diff --git a/include/signal.h b/include/signal.h index 3279248d21..fe20cede39 100644 --- a/include/signal.h +++ b/include/signal.h @@ -37,20 +37,27 @@ /* Signal set management definitions and macros. */ -#define NULL_SIGNAL_SET ((sigset_t)0x00000000) -#define ALL_SIGNAL_SET ((sigset_t)0xffffffff) #define MIN_SIGNO 1 /* Lowest valid signal number */ -#define MAX_SIGNO 31 /* Highest valid signal number */ +#define MAX_SIGNO 63 /* Highest valid signal number */ #define GOOD_SIGNO(s) ((((unsigned)(s)) <= MAX_SIGNO)) -#define SIGNO2SET(s) ((sigset_t)1 << (s)) + +/* Definitions for "standard" signals */ + +#define SIGSTDMIN 1 /* First standard signal number */ +#define SIGSTDMAX 31 /* Last standard signal number */ /* Definitions for "real time" signals */ -#define SIGSTDMAX 29 /* Last standard signal number */ #define SIGRTMIN (SIGSTDMAX + 1) /* First real time signal */ #define SIGRTMAX MAX_SIGNO /* Last real time signal */ #define _NSIG (MAX_SIGNO + 1) /* Biggest signal number + 1 */ +/* sigset_t is represented as an array of 32-b unsigned integers. + * _SIGSET_NELEM is the allocated isze of the array + */ + +#define _SIGSET_NELEM ((_NSIG + 31) >> 5) + /* NuttX does not support all standard signal actions. NuttX supports what * are referred to as "real time" signals. The default action of all NuttX * signals is to simply ignore the signal. Certain signals can be @@ -224,11 +231,7 @@ # define SIG_HOLD ((_sa_handler_t)1) /* Used only with sigset() */ #endif -#define tkill(tid, signo) tgkill((pid_t)-1, tid, signo) - -#define sigisemptyset(set) (!*(set)) -#define sigorset(dest, left, right) (!(*(dest) = *(left) | *(right))) -#define sigandset(dest, left, right) (!(*(dest) = *(left) & *(right))) +#define tkill(tid, signo) tgkill((pid_t)-1, tid, signo) /******************************************************************************** * Public Types @@ -239,10 +242,12 @@ * special meaning in some circumstances (e.g., kill()). */ -#ifndef __SIGSET_T_DEFINED -typedef uint32_t sigset_t; /* Bit set of 32 signals */ -#define __SIGSET_T_DEFINED 1 -#endif +struct sigset_s +{ + uint32_t _elem[_SIGSET_NELEM]; +}; + +typedef struct sigset_s sigset_t; /* Bit set of _NSIG signals */ /* Possibly volatile-qualified integer type of an object that can be accessed * as an atomic entity, even in the presence of asynchronous interrupts. @@ -295,10 +300,7 @@ struct siginfo FAR void *si_user; /* The User info associated with sigaction */ }; -#ifndef __SIGINFO_T_DEFINED typedef struct siginfo siginfo_t; -#define __SIGINFO_T_DEFINED 1 -#endif /* Non-standard convenience definition of signal handling function types. * These should be used only internally within the NuttX signal logic. @@ -351,13 +353,16 @@ int raise(int signo); int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction *oact); int sigaddset(FAR sigset_t *set, int signo); +int sigandset(FAR sigset_t *dest, FAR sigset_t *left, FAR sigset_t *right); int sigdelset(FAR sigset_t *set, int signo); int sigemptyset(FAR sigset_t *set); int sigfillset(FAR sigset_t *set); int sighold(int signo); +int sigisemptyset(FAR sigset_t *set); int sigismember(FAR const sigset_t *set, int signo); int sigignore(int signo); _sa_handler_t signal(int signo, _sa_handler_t func); +int sigorset(FAR sigset_t *dest, FAR sigset_t *left, FAR sigset_t *right); int sigpause(int signo); int sigpending(FAR sigset_t *set); int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); @@ -375,35 +380,4 @@ int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *value); } #endif -/******************************************************************************** - * Minimal Type Definitions - ********************************************************************************/ - -#else /* __INCLUDE_SIGNAL_H */ - -/* Avoid circular dependencies by assuring that simple type definitions are - * available in any inclusion ordering. - */ - -/******************************************************************************** - * Included Files - ********************************************************************************/ - -#include <stdint.h> - -/******************************************************************************** - * Public Types - ********************************************************************************/ - -#ifndef __SIGSET_T_DEFINED -typedef uint32_t sigset_t; -# define __SIGSET_T_DEFINED 1 -#endif - -#ifndef __SIGINFO_T_DEFINED -struct siginfo; -typedef struct siginfo siginfo_t; -# define __SIGINFO_T_DEFINED 1 -#endif - #endif /* __INCLUDE_SIGNAL_H */ diff --git a/libs/libc/signal/Make.defs b/libs/libc/signal/Make.defs index 12a468e589..aca684b8a9 100644 --- a/libs/libc/signal/Make.defs +++ b/libs/libc/signal/Make.defs @@ -21,6 +21,8 @@ # Add the signal C files to the build CSRCS += sig_addset.c sig_delset.c sig_emptyset.c sig_fillset.c +CSRCS += sig_nandset.c sig_andset.c sig_orset.c sig_xorset.c +CSRCS += sig_isemptyset.c CSRCS += sig_hold.c sig_ignore.c sig_ismember.c sig_pause.c sig_psignal.c CSRCS += sig_raise.c sig_relse.c sig_set.c sig_signal.c sig_wait.c diff --git a/libs/libc/signal/sig_addset.c b/libs/libc/signal/sig_addset.c index b4b240883d..b2bcc2c342 100644 --- a/libs/libc/signal/sig_addset.c +++ b/libs/libc/signal/sig_addset.c @@ -24,6 +24,7 @@ #include <signal.h> #include <errno.h> +#include <nuttx/signal.h> /**************************************************************************** * Public Functions @@ -37,7 +38,7 @@ * specified by set. * * Input Parameters: - * set - Signal set to add signal to + * set - Signal set to add signal to * signo - Signal to add * * Returned Value: @@ -63,7 +64,7 @@ int nxsig_addset(FAR sigset_t *set, int signo) { /* Add the signal to the set */ - *set |= SIGNO2SET(signo); + set->_elem[_SIGSET_NDX(signo)] |= _SIGNO2SET(signo); return OK; } } diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_andset.c similarity index 64% copy from libs/libc/signal/sig_emptyset.c copy to libs/libc/signal/sig_andset.c index a1a8516843..eebec7b5c8 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_andset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/signal/sig_emptyset.c + * libs/libc/signal/sig_andset.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -23,30 +23,46 @@ ****************************************************************************/ #include <signal.h> +#include <errno.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: sigemptyset + * Name: sigandset * * Description: - * This function initializes the signal set specified by set such that all - * signals are excluded. + * This function returns the intersection of right and left in dest. + * + * This is a non-standard function that may be provided by glibc if + * _GNU_SOURCE is defined. * * Input Parameters: - * set - Signal set to initialize + * dest - Location to store the intersection + * left, right - The two sets to use in the intersection * * Returned Value: - * 0 (OK), or -1 (ERROR) if the signal set cannot be initialized. + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * 0 on success and -1 on failure * * Assumptions: * ****************************************************************************/ -int sigemptyset(FAR sigset_t *set) +int sigandset(FAR sigset_t *dest, FAR sigset_t *left, FAR sigset_t *right) { - *set = NULL_SIGNAL_SET; + int ndx; + + /* Add the signal to the dest set */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + dest->_elem[ndx] = left->_elem[ndx] & right->_elem[ndx]; + } + return OK; } diff --git a/libs/libc/signal/sig_delset.c b/libs/libc/signal/sig_delset.c index 02b16df935..aa0d541554 100644 --- a/libs/libc/signal/sig_delset.c +++ b/libs/libc/signal/sig_delset.c @@ -24,6 +24,7 @@ #include <signal.h> #include <errno.h> +#include <nuttx/signal.h> /**************************************************************************** * Public Functions @@ -63,7 +64,7 @@ int nxsig_delset(FAR sigset_t *set, int signo) { /* Remove the signal from the set */ - *set &= ~SIGNO2SET(signo); + set->_elem[_SIGSET_NDX(signo)] &= ~_SIGNO2SET(signo); return OK; } } diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_emptyset.c index a1a8516843..dd5ddec5b0 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_emptyset.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include <signal.h> +#include <nuttx/signal.h> /**************************************************************************** * Public Functions @@ -47,6 +48,14 @@ int sigemptyset(FAR sigset_t *set) { - *set = NULL_SIGNAL_SET; + int ndx; + + /* Remove all signals from the set */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + set->_elem[ndx] = _NO_SIGNALS; + } + return OK; } diff --git a/libs/libc/signal/sig_fillset.c b/libs/libc/signal/sig_fillset.c index fe5f7e6b4b..9f88bee9ec 100644 --- a/libs/libc/signal/sig_fillset.c +++ b/libs/libc/signal/sig_fillset.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include <signal.h> +#include <nuttx/signal.h> /**************************************************************************** * Public Functions @@ -45,6 +46,14 @@ int sigfillset(FAR sigset_t *set) { - *set = ALL_SIGNAL_SET; + int ndx; + + /* Add sll signals to the set */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + set->_elem[ndx] = _ALL_SIGNALS; + } + return OK; } diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_isemptyset.c similarity index 65% copy from libs/libc/signal/sig_emptyset.c copy to libs/libc/signal/sig_isemptyset.c index a1a8516843..874a160242 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_isemptyset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/signal/sig_emptyset.c + * libs/libc/signal/sig_isemptyset.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -22,31 +22,51 @@ * Included Files ****************************************************************************/ +#include <stdbool.h> #include <signal.h> +#include <errno.h> +#include <nuttx/signal.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: sigemptyset + * Name: sigisemptyset * * Description: - * This function initializes the signal set specified by set such that all - * signals are excluded. + * This function returns 1 if set contains no signals, and 0 otherwise. + * + * This is a non-standard function that may be provided by glibc if + * _GNU_SOURCE is defined. * * Input Parameters: - * set - Signal set to initialize + * set - Signal set to test * * Returned Value: - * 0 (OK), or -1 (ERROR) if the signal set cannot be initialized. + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * true - The set is empty. * * Assumptions: * ****************************************************************************/ -int sigemptyset(FAR sigset_t *set) +int sigisemptyset(FAR sigset_t *set) { - *set = NULL_SIGNAL_SET; - return OK; + int ndx; + + /* Add the signal to the set */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + if (set->_elem[ndx] != _NO_SIGNALS) + { + return 0; + } + } + + return 1; } diff --git a/libs/libc/signal/sig_ismember.c b/libs/libc/signal/sig_ismember.c index 6c19dfbc7f..d605a92027 100644 --- a/libs/libc/signal/sig_ismember.c +++ b/libs/libc/signal/sig_ismember.c @@ -66,7 +66,7 @@ int nxsig_ismember(FAR const sigset_t *set, int signo) { /* Check if the signal is in the set */ - return ((*set & SIGNO2SET(signo)) != 0); + return ((set->_elem[_SIGSET_NDX(signo)] & _SIGNO2SET(signo)) != 0); } } diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_nandset.c similarity index 64% copy from libs/libc/signal/sig_emptyset.c copy to libs/libc/signal/sig_nandset.c index a1a8516843..9f6cba7671 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_nandset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/signal/sig_emptyset.c + * libs/libc/signal/sig_nandset.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -23,30 +23,44 @@ ****************************************************************************/ #include <signal.h> +#include <errno.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: sigemptyset + * Name: nxsig_nandset * * Description: - * This function initializes the signal set specified by set such that all - * signals are excluded. + * This function returns the intersection of the left set and the + * complement of the right set in dest. * * Input Parameters: - * set - Signal set to initialize + * dest - The location to store the result + * left - The uncomplemented set used in the intersection + * right - The set that will be complemented and used in the intersection * * Returned Value: - * 0 (OK), or -1 (ERROR) if the signal set cannot be initialized. + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. * * Assumptions: * ****************************************************************************/ -int sigemptyset(FAR sigset_t *set) +int nxsig_nandset(FAR sigset_t *dest, FAR const sigset_t *left, + FAR const sigset_t *right) { - *set = NULL_SIGNAL_SET; + int ndx; + + /* Remove the signals in the right set from the left set */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + dest->_elem[ndx] = left->_elem[ndx] & ~right->_elem[ndx]; + } + return OK; } diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_orset.c similarity index 65% copy from libs/libc/signal/sig_emptyset.c copy to libs/libc/signal/sig_orset.c index a1a8516843..63e9672d24 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_orset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/signal/sig_emptyset.c + * libs/libc/signal/sig_orset.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -23,30 +23,46 @@ ****************************************************************************/ #include <signal.h> +#include <errno.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: sigemptyset + * Name: sigorset * * Description: - * This function initializes the signal set specified by set such that all - * signals are excluded. + * This function returns the union of right and left in dest. + * + * This is a non-standard function that may be provided by glibc if + * _GNU_SOURCE is defined. * * Input Parameters: - * set - Signal set to initialize + * dest - Location to store the union + * left, right - The two sets to use in the unioon * * Returned Value: - * 0 (OK), or -1 (ERROR) if the signal set cannot be initialized. + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * 0 on success and -1 on failure * * Assumptions: * ****************************************************************************/ -int sigemptyset(FAR sigset_t *set) +int sigorset(FAR sigset_t *dest, FAR sigset_t *left, FAR sigset_t *right) { - *set = NULL_SIGNAL_SET; + int ndx; + + /* Add the signal sets */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + dest->_elem[ndx] = left->_elem[ndx] | right->_elem[ndx]; + } + return OK; } diff --git a/libs/libc/signal/sig_wait.c b/libs/libc/signal/sig_wait.c index 05164563f2..ede4744b44 100644 --- a/libs/libc/signal/sig_wait.c +++ b/libs/libc/signal/sig_wait.c @@ -61,7 +61,7 @@ * * Input Parameters: * set - The set of pending signals to wait for - * sig - The location in which to return the pending signal number. + * sig - The location in which to store the pending signal number. * * Returned Value: * Upon successful completion, sigwait() stores the signal number of the diff --git a/libs/libc/signal/sig_emptyset.c b/libs/libc/signal/sig_xorset.c similarity index 67% copy from libs/libc/signal/sig_emptyset.c copy to libs/libc/signal/sig_xorset.c index a1a8516843..1b22d19de2 100644 --- a/libs/libc/signal/sig_emptyset.c +++ b/libs/libc/signal/sig_xorset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/signal/sig_emptyset.c + * libs/libc/signal/sig_xorset.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -23,30 +23,44 @@ ****************************************************************************/ #include <signal.h> +#include <errno.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: sigemptyset + * Name: nxsig_xorset * * Description: - * This function initializes the signal set specified by set such that all - * signals are excluded. + * This function returns the xor of right and left in dest. * * Input Parameters: - * set - Signal set to initialize + * dest - Location to store the union + * left, right - The two sets to use in the union * * Returned Value: - * 0 (OK), or -1 (ERROR) if the signal set cannot be initialized. + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + * 0 on successor or -1 on failure * * Assumptions: * ****************************************************************************/ -int sigemptyset(FAR sigset_t *set) +int nxsig_xorset(FAR sigset_t *dest, FAR const sigset_t *left, + FAR const sigset_t *right) { - *set = NULL_SIGNAL_SET; + int ndx; + + /* Add the signal sets */ + + for (ndx = 0; ndx < _SIGSET_NELEM; ndx++) + { + dest->_elem[ndx] = left->_elem[ndx] ^ right->_elem[ndx]; + } + return OK; } diff --git a/libs/libc/spawn/lib_psa_dump.c b/libs/libc/spawn/lib_psa_dump.c index 16c4159f9c..d45efe86b3 100644 --- a/libs/libc/spawn/lib_psa_dump.c +++ b/libs/libc/spawn/lib_psa_dump.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <nuttx/signal.h> /* Output debug info even if debug output is not selected. */ @@ -123,7 +124,7 @@ void posix_spawnattr_dump(posix_spawnattr_t *attr) _err(" Unrecognized\n"); } - _err(" sigmask: %08jx\n", (uintmax_t)attr->sigmask); + _err(" sigmask: " SIGSET_FMT "\n", SIGSET_ELEM(&attr->sigmask)); #endif /* CONFIG_DEBUG_ERROR */ } diff --git a/libs/libc/spawn/lib_psa_init.c b/libs/libc/spawn/lib_psa_init.c index ebb06689a7..cb1261e06a 100644 --- a/libs/libc/spawn/lib_psa_init.c +++ b/libs/libc/spawn/lib_psa_init.c @@ -85,7 +85,7 @@ int posix_spawnattr_init(posix_spawnattr_t *attr) /* Empty signal mask */ - attr->sigmask = 0; + sigemptyset(&attr->sigmask); #ifdef CONFIG_SCHED_SPORADIC /* Sporadic scheduling parameters */ diff --git a/sched/misc/assert.c b/sched/misc/assert.c index e1afdd263f..6efa0873f1 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -28,6 +28,7 @@ #include <nuttx/board.h> #include <nuttx/irq.h> #include <nuttx/tls.h> +#include <nuttx/signal.h> #include <nuttx/panic_notifier.h> #include <nuttx/reboot_notifier.h> @@ -286,7 +287,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) #endif " %3d %-8s %-7s %c%c%c" " %-18s" - " %08" PRIx32 + " " SIGSET_FMT " %p" " %7zu" #ifdef CONFIG_STACK_COLORATION @@ -310,7 +311,7 @@ static void dump_task(FAR struct tcb_s *tcb, FAR void *arg) , tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : '-' , tcb->flags & TCB_FLAG_EXIT_PROCESSING ? 'P' : '-' , state - , tcb->sigprocmask + , SIGSET_ELEM(&tcb->sigprocmask) , tcb->stack_base_ptr , tcb->adj_stack_size #ifdef CONFIG_STACK_COLORATION diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index 2290cabcfe..5280bf5f92 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -63,7 +63,7 @@ void nx_pthread_exit(FAR void *exit_value) { FAR struct tcb_s *tcb = this_task(); - sigset_t set = ALL_SIGNAL_SET; + sigset_t set; int status; sinfo("exit_value=%p\n", exit_value); @@ -75,6 +75,7 @@ void nx_pthread_exit(FAR void *exit_value) * are performing the JOIN handshake. */ + sigfillset(&set); nxsig_procmask(SIG_SETMASK, &set, NULL); /* Complete pending join operations */ diff --git a/sched/signal/sig_action.c b/sched/signal/sig_action.c index c58b2bf961..cf16f98a14 100644 --- a/sched/signal/sig_action.c +++ b/sched/signal/sig_action.c @@ -235,8 +235,8 @@ int nxsig_action(int signo, FAR const struct sigaction *act, /* Return SIG_DFL if the default signal is attached */ oact->sa_handler = SIG_DFL; - oact->sa_mask = NULL_SIGNAL_SET; oact->sa_flags = SA_SIGINFO; + sigemptyset(&oact->sa_mask); } else #endif @@ -253,8 +253,8 @@ int nxsig_action(int signo, FAR const struct sigaction *act, /* There isn't an old value */ oact->sa_handler = NULL; - oact->sa_mask = NULL_SIGNAL_SET; oact->sa_flags = 0; + sigemptyset(&oact->sa_mask); } } diff --git a/sched/signal/sig_cleanup.c b/sched/signal/sig_cleanup.c index 0cab035e07..d380ce0b5e 100644 --- a/sched/signal/sig_cleanup.c +++ b/sched/signal/sig_cleanup.c @@ -61,8 +61,8 @@ void nxsig_cleanup(FAR struct tcb_s *stcb) /* Misc. signal-related clean-up */ - stcb->sigprocmask = ALL_SIGNAL_SET; - stcb->sigwaitmask = NULL_SIGNAL_SET; + sigfillset(&stcb->sigprocmask); + sigemptyset(&stcb->sigwaitmask); } /**************************************************************************** diff --git a/sched/signal/sig_deliver.c b/sched/signal/sig_deliver.c index 9a72ed64d6..da6cac89d4 100644 --- a/sched/signal/sig_deliver.c +++ b/sched/signal/sig_deliver.c @@ -33,6 +33,7 @@ #include <nuttx/irq.h> #include <nuttx/arch.h> +#include <nuttx/signal.h> #include "signal/signal.h" @@ -62,7 +63,8 @@ void nxsig_deliver(FAR struct tcb_s *stcb) FAR sigq_t *sigq; sigset_t savesigprocmask; sigset_t newsigprocmask; - sigset_t altsigprocmask; + sigset_t tmpset1; + sigset_t tmpset2; irqstate_t flags; /* Loop while there are signals to be delivered */ @@ -114,7 +116,7 @@ void nxsig_deliver(FAR struct tcb_s *stcb) */ savesigprocmask = stcb->sigprocmask; - newsigprocmask = savesigprocmask | sigq->mask; + sigorset(&newsigprocmask, &savesigprocmask, &sigq->mask); stcb->sigprocmask = newsigprocmask; #ifndef CONFIG_BUILD_FLAT @@ -182,9 +184,10 @@ void nxsig_deliver(FAR struct tcb_s *stcb) * in the current sigprocmask that were already set by newsigprocmask. */ - altsigprocmask = stcb->sigprocmask ^ newsigprocmask; - stcb->sigprocmask = (stcb->sigprocmask & altsigprocmask) | - (savesigprocmask & ~altsigprocmask); + nxsig_xorset(&tmpset1, &stcb->sigprocmask, &newsigprocmask); + sigandset(&tmpset2, &stcb->sigprocmask, &tmpset1); + nxsig_nandset(&tmpset1, &savesigprocmask, &tmpset1); + sigorset(&stcb->sigprocmask, &tmpset1, &tmpset2); /* Remove the signal structure from the sigpostedq */ diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index 8407251336..fe091ebfda 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -97,7 +97,7 @@ static int nxsig_queue_action(FAR struct tcb_s *stcb, siginfo_t *info) sigq->mask = sigact->act.sa_mask; if ((sigact->act.sa_flags & SA_NODEFER) == 0) { - sigq->mask |= SIGNO2SET(info->si_signo); + sigaddset(&sigq->mask, info->si_signo); } memcpy(&sigq->info, info, sizeof(siginfo_t)); @@ -321,9 +321,10 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) int masked; int ret = OK; - sinfo("TCB=%p pid=%d signo=%d code=%d value=%d mask=%08" PRIx32 "\n", + sinfo("TCB=%p pid=%d signo=%d code=%d value=%d masked=%s\n", stcb, stcb->pid, info->si_signo, info->si_code, - info->si_value.sival_int, stcb->sigprocmask); + info->si_value.sival_int, + sigismember(&stcb->sigprocmask, info->si_signo) == 1 ? "YES" : "NO"); DEBUGASSERT(stcb != NULL && info != NULL); @@ -383,7 +384,7 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) nxsig_ismember(&stcb->sigwaitmask, info->si_signo))) { memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t)); - stcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&stcb->sigwaitmask); if (WDOG_ISACTIVE(&stcb->waitdog)) { @@ -446,7 +447,7 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info) if (stcb->task_state == TSTATE_WAIT_SIG) { memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t)); - stcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&stcb->sigwaitmask); if (WDOG_ISACTIVE(&stcb->waitdog)) { diff --git a/sched/signal/sig_pending.c b/sched/signal/sig_pending.c index ec4a0412d1..59eafb130e 100644 --- a/sched/signal/sig_pending.c +++ b/sched/signal/sig_pending.c @@ -90,7 +90,7 @@ sigset_t nxsig_pendingset(FAR struct tcb_s *stcb) group = stcb->group; DEBUGASSERT(group); - sigpendset = NULL_SIGNAL_SET; + sigemptyset(&sigpendset); flags = enter_critical_section(); for (sigpend = (FAR sigpendq_t *)group->tg_sigpendingq.head; diff --git a/sched/signal/sig_ppoll.c b/sched/signal/sig_ppoll.c index 2bea8c9469..cf216c3306 100644 --- a/sched/signal/sig_ppoll.c +++ b/sched/signal/sig_ppoll.c @@ -91,7 +91,7 @@ int ppoll(FAR struct pollfd *fds, nfds_t nfds, rtcb->sigprocmask = *sigmask; } - rtcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&rtcb->sigwaitmask); /* Check if there is a pending signal corresponding to one of the * signals that will be unblocked by the new sigprocmask. diff --git a/sched/signal/sig_procmask.c b/sched/signal/sig_procmask.c index fa32e02117..3cca9b1491 100644 --- a/sched/signal/sig_procmask.c +++ b/sched/signal/sig_procmask.c @@ -119,7 +119,8 @@ int nxsig_procmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) */ case SIG_BLOCK: - rtcb->sigprocmask |= *set; + sigorset(&rtcb->sigprocmask, &rtcb->sigprocmask, + (FAR sigset_t *)set); break; /* The resulting set is the intersection of the current set and @@ -127,7 +128,7 @@ int nxsig_procmask(int how, FAR const sigset_t *set, FAR sigset_t *oset) */ case SIG_UNBLOCK: - rtcb->sigprocmask &= ~(*set); + nxsig_nandset(&rtcb->sigprocmask, &rtcb->sigprocmask, set); break; /* The resulting set is the signal set pointed to by set. */ diff --git a/sched/signal/sig_pselect.c b/sched/signal/sig_pselect.c index a75b79760e..402639b346 100644 --- a/sched/signal/sig_pselect.c +++ b/sched/signal/sig_pselect.c @@ -88,7 +88,7 @@ int pselect(int nfds, FAR fd_set *readfds, FAR fd_set *writefds, rtcb->sigprocmask = *sigmask; } - rtcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&rtcb->sigwaitmask); /* Check if there is a pending signal corresponding to one of the * signals that will be unblocked by the new sigprocmask. diff --git a/sched/signal/sig_suspend.c b/sched/signal/sig_suspend.c index b11949b979..b4e4667fda 100644 --- a/sched/signal/sig_suspend.c +++ b/sched/signal/sig_suspend.c @@ -101,7 +101,7 @@ int sigsuspend(FAR const sigset_t *set) saved_sigprocmask = rtcb->sigprocmask; rtcb->sigprocmask = *set; - rtcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&rtcb->sigwaitmask); /* Check if there is a pending signal corresponding to one of the * signals that will be unblocked by the new sigprocmask. diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c index 77ab7634b9..2f4c693913 100644 --- a/sched/signal/sig_timedwait.c +++ b/sched/signal/sig_timedwait.c @@ -260,8 +260,9 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info, * signals in the pending signal set argument. */ - intersection = *set & nxsig_pendingset(rtcb); - if (intersection != NULL_SIGNAL_SET) + intersection = nxsig_pendingset(rtcb); + sigandset(&intersection, &intersection, (FAR sigset_t *)set); + if (!sigisemptyset(&intersection)) { /* One or more of the signals in intersections is sufficient to cause * us to not wait. Pick the lowest numbered signal and mark it not @@ -414,7 +415,7 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info, /* We are running again, clear the sigwaitmask */ - rtcb->sigwaitmask = NULL_SIGNAL_SET; + sigemptyset(&rtcb->sigwaitmask); /* When we awaken, the cause will be in the TCB. Get the signal number * or timeout) that awakened us. diff --git a/sched/signal/sig_unmaskpendingsignal.c b/sched/signal/sig_unmaskpendingsignal.c index edac039f16..9262a047cd 100644 --- a/sched/signal/sig_unmaskpendingsignal.c +++ b/sched/signal/sig_unmaskpendingsignal.c @@ -65,8 +65,9 @@ bool nxsig_unmask_pendingsignal(void) * can only be changed on this thread of execution. */ - unmaskedset = ~(rtcb->sigprocmask) & nxsig_pendingset(rtcb); - if (unmaskedset == NULL_SIGNAL_SET) + unmaskedset = nxsig_pendingset(rtcb); + nxsig_nandset(&unmaskedset, &unmaskedset, &rtcb->sigprocmask); + if (sigisemptyset(&unmaskedset)) { sched_unlock(); return false; @@ -109,7 +110,7 @@ bool nxsig_unmask_pendingsignal(void) } } } - while (unmaskedset != NULL_SIGNAL_SET); + while (!sigisemptyset(&unmaskedset)); sched_unlock(); return true; diff --git a/sched/task/task_restart.c b/sched/task/task_restart.c index 4f4c131031..e3f9f573f8 100644 --- a/sched/task/task_restart.c +++ b/sched/task/task_restart.c @@ -144,7 +144,7 @@ int nxtask_restart(pid_t pid) /* Deallocate anything left in the TCB's signal queues */ nxsig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */ - tcb->cmn.sigprocmask = NULL_SIGNAL_SET; /* Reset sigprocmask */ + sigemptyset(&tcb->cmn.sigprocmask); /* Reset sigprocmask */ /* Reset the current task priority */