nuttx/sched/signal/sig_procmask.c
Gregory Nutt 717bb04cb7 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.
2023-03-27 16:59:04 +03:00

204 lines
6.7 KiB
C

/****************************************************************************
* sched/signal/sig_procmask.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sched.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/wdog.h>
#include <nuttx/kmalloc.h>
#include <nuttx/signal.h>
#include "sched/sched.h"
#include "signal/signal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxsig_procmask
*
* Description:
* This function allows the calling process to examine and/or change its
* signal mask. If the 'set' is not NULL, then it points to a set of
* signals to be used to change the currently blocked set. The value of
* 'how' indicates the manner in which the set is changed.
*
* If there any pending unblocked signals after the call to
* nxsig_procmask(), those signals will be delivered before
* nxsig_procmask() returns.
*
* If nxsig_procmask() fails, the signal mask of the process is not changed
* by this function call.
*
* This is an internal OS interface. It is functionally equivalent to
* sigprocmask() except that it does not modify the errno value.
*
* Input Parameters:
* how - How the signal mask will be changed:
* SIG_BLOCK - The resulting set is the union of the current set
* and the signal set pointed to by 'set'.
* SIG_UNBLOCK - The resulting set is the intersection of the current
* set and the complement of the signal set pointed to
* by 'set'.
* SIG_SETMASK - The resulting set is the signal set pointed to by
* 'set'.
* set - Location of the new signal mask
* oset - Location to store the old signal mask
*
* 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.
*
* EINVAL - The 'how' argument is invalid.
*
****************************************************************************/
int nxsig_procmask(int how, FAR const sigset_t *set, FAR sigset_t *oset)
{
FAR struct tcb_s *rtcb = this_task();
irqstate_t flags;
int ret = OK;
sched_lock();
/* Return the old signal mask if requested */
if (oset != NULL)
{
*oset = rtcb->sigprocmask;
}
/* Modify the current signal mask if so requested */
if (set != NULL)
{
/* Some of these operations are non-atomic. We need to protect
* ourselves from attempts to process signals from interrupts
*/
flags = enter_critical_section();
/* Okay, determine what we are supposed to do */
switch (how)
{
/* The resulting set is the union of the current set and the
* signal set pointed to by set.
*/
case SIG_BLOCK:
sigorset(&rtcb->sigprocmask, &rtcb->sigprocmask,
(FAR sigset_t *)set);
break;
/* The resulting set is the intersection of the current set and
* the complement of the signal set pointed to by set.
*/
case SIG_UNBLOCK:
nxsig_nandset(&rtcb->sigprocmask, &rtcb->sigprocmask, set);
break;
/* The resulting set is the signal set pointed to by set. */
case SIG_SETMASK:
rtcb->sigprocmask = *set;
break;
default:
ret = -EINVAL;
break;
}
leave_critical_section(flags);
/* Now, process any pending signals that were just unmasked */
nxsig_unmask_pendingsignal();
}
sched_unlock();
return ret;
}
/****************************************************************************
* Name: sigprocmask
*
* Description:
* This function allows the calling process to examine and/or change its
* signal mask. If the 'set' is not NULL, then it points to a set of
* signals to be used to change the currently blocked set. The value of
* 'how' indicates the manner in which the set is changed.
*
* If there any pending unblocked signals after the call to sigprocmask(),
* those signals will be delivered before sigprocmask() returns.
*
* If sigprocmask() fails, the signal mask of the process is not changed
* by this function call.
*
* Input Parameters:
* how - How the signal mask will be changed:
* SIG_BLOCK - The resulting set is the union of the current set
* and the signal set pointed to by 'set'.
* SIG_UNBLOCK - The resulting set is the intersection of the current
* set and the complement of the signal set pointed to
* by 'set'.
* SIG_SETMASK - The resulting set is the signal set pointed to by
* 'set'.
* set - Location of the new signal mask
* oset - Location to store the old signal mask
*
* Returned Value:
* This function will return 0 (OK) on success or -1 (ERROR) if how is
* invalid. In the latter case, the errno variable will be set to EINVAL.
*
****************************************************************************/
int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset)
{
int ret;
/* Let nxsig_procmask do all of the work */
ret = nxsig_procmask(how, set, oset);
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
}
return ret;
}