libc: add support for sigsetjmp() and siglongjmp()

Add support for sigsetjmp() and siglongjmp().

This implementation is build on top of setjmp() and longjmp().
sigsetjmp() in that case must be implemented as a macro otherwise
we lose setjmp context.
siglongjmp() is kept as inline function to satisfy the PSE52 VSX
tests requirement.

An alternative implementation requires writing these function in
assembly code for each architecture.

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
This commit is contained in:
p-szafonimateusz 2025-07-31 15:32:43 +02:00 committed by Xiang Xiao
parent 396f5b40ce
commit b1e03bca0c
2 changed files with 112 additions and 37 deletions

View file

@ -15,27 +15,27 @@ POSIX PSE51 - Minimal
Units of Functionality Requirements:
+------------------------------+----------------+---------+
| Symbol | Support | Remarks |
+==============================+================+=========+
| POSIX_ADA_LANG_SUPPORT | No | |
+------------------------------+----------------+---------+
| `POSIX_C_LANG_JUMP`_ | Yes | |
+------------------------------+----------------+---------+
| `POSIX_C_LANG_SUPPORT`_ | 94/105 [#fn1]_ | |
+------------------------------+----------------+---------+
| `POSIX_DEVICE_IO`_ | Yes | |
+------------------------------+----------------+---------+
| `POSIX_FILE_LOCKING`_ | Yes | |
+------------------------------+----------------+---------+
| `POSIX_SINGLE_PROCESS`_ | 8/9 | |
+------------------------------+----------------+---------+
| `POSIX_THREADS_BASE`_ | Yes | |
+------------------------------+----------------+---------+
| `POSIX_THREADS_EXT`_ [#fn2]_ | Yes | |
+------------------------------+----------------+---------+
| `XSI_THREADS_EXT`_ | 2/4 | |
+------------------------------+----------------+---------+
+------------------------------+----------------+--------------------------+
| Symbol | Support | Remarks |
+==============================+================+==========================+
| POSIX_ADA_LANG_SUPPORT | No | |
+------------------------------+----------------+--------------------------+
| `POSIX_C_LANG_JUMP`_ | Yes | ``CONFIG_ARCH_SETJMP_H`` |
+------------------------------+----------------+--------------------------+
| `POSIX_C_LANG_SUPPORT`_ | 94/105 [#fn1]_ | |
+------------------------------+----------------+--------------------------+
| `POSIX_DEVICE_IO`_ | Yes | |
+------------------------------+----------------+--------------------------+
| `POSIX_FILE_LOCKING`_ | Yes | |
+------------------------------+----------------+--------------------------+
| `POSIX_SINGLE_PROCESS`_ | 8/9 | |
+------------------------------+----------------+--------------------------+
| `POSIX_THREADS_BASE`_ | Yes | |
+------------------------------+----------------+--------------------------+
| `POSIX_THREADS_EXT`_ [#fn2]_ | Yes | |
+------------------------------+----------------+--------------------------+
| `XSI_THREADS_EXT`_ | 2/4 | |
+------------------------------+----------------+--------------------------+
.. [#fn1] ``fenv.h`` related functions not supported.
.. [#fn2] In older revisions this was called ``XSI_THREAD_MUTEX_EXT``
@ -152,19 +152,19 @@ The Dedicated Realtime System Profile (PSE53) includes all features from PSE52 a
Units of Functionality Requirements:
+-----------------------------+---------+------------------+
| Symbol | Support | Remarks |
+=============================+=========+==================+
| POSIX_EVENT_MGMT [#fn8]_ | Yes | |
+-----------------------------+---------+------------------+
| `POSIX_MULTI_PROCESS`_ | 25/29 | |
+-----------------------------+---------+------------------+
| `POSIX_NETWORKING`_ | Yes | ``CONFIG_NET`` |
+-----------------------------+---------+------------------+
| `POSIX_PIPE`_ | Yes | ``CONFIG_PIPES`` |
+-----------------------------+---------+------------------+
| `POSIX_SIGNAL_JUMP`_ | No | |
+-----------------------------+---------+------------------+
+-----------------------------+---------+--------------------------+
| Symbol | Support | Remarks |
+=============================+=========+==========================+
| POSIX_EVENT_MGMT [#fn8]_ | Yes | |
+-----------------------------+---------+--------------------------+
| `POSIX_MULTI_PROCESS`_ | 25/29 | |
+-----------------------------+---------+--------------------------+
| `POSIX_NETWORKING`_ | Yes | ``CONFIG_NET`` |
+-----------------------------+---------+--------------------------+
| `POSIX_PIPE`_ | Yes | ``CONFIG_PIPES`` |
+-----------------------------+---------+--------------------------+
| `POSIX_SIGNAL_JUMP`_ | Yes | ``CONFIG_ARCH_SETJMP_H`` |
+-----------------------------+---------+--------------------------+
.. [#fn8] Deprecated in new revisions of POSIX.
Merged into ``POSIX_DEVICE_IO``.
@ -1614,9 +1614,9 @@ Signal Jump Functions:
+--------------------------------+---------+
| API | Support |
+================================+=========+
| siglongjmp() | No |
| siglongjmp() | Yes |
+--------------------------------+---------+
| sigsetjmp() | No |
| sigsetjmp() | Yes |
+--------------------------------+---------+
POSIX_C_LANG_WIDE_CHAR

View file

@ -38,14 +38,89 @@
#ifdef CONFIG_ARCH_SETJMP_H
# include <arch/setjmp.h>
#endif
# include <signal.h>
/****************************************************************************
* Type Definitions
****************************************************************************/
struct sigsetjmp_buf_s
{
jmp_buf jmpbuf; /* setjmp/longjmp buffer */
int savemask; /* Flag indicating if mask was saved */
sigset_t sigmask; /* Saved signal mask */
};
typedef struct sigsetjmp_buf_s sigjmp_buf[1];
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: siglongjmp
*
* Description:
* Restores the program's execution context previously saved by
* sigsetjmp().
*
* Input Parameters:
* env - a pointer to a sigjmp_buf structure
* val - return value for sigsetjmp()
*
* Returned Value:
* This function does not return anything explicitly.
*
* Assumptions:
*
****************************************************************************/
static inline_function void siglongjmp(sigjmp_buf env, int val)
{
if (env->savemask)
{
sigprocmask(SIG_SETMASK, &env->sigmask, NULL);
}
longjmp(env->jmpbuf, val);
}
/****************************************************************************
* Name: sigsetjmp
* int sigsetjmp(sigjmp_buf env, int savemask)
*
* Description:
* Saves the current program execution context including. It can
* optionally save the thread's current signal mask if the savemask
* parameter is non-zero.
*
* REVISIT:
* what if a signal is delivered between sigprocmask() and setjmp() ?
*
* Input Parameters:
* env - a pointer to a sigjmp_buf structure
* savemask - a flag used to determine if the signal mask is to be saved
*
* Returned Value:
* 0 sigsetjmp called directly
* non-0 we justed returned from a siglongjmp()
*
* Assumptions:
*
****************************************************************************/
#define sigsetjmp(env, _savemask) \
({ \
int _ret; \
env->savemask = _savemask; \
if (_savemask) \
{ \
sigprocmask(0, NULL, &env->sigmask); \
} \
_ret = setjmp(env->jmpbuf); \
_ret; \
})
#endif
#endif /* __INCLUDE_NUTTX_LIB_SETJMP_H */