From f39b15d28b041eb7a47697de9a7698bcd0f43992 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Sat, 19 Sep 2026 14:26:05 -0400 Subject: [PATCH] sched/pthread: Implement pthread_sigqueue Implements the pthread_sigqueue Linux extension to pthreads. Follows a similar implementation to sigqueue, except targeting a specific thread through nxsig_dispatch. Signed-off-by: Matteo Golin --- arch/sim/src/nuttx-names.in | 3 +- include/signal.h | 1 + libs/libc/libc.csv | 1 + sched/pthread/CMakeLists.txt | 1 + sched/pthread/Make.defs | 2 +- sched/pthread/pthread_sigqueue.c | 81 ++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 sched/pthread/pthread_sigqueue.c diff --git a/arch/sim/src/nuttx-names.in b/arch/sim/src/nuttx-names.in index 3c7f1caa744..9449f9e33f2 100644 --- a/arch/sim/src/nuttx-names.in +++ b/arch/sim/src/nuttx-names.in @@ -83,7 +83,7 @@ NXSYMBOLS(lstat) NXSYMBOLS(malloc) NXSYMBOLS(malloc_size) NXSYMBOLS(malloc_usable_size) -NXSYMBOLS(memchr) +NXSYMBOLS(memchr) NXSYMBOLS(memcpy) NXSYMBOLS(memfd_create) NXSYMBOLS(mkdir) @@ -122,6 +122,7 @@ NXSYMBOLS(pthread_setspecific) #endif NXSYMBOLS(pthread_self) NXSYMBOLS(pthread_sigmask) +NXSYMBOLS(pthread_sigqueue) NXSYMBOLS(puts) NXSYMBOLS(read) NXSYMBOLS(readdir) diff --git a/include/signal.h b/include/signal.h index 392ab270154..99bade0f945 100644 --- a/include/signal.h +++ b/include/signal.h @@ -490,6 +490,7 @@ int siginterrupt(int signo, int flag); int pthread_kill(pthread_t thread, int sig); int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); +int pthread_sigqueue(pthread_t thread, int sig, const union sigval value); #undef EXTERN #ifdef __cplusplus diff --git a/libs/libc/libc.csv b/libs/libc/libc.csv index 2cf17ac4b15..da894be284f 100644 --- a/libs/libc/libc.csv +++ b/libs/libc/libc.csv @@ -241,6 +241,7 @@ "pthread_self","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","pthread_t","void" "pthread_setname_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","const char *" "pthread_setspecific","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && CONFIG_TLS_NELEM > 0","int","pthread_key_t","FAR const void *" +"pthread_sigqueue","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","int","const union sigval" "pthread_yield","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","void" "puts","stdio.h","defined(CONFIG_FILE_STREAM)","int","FAR const IPTR char *" "putwc","wchar.h","defined(CONFIG_FILE_STREAM)","wint_t","wchar_t","FAR FILE *" diff --git a/sched/pthread/CMakeLists.txt b/sched/pthread/CMakeLists.txt index 93184c7ec94..3ce9bb09c11 100644 --- a/sched/pthread/CMakeLists.txt +++ b/sched/pthread/CMakeLists.txt @@ -30,6 +30,7 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_getschedparam.c pthread_setschedparam.c pthread_sigmask.c + pthread_sigqueue.c pthread_cancel.c pthread_completejoin.c pthread_findjoininfo.c diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index 5cf99995dd2..8e28702ac1a 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -24,7 +24,7 @@ ifneq ($(CONFIG_DISABLE_PTHREAD),y) CSRCS += pthread_create.c pthread_exit.c pthread_join.c pthread_detach.c CSRCS += pthread_getschedparam.c pthread_setschedparam.c -CSRCS += pthread_sigmask.c pthread_cancel.c +CSRCS += pthread_sigmask.c pthread_sigqueue.c pthread_cancel.c CSRCS += pthread_completejoin.c pthread_findjoininfo.c CSRCS += pthread_release.c pthread_setschedprio.c diff --git a/sched/pthread/pthread_sigqueue.c b/sched/pthread/pthread_sigqueue.c new file mode 100644 index 00000000000..2819e00dff5 --- /dev/null +++ b/sched/pthread/pthread_sigqueue.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * sched/pthread/pthread_sigqueue.c + * + * SPDX-License-Identifer: Apache-2.0 + * + * 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 + +#include +#include +#include +#include + +#include + +#include "sched/sched.h" +#include "signal/signal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int pthread_sigqueue(pthread_t thread, int sig, const union sigval value) +{ +#ifdef CONFIG_SCHED_HAVE_PARENT + FAR struct tcb_s *rtcb = this_task(); +#endif + siginfo_t info; + int err; + + sinfo("tid=%d sig=%d value=%d\n", thread, sig, value.sival_int); + + /* Check if signal is valid */ + + if (!GOOD_SIGNO(sig)) + { + return EINVAL; + } + + /* Create the siginfo structure */ + + info.si_signo = sig; + info.si_code = SI_QUEUE; + info.si_errno = OK; + info.si_value = value; +#ifdef CONFIG_SCHED_HAVE_PARENT + info.si_pid = rtcb->pid; + info.si_status = OK; +#endif + info.si_user = NULL; /* Will be set in sig_dispatch.c */ + + /* Send the signal */ + + err = nxsig_dispatch((pid_t)thread, &info, true); + if (err < 0) + { + return -err; + } + + return 0; +}