Skip to content

Conversation

@wangchdo
Copy link
Contributor

@wangchdo wangchdo commented Nov 20, 2025

Summary

Depends-on: apache/nuttx-apps#3217 (apps updated to disabled signals).

Currently, NuttX is being adopted increasingly on small embedded systems with tight resource constraints. Many of these systems do not require signal handling functionality or POSIX-related APIs.

With #17200 introducing scheduled sleep support, and #17204 replacing all signal-based sleep implementations in drivers and the filesystem with scheduled sleep, the dependency on signals has been significantly reduced.

Therefore, it is now a good time to provide an option for users to disable signal support entirely, allowing them to reduce code size and memory usage when signal functionality is not needed.

Impact

Add configuration support that allows users to disable signal functionality.

When signals are disabled, the related POSIX APIs—including sleep, usleep, kill, pkill, and pthread—will be disabled as well.

Testing

ostest is heavily dependent on POSIX APIs—including sleep, usleep, kill, pkill, and pthread. Therefore, to disable signal support, ostest must also be disabled until it is refactored to reduce its reliance on these APIs.

I have tested the signal-disable option on the fvp-armv8r-aarch32 board with ostest disabled, and the build succeeds and runs correctly.


NuttShell (NSH)
nsh> [ 0] Idle_Task: nx_start: CPU0: Beginning Idle Loop
nsh> 
nsh> uname -a
NuttX 0.0.0 cce68d3ead-dirty Nov 20 2025 14:43:39 arm fvp-armv8r-aarch32
nsh> 
nsh> 
nsh> help
help usage:  help [-v] [<cmd>]

    .           cd          exec        ls          pwd         truncate    
    [           cp          exit        mkdir       rm          uname       
    ?           cmp         expr        mkrd        rmdir       umount      
    alias       dirname     false       mount       set         unset       
    unalias     df          fdinfo      mv          source      uptime      
    basename    dmesg       free        pidof       test        xd          
    break       echo        help        printf      time        
    cat         env         hexdump     ps          true        

Builtin Apps:
    dd       nsh      sh       hello    
nsh> 
nsh> 
nsh> hello
[ 2] nsh_main: task_spawn: name=hello entry=0x2f554 file_actions=0x20009a88 attr=0x20009a8c argv=0x20009b48
[ 2] nsh_main: spawn_execattrs: Setting policy=2 priority=100 for pid=3
[ 2] nsh_main: nxtask_activate: hello pid=3,TCB=0x2000a0a0
Hello, World!!
[ 3] hello: nxtask_exit: hello pid=3,TCB=0x2000a0a0
nsh> 
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready                       0008176 0000888  10.8%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore          0008128 0000432   5.3%  hpwork 0x200002e0 0x20000330
    2     2     0 100 RR       Task      - Running                     0008152 0001840  22.5%  nsh_main
nsh> 

@github-actions github-actions bot added Arch: arm Issues related to ARM (32-bit) architecture Area: Drivers Drivers issues Area: File System File System issues Area: OS Components OS Components issues Size: M The size of the change in this PR is medium labels Nov 20, 2025
szafonimateusz-mi

This comment was marked as duplicate.

Copy link
Member

@raiden00pl raiden00pl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can't disable signals under POSIX. As much as I like this change and minimizing the footprint of NuttX, this change is against INVIOLABLES.md and it certainly can't be merged without more discussion in the community.

@github-actions github-actions bot added Arch: arm64 Issues related to ARM64 (64-bit) architecture Arch: avr Issues related to all AVR(8-bit or 32-bit) architectures Arch: mips Issues related to the MIPS architecture Arch: openrisc Issues related to the OpenRISC architecture Arch: renesas Issues related to the Renesas chips Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Arch: simulator Issues related to the SIMulator Arch: sparc Issues related to the SPARC architecture Arch: tricore Issues related to the TriCore architecture from Infineon labels Nov 20, 2025
cp15_cacheops.c)

if(NOT CONFIG_DISABLE_SIGNALS)
list(APPEND SRCS arm_schedulesigaction.c arm_sigdeliver.c)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not fix this comment yet.

@wangchdo
Copy link
Contributor Author

When signals are disabled, the related POSIX APIs—including sleep, usleep, kill, pkill, and pthread—will be disabled as well.

It's too limit that sleep/usleep can't be called when CONFIG_DISABLE_SIGNALS equals true, so I would suggest that this feature should be done by level:

  1. disable all signal related functionality like this pr
  2. disable signal function related to signal handler(callback), but keep other simple but frequnctly used function(e.g. wait/sigwait/ppoll).
  3. enable all signal functionality like before

Upon reconsideration, I prefer to only allow disabling all signal-related functionality, and re-implement the signal-dependent functions such as sleep()/usleep() using the newly added scheduler-based sleep APIs.

not only sleep/usleep, my real concern is the following functions:

pid_t wait(FAR int *stat_loc);
int   waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options);
pid_t waitpid(pid_t pid, FAR int *stat_loc, int options);

These functions is important to make nsh work correctly.

  1. This approach is clearer and safer. If we allow disabling only part of the signal subsystem, we would need to modify the implementations of the remaining signal functions.

But we just need skip the signal dispatch, no other change.

At the same time, we cannot guarantee that those functions will continue to behave exactly as before. Even worse, it becomes harder for users to understand the actual impact of partially disabling signal features.

The rule is simple, signal action doesn't work, but all other signal related feature work as before.

OK. If we disable only the signal action feature while keeping the rest of the signal subsystem intact, we still need to retain sigset_t sigprocmask, sigset_t sigwaitmask, and siginfo_t *sigunbinfo in struct tcb_s, and only remove sq_queue_t sigpendactionq and sq_queue_t sigpostedq. The remaining fields (sigprocmask, sigwaitmask, and sigunbinfo) occupy about 20 bytes in total, whereas sigpendactionq and sigpostedq together take about 16 bytes.

In addition, selectively disabling only the signal action functionality would require refactoring the implementation to clearly separate signal-action logic from the rest of the signal subsystem, which increases overall complexity.

But it may still be worthwhile, since disabling signal actions only can also improve task initialization/creation/switch/exit performance and reduce task stack usage.

I will look into the details and evaluate the pros and cons.

@wangchdo
Copy link
Contributor Author

wangchdo commented Nov 24, 2025

When signals are disabled, the related POSIX APIs—including sleep, usleep, kill, pkill, and pthread—will be disabled as well.

It's too limit that sleep/usleep can't be called when CONFIG_DISABLE_SIGNALS equals true, so I would suggest that this feature should be done by level:

  1. disable all signal related functionality like this pr
  2. disable signal function related to signal handler(callback), but keep other simple but frequnctly used function(e.g. wait/sigwait/ppoll).
  3. enable all signal functionality like before

Upon reconsideration, I prefer to only allow disabling all signal-related functionality, and re-implement the signal-dependent functions such as sleep()/usleep() using the newly added scheduler-based sleep APIs.

1. This approach is clearer and safer. If we allow disabling only part of the signal subsystem, we would need to modify the implementations of the remaining signal functions. At the same time, we cannot guarantee that those functions will continue to behave exactly as before. Even worse, it becomes harder for users to understand the actual impact of partially disabling signal features.

2. With PR [sched/sleep: add support for scheduling sleep #17200](https://github.com/apache/nuttx/pull/17200)  introducing scheduler-based sleep support, and PR [sched/sleep: replace all Signal-based sleep implement to Scheduled sleep #17204](https://github.com/apache/nuttx/pull/17204)  replacing all signal-based sleep implementations in drivers and the filesystem with scheduler-based versions, the overall dependency on signals has already been significantly reduced.

3. We can re-implement the libc sleep()/usleep() functions using the new API added by PR [sched/sleep: Add nxched_nanosleep() API #17368](https://github.com/apache/nuttx/pull/17368). This will even be more lightweight compared to the current signal-based wait mechanism.

Thank you @wangchdo :-)

  • I also think that when Signals are not here that means signals are not here (not just part of the signals).
  • Would it be possible that you implement sleep alternatives that would not depend on signals? That way we could compare full implementation on a working prototype, make some testing and measurements. Then decide if we move forward with that approach.

Yes, I plan to implement sleep alternatives with #17368

  • Would alternative sleep implementation also work when signals are enabled? Or two implementations would have to co-exist one with for signals and the other without signals?

I think the version without signals are better

  • What are risks and benefits here?

    • backward compatibility?
    • portability?
    • timing precision?
    • code size?
    • others?

I will show these data later

@cederom
Copy link
Contributor

cederom commented Nov 24, 2025

I guess apache/nuttx-apps#3217 by @extinguish is a prototype on @xiaoxiang781216 idea? :-)

@xiaoxiang781216
Copy link
Contributor

When signals are disabled, the related POSIX APIs—including sleep, usleep, kill, pkill, and pthread—will be disabled as well.

It's too limit that sleep/usleep can't be called when CONFIG_DISABLE_SIGNALS equals true, so I would suggest that this feature should be done by level:

  1. disable all signal related functionality like this pr
  2. disable signal function related to signal handler(callback), but keep other simple but frequnctly used function(e.g. wait/sigwait/ppoll).
  3. enable all signal functionality like before

Upon reconsideration, I prefer to only allow disabling all signal-related functionality, and re-implement the signal-dependent functions such as sleep()/usleep() using the newly added scheduler-based sleep APIs.

not only sleep/usleep, my real concern is the following functions:

pid_t wait(FAR int *stat_loc);
int   waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options);
pid_t waitpid(pid_t pid, FAR int *stat_loc, int options);

These functions is important to make nsh work correctly.

  1. This approach is clearer and safer. If we allow disabling only part of the signal subsystem, we would need to modify the implementations of the remaining signal functions.

But we just need skip the signal dispatch, no other change.

At the same time, we cannot guarantee that those functions will continue to behave exactly as before. Even worse, it becomes harder for users to understand the actual impact of partially disabling signal features.

The rule is simple, signal action doesn't work, but all other signal related feature work as before.

OK. If we disable only the signal action feature while keeping the rest of the signal subsystem intact, we still need to retain sigset_t sigprocmask, sigset_t sigwaitmask, and siginfo_t *sigunbinfo in struct tcb_s, and only remove sq_queue_t sigpendactionq and sq_queue_t sigpostedq. The remaining fields (sigprocmask, sigwaitmask, and sigunbinfo) occupy about 20 bytes in total, whereas sigpendactionq and sigpostedq together take about 16 bytes.

Yes, this is a compromise if we want to make the most POSIX application/driver work as before. In very simple case, the full disable may work well, but the partial disable may work better in many normal case.

In addition, selectively disabling only the signal action functionality would require refactoring the implementation to clearly separate signal-action logic from the rest of the signal subsystem, which increases overall complexity.

#17357 already finish the work, it isn't complex than the full disable:
a567855

But it may still be worthwhile, since disabling signal actions only can also improve task initialization/creation/switch/exit performance and reduce task stack usage.

here is the code save:


1. has passed ostest on CONFIG_DISABLE_SIGNALS=y
2. Here are the test results from our ARMv7-A platform:

When CONFIG_DISABLE_SIGNALS=n:
Binary size = 1,295,424 bytes, Used RAM = 37,980 bytes

When CONFIG_DISABLE_SIGNALS=y:
Binary size = 1,262,624 bytes, Used RAM = 37,852 bytes

This shows a reduction of 32,800 bytes in binary size and 128 bytes in RAM usage.

I will look into the details and evaluate the pros and cons.

@acassis
Copy link
Contributor

acassis commented Nov 24, 2025

When signals are disabled, the related POSIX APIs—including sleep, usleep, kill, pkill, and pthread—will be disabled as well.

It's too limit that sleep/usleep can't be called when CONFIG_DISABLE_SIGNALS equals true, so I would suggest that this feature should be done by level:

  1. disable all signal related functionality like this pr
  2. disable signal function related to signal handler(callback), but keep other simple but frequnctly used function(e.g. wait/sigwait/ppoll).
  3. enable all signal functionality like before

Upon reconsideration, I prefer to only allow disabling all signal-related functionality, and re-implement the signal-dependent functions such as sleep()/usleep() using the newly added scheduler-based sleep APIs.

1. This approach is clearer and safer. If we allow disabling only part of the signal subsystem, we would need to modify the implementations of the remaining signal functions. At the same time, we cannot guarantee that those functions will continue to behave exactly as before. Even worse, it becomes harder for users to understand the actual impact of partially disabling signal features.

2. With PR [sched/sleep: add support for scheduling sleep #17200](https://github.com/apache/nuttx/pull/17200)  introducing scheduler-based sleep support, and PR [sched/sleep: replace all Signal-based sleep implement to Scheduled sleep #17204](https://github.com/apache/nuttx/pull/17204)  replacing all signal-based sleep implementations in drivers and the filesystem with scheduler-based versions, the overall dependency on signals has already been significantly reduced.

3. We can re-implement the libc sleep()/usleep() functions using the new API added by PR [sched/sleep: Add nxsched_nanosleep() API #17368](https://github.com/apache/nuttx/pull/17368). This will even be more lightweight compared to the current signal-based wait mechanism.

Yes, these points your raised makes total sense.

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

Yes, this is a compromise if we want to make the most POSIX application/driver work as before. In very simple case, the full disable may work well, but the partial disable may work better in many normal case.

  1. The stage you described is just phase 1, because many signal-related APIs are retained and can be called normally, but signal functionality is missing. The changes in this PR will completely disable signal support.
  2. You have made numerous kernel modifications, yet no one is willing to submit them to the community. Every time @wangchdo contributes valuable code, you instruct individuals from Xiaomi to submit code with identical functionality. Similar issues exist with the hwtimer sched/hrtimer: add a high resolution timer module in sched and tricore porting to support hard real time cases #17065 and current PR. Why do you consistently challenge individual developers' submissions instead of assisting them in merging their work into the community? This is unfair—not just to individual developers, but to the entire developer community.

@xiaoxiang781216
Copy link
Contributor

  1. You have made numerous kernel modifications, yet no one is willing to submit them to the community. Every time @wangchdo contributes valuable code, you instruct individuals from Xiaomi to submit code with identical functionality. Similar issues exist with the hwtimer sched/hrtimer: add a high resolution timer module in sched and tricore porting to support hard real time cases #17065

I already point out the key problem of #17065, which must be fixed before I can approve it.
do you mean @Fix-Point 's pr: #17312, #17316, #17339 and #17338?
which is totally different from #17065.

and current PR.

Do you review #17352 and #17357 carefully? The detail is totally different as I already mention many time, so I don't repeat the difference here again.
Both approach has the pron. and cron., so I suggest to accept both by disabling the signal by level.

Why do you consistently challenge individual developers' submissions instead of assisting them in merging their work into the community? This is unfair—not just to individual developers, but to the entire developer community.

I review @wangchdo 's patch carefully and point out the place which need improve, once the problem get fixed, I always approve and his change. could you point out which patch I block it after the comment get addressed?

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

Do you review #17352 and #17357 carefully? The detail is totally different as I already mention many time, so I don't repeat the difference here again. Both approach has the pron. and cron., so I suggest to accept both by disabling the signal by level.

Of course, I am very familiar with the implementation of signal. In fact, I made similar changes in my internal branch and applied them to the real product. Therefore, after wangcd submitted the PR, I did not submit my part, but instead encouraged his commit to be successfully merged.

BTW I dare say that if wangcd hadn't submitted this commit, you guys wouldn't have submitted it either, right?

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

To reiterate, the current implementation of signals is highly unsafe because it borrows the context of the interrupted thread in its delivery logic. If a lock is held in the signal context, a serious bug will occur, which is why we prohibit the use of signals.

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

As @raiden00pl mentioned, many POSIX capabilities actually rely on the MMU implementation; for example, fork/signal cannot be fully replicated on devices without virtual addresses.

@acassis
Copy link
Contributor

acassis commented Nov 24, 2025

@xiaoxiang781216 I think we should have a Roadmap from Xiaomi of commits submission, to avoid issues like this. There are my useful things that Xiaomi people did and most still not updated to mainline yet, this causes people to waste their time re-implementing something that you guys already implemented (CMUX support is an example, fortunately the submitted implemented was for userspace and will not conflict with yours and you explained that didn't send it early because it had some issues).

Having this Roadmap will avoid:

  1. People wasting time reinventing the wheel
  2. Xiaomi devs will not have to modify their implementation or create internal patches to replace mainline with yours (worst case)
  3. The situation where someone submit a PR and yours dev submit the same PR to avoid their to enter in mainline that could cause situation 2.

I think it also will be useful to bring more awareness of what is coming next and community devs could engage on this process to improve that solution before that it submitted here.

@xiaoxiang781216
Copy link
Contributor

To reiterate, the current implementation of signals is highly unsafe because it borrows the context of the interrupted thread in its delivery logic. If a lock is held in the signal context, a serious bug will occur, which is why we prohibit the use of signals.

Signal just like a software interrupt, which has many limitation similar with you can't do many thing in hardware interrupt.
Spec has the dedicadated page declare which you can do and can't do in the signal handle:
https://man7.org/linux/man-pages/man7/signal-safety.7.html
https://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

To reiterate, the current implementation of signals is highly unsafe because it borrows the context of the interrupted thread in its delivery logic. If a lock is held in the signal context, a serious bug will occur, which is why we prohibit the use of signals.

Signal just like a software interrupt, which has many limitation similar with you can't do many thing in hardware interrupt. Spec has the dedicadated page declare which you can do and can't do in the signal handle: https://man7.org/linux/man-pages/man7/signal-safety.7.html https://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html

But our system does not follow this standard, especially VFS. On our real device, there was a bug caused by a POSIX library using read/write interfaces in the signal context, resulting in a deadlock, I merely wish to state that there is still a long way to go, which, of course, is irrelevant to the current topic.

@xiaoxiang781216
Copy link
Contributor

@xiaoxiang781216 I think we should have a Roadmap from Xiaomi of commits submission, to avoid issues like this. There are my useful things that Xiaomi people did and most still not updated to mainline yet, this causes people to waste their time re-implementing something that you guys already implemented (CMUX support is an example, fortunately the submitted implemented was for userspace and will not conflict with yours and you explained that didn't send it early because it had some issues).

Having this Roadmap will avoid:

  1. People wasting time reinventing the wheel
  2. Xiaomi devs will not have to modify their implementation or create internal patches to replace mainline with yours (worst case)
  3. The situation where someone submit a PR and yours dev submit the same PR to avoid their to enter in mainline that could cause situation 2.

Who come to first isn't important, we should select the implementation which is better and complete. If both implementation is valuable like cmux and signal, both should be merged. If some work need be done to merge both and the contributor doens't have time to do it, we can take time to do it and keep their credit.

I think it also will be useful to bring more awareness of what is coming next and community devs could engage on this process to improve that solution before that it submitted here.

yes, it will be better to have a place to share the roadmap.

@anchao
Copy link
Contributor

anchao commented Nov 24, 2025

Who come to first isn't important, we should select the implementation which is better and complete. If both implementation is valuable like cmux and signal, both should be merged. If some work need be done to merge both and the contributor doens't have time to do it, we can take time to do it and keep their credit.

If we have a better implementation that retains the individual developer's contribution, that's the best solution.

@acassis
Copy link
Contributor

acassis commented Nov 24, 2025

@xiaoxiang781216 I think we should have a Roadmap from Xiaomi of commits submission, to avoid issues like this. There are my useful things that Xiaomi people did and most still not updated to mainline yet, this causes people to waste their time re-implementing something that you guys already implemented (CMUX support is an example, fortunately the submitted implemented was for userspace and will not conflict with yours and you explained that didn't send it early because it had some issues).
Having this Roadmap will avoid:

  1. People wasting time reinventing the wheel
  2. Xiaomi devs will not have to modify their implementation or create internal patches to replace mainline with yours (worst case)
  3. The situation where someone submit a PR and yours dev submit the same PR to avoid their to enter in mainline that could cause situation 2.

Who come to first isn't important, we should select the implementation which is better and complete. If both implementation is valuable like cmux and signal, both should be merged. If some work need be done to merge both and the contributor doens't have time to do it, we can take time to do it and keep their credit.

I think it also will be useful to bring more awareness of what is coming next and community devs could engage on this process to improve that solution before that it submitted here.

yes, it will be better to have a place to share the roadmap.

I suggest using the Projects here in github to maps the Roadmap features. I should include the supposed date (Weeks of Year 1-52 or Q1-Q3 for distant/complex features). It could contains reference to existing open Issues, to explain what could be implemented in the coming PR.

@cederom
Copy link
Contributor

cederom commented Nov 24, 2025

  1. Okay I can see the @xiaoxiang781216 point, the "partial signal handling" is equivalent to disabling signals but least invasive to the current code. Full signal disable may be breaking existing code, but may result in smaller code? Lets discuss on the mailing list please before anything is merged - all pros and cons of both solutions I am sure we will find good way forward together maybe even something new :-)

  2. I agree fully with @acassis that we clearly miss the Xiaomi roadmap and sometimes we are surprised by incoming changes. I have created this dedicated "Project" where Xiaomi can put Issues and mark timeline. This will also clearly show Xiaomi support to NuttX and maybe motivate other companies to help us! @xiaoxiang781216 is the admin/manager of that app. It is called "Project" and its kind of sub-application here in GitHub it works on the existing Issues and PR just to organize them so its just king of organizer with a timeline plot and list of tasks/issues :-)

https://github.com/orgs/apache/projects/551

Currently nuttx is more and more used on small embedded systems
with limited resources. Some of these systems do not require
signal handling functionality or posix apis. This patch adds a
configuration option to disable signal handling in order to save
code size and memory.

Signed-off-by: Chengdong Wang <[email protected]>
Update architecture-level signal implementations to support optional signal disabling.

Signed-off-by: Chengdong Wang <[email protected]>
@wangchdo
Copy link
Contributor Author

wangchdo commented Nov 25, 2025

  1. Okay I can see the @xiaoxiang781216 point, the "partial signal handling" is equivalent to disabling signals but least invasive to the current code. Full signal disable may be breaking existing code, but may result in smaller code? Lets discuss on the mailing list please before anything is merged - all pros and cons of both solutions I am sure we will find good way forward together maybe even something new :-)
  2. I agree fully with @acassis that we clearly miss the Xiaomi roadmap and sometimes we are surprised by incoming changes. I have created this dedicated "Project" where Xiaomi can put Issues and mark timeline. This will also clearly show Xiaomi support to NuttX and maybe motivate other companies to help us! @xiaoxiang781216 is the admin/manager of that app. It is called "Project" and its kind of sub-application here in GitHub it works on the existing Issues and PR just to organize them so its just king of organizer with a timeline plot and list of tasks/issues :-)

https://github.com/orgs/apache/projects/551

As @anchao mentioned — and I completely agree — signals are disabled not only to reduce footprint, but also to improve safety.

To reiterate, the current signal implementation is inherently unsafe because it reuses the interrupted thread’s context during signal delivery. If a lock happens to be held when the signal handler runs, it can lead to severe issues, which is exactly why we prohibit the use of signals.

By the way, I work for Li Auto, a well-known Chinese new energy vehicle manufacturer that has sold more than 1.4 million cars. I am responsible for using NuttX to develop platform software for our vehicle control systems. We place great emphasis on both footprint and safety, and of course, safety is always our top priority.

We have also open-sourced our project, which is available at: https://gitee.com/haloos

@xiaoxiang781216
Copy link
Contributor

xiaoxiang781216 commented Nov 25, 2025

Apache NuttX RTOS: Xiaomi Contributions.

As @anchao mentioned, which I agree a lot: sigals are disabled not only for footprint but also for improving safety:

Again I don't against the full disable signal, but the full disable can't be enabled in many cases. The disable signal by level is more flexiable and useful, and let the end user enable the full or partial signal disable case by case.

To reiterate, the current implementation of signals is highly unsafe because it borrows the context of the interrupted thread in its delivery logic. If a lock is held in the signal context, a serious bug will occur, which is why we prohibit the use of signals.

Do you review @extinguish's patch? the partial signal disable remove all these unsafe part you mention, but keep the useful and safe component to improve the POSIX compliant.

By the way, I work for Li Auto, a well-known Chinese new energy vehicle manufacturer that has sold more than 1.4 million cars. I am responsible for using NuttX to develop platform software for our vehicle control systems.

It's great that more and more company develop the different solution on top of NuttX.

We place great emphasis on both footprint and safety, and of course, safety is always our top priority.

But, we need consider other application(e.g. IoT, embeded, AI..) too since many people use NuttX on these fields. Actually, we also use NuttX on many products including car, that's why I suggest to accept both approach.

@cederom
Copy link
Contributor

cederom commented Nov 25, 2025

Thank you guys! I have sent the update on the mailing list with this PR and apache/nuttx-apps#3217 (applications update signal disable).

What is the Signal Disable impact on the Drivers?

@xiaoxiang781216
Copy link
Contributor

xiaoxiang781216 commented Nov 25, 2025

Thank you guys! I have sent the update on the mailing list with this PR and apache/nuttx-apps#3217 (applications update signal disable).

What is the Signal Disable impact on the Drivers?

With the partial signal disable solution, driver which notify the event to userspace through signal still work if it uses sigwaitinfo(not signal handler) to receive the event, for example, button driver notification example work as before:
https://github.com/apache/nuttx/blob/master/include/nuttx/input/buttons.h#L77-L111
https://github.com/apache/nuttx-apps/blob/master/examples/buttons/buttons_main.c#L201-L256
but this example can't work with the full signal disable.
On the other hand, timer driver example can't work with both approach:
https://github.com/apache/nuttx-apps/blob/master/examples/timer/timer_main.c#L84-L97
since it receive the event through signal handler.

@cederom
Copy link
Contributor

cederom commented Nov 25, 2025

@cederom: Thank you guys! I have sent the update on the mailing list with this PR and apache/nuttx-apps#3217 (applications update signal disable).
What is the Signal Disable impact on the Drivers?

@xiaoxiang781216: With the partial signal disable solution, driver which notify the event to userspace through signal still work if it uses sigwaitinfo(not signal handler) to receive the event, for example, button driver notification example work as before: https://github.com/apache/nuttx/blob/master/include/nuttx/input/buttons.h#L77-L111 https://github.com/apache/nuttx-apps/blob/master/examples/buttons/buttons_main.c#L201-L256 but this example can't work with the full signal disable. On the other hand, timer driver example can't work with both approach: https://github.com/apache/nuttx-apps/blob/master/examples/timer/timer_main.c#L84-L97 since it receive the event through signal handler.

@xiaoxiang781216 thank you! :-)

So it looks like we have two general options and approaches, is this correct?

  1. Partial Signals disable:
    • Safer and requires almost no modifications of existing code.
    • Some things may be impacted (which one and how?).
    • Moderate firmware size decrease (how much?).
    • Option to decrease firmware size but with some impact to try-out-yourself (but why needed at all?).
  2. Full Signals disable:
    • Requires a lot of code modification, so better to assume special uses cases only with no other NuttX stuff operational.
    • Existing code is impacted (almost all).
    • Biggest possible firmware size decrease (18296->7492 2.44x Flash save, 1236->928 1.32x RAM save).
    • Option to trim down firmware size with use-at-your-own-risk aka i-know-what-i-am-doing approach.

Maybe we can consider both options as possible or only one that offers biggest benefit at the lowest cost?

  • I just wonder how to organize this update so we don't flip all existing code upside down and now to create additional tons of work. Each update in each place is a potential problem later on.
  • The partial signal disable option seems least invasive and not much places need an update right? Do we exactly know what is impacted (rtos, apps, drivers) and what would be the benefit (i.e. 50% of the firmware size decrease)? If its 50% size decrease then it may be worth the work, if 10% then maybe not worth it?
  • The full signal disable is for extreme cases where people need to assume no other standard NuttX stuff will work but they want to keep the NuttX ecosystem while writing most of things on their own including applications and drivers?

@xiaoxiang781216
Copy link
Contributor

xiaoxiang781216 commented Nov 25, 2025

@cederom: Thank you guys! I have sent the update on the mailing list with this PR and apache/nuttx-apps#3217 (applications update signal disable).
What is the Signal Disable impact on the Drivers?

@xiaoxiang781216: With the partial signal disable solution, driver which notify the event to userspace through signal still work if it uses sigwaitinfo(not signal handler) to receive the event, for example, button driver notification example work as before: https://github.com/apache/nuttx/blob/master/include/nuttx/input/buttons.h#L77-L111 https://github.com/apache/nuttx-apps/blob/master/examples/buttons/buttons_main.c#L201-L256 but this example can't work with the full signal disable. On the other hand, timer driver example can't work with both approach: https://github.com/apache/nuttx-apps/blob/master/examples/timer/timer_main.c#L84-L97 since it receive the event through signal handler.

@xiaoxiang781216 thank you! :-)

So it looks like we have two general options and approaches, is this correct?

Yes.

  1. Partial Signals disable:

    • Safer and requires almost no modifications of existing code.
    • Some things may be impacted (which one and how?).

sigaction/signal and sigpending can't be used anymore, all othe sigxxx function work as before

https://github.com/apache/nuttx/pull/17357/files#diff-b2638ab8551b8ccdc2caf1d064e4dd07ea1bcd1405a562591213d6ed10969594R175
https://github.com/apache/nuttx/pull/17357/files#diff-b2638ab8551b8ccdc2caf1d064e4dd07ea1bcd1405a562591213d6ed10969594R178

  • Moderate firmware size decrease (how much?).

here is the number from: #17357

When CONFIG_DISABLE_SIGNALS=n:
Binary size = 1,295,424 bytes, Used RAM = 37,980 bytes

When CONFIG_DISABLE_SIGNALS=y:
Binary size = 1,262,624 bytes, Used RAM = 37,852 bytes

This shows a reduction of 32,800 bytes in binary size and 128 bytes in RAM usage.
  • Option to decrease firmware size but with some impact to try-out-yourself (but why needed at all?).
  1. Full Signals disable:

    • Requires a lot of code modification, so better to assume special uses cases only with no other NuttX stuff operational.
    • Existing code is impacted (almost all).
    • Biggest possible firmware size decrease (18296->7492 2.44x Flash save, 1236->928 1.32x RAM save).
    • Option to trim down firmware size with use-at-your-own-risk aka i-know-what-i-am-doing approach.

disable signal is just an option, just like many DISABLE_XXX option here:
https://github.com/apache/nuttx/blob/master/sched/Kconfig#L18-L45
if you don't call these api, you can just disable it to save your code size. If you aren't sure whether you really use these api, enabling DISABLE_XXX in your defconfig, linker will report the result to you.

Maybe we can consider both options as possible or only one that offers biggest benefit at the lowest cost?

  • I just wonder how to organize this update so we don't flip all existing code upside down and now to create additional tons of work. Each update in each place is a potential problem later on.
  • The partial signal disable option seems least invasive and not much places need an update right? Do we exactly know what is impacted (rtos, apps, drivers) and what would be the benefit (i.e. 50% of the firmware size decrease)? If its 50% size decrease then it may be worth the work, if 10% then maybe not worth it?
  • The full signal disable is for extreme cases where people need to assume no other standard NuttX stuff will work but they want to keep the NuttX ecosystem while writing most of things on their own including applications and drivers?

It's just a simple change(exclude the signal related functions from build), and the wrong config will report the link error, not runtime error. I can't understand why do we spend so much time to consider the meaningless case. If your driver or apps use signal, don't enable CONFIG_DISABLE_SIGNALS, that's it.
So I would suggest you to review the change to understand what really happen instead.

@acassis
Copy link
Contributor

acassis commented Nov 25, 2025

Thank you guys! I have sent the update on the mailing list with this PR and apache/nuttx-apps#3217 (applications update signal disable).
What is the Signal Disable impact on the Drivers?

With the partial signal disable solution, driver which notify the event to userspace through signal still work if it uses sigwaitinfo(not signal handler) to receive the event, for example, button driver notification example work as before: https://github.com/apache/nuttx/blob/master/include/nuttx/input/buttons.h#L77-L111 https://github.com/apache/nuttx-apps/blob/master/examples/buttons/buttons_main.c#L201-L256 but this example can't work with the full signal disable. On the other hand, timer driver example can't work with both approach: https://github.com/apache/nuttx-apps/blob/master/examples/timer/timer_main.c#L84-L97 since it receive the event through signal handler.

I think that is a good feature if we could still getting working the buttons, zerocross and other drivers that depends on signal. @xiaoxiang781216 @wangchdo @anchao I think most of people that will decide it doesn't have the complete understanding how signals works on NuttX.

I suggest creating a Documentation explains how do signals work on NuttX. It could be an overview, but should explain details as @anchao commented about signals on NuttX using the ISR context, etc. Also it should explain how the partial disable works.

@xiaoxiang781216 @wangchdo is it possible to have more two disable levels: partial (where buttons, etc, works) and full (not signal at all, buttons will not work) ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Arch: arm64 Issues related to ARM64 (64-bit) architecture Arch: avr Issues related to all AVR(8-bit or 32-bit) architectures Arch: mips Issues related to the MIPS architecture Arch: openrisc Issues related to the OpenRISC architecture Arch: renesas Issues related to the Renesas chips Arch: risc-v Issues related to the RISC-V (32-bit or 64-bit) architecture Arch: simulator Issues related to the SIMulator Arch: sparc Issues related to the SPARC architecture Arch: tricore Issues related to the TriCore architecture from Infineon Arch: x86 Issues related to the x86 architecture Arch: x86_64 Issues related to the x86_64 architecture Arch: xtensa Issues related to the Xtensa architecture Arch: z16 Issues related to the Z16 architecture Arch: z80 Issues related to the Z80 architecture Area: Drivers Drivers issues Area: File System File System issues Area: OS Components OS Components issues Size: L The size of the change in this PR is large Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants