In order to turn longjmp context-switch safe, it's necessary
to disable interrupts before modifying windowbase and windowstart.
Otherwise, after a context switch, windowstart and windowbase
would be different, leading to a wrongly set windowstart bit due to
longjmp writing it based on the windowbase before the context switch.
This corrupts the registers at the next window overflow reaching
that wrongly set bit.
*Background:*
This PR is related to an issue first observed on ESP-IDF
https://github.com/espressif/esp-idf/issues/5229 and it was, then,
checked on NuttX using a test application.
*The test application:*
To check if the problem affects ESP32, ESP32-S2 and ESP32-S3 on
NuttX, it was created an application based on:
https://en.cppreference.com/w/c/program/longjmp
The application creates 16 tasks (`#define NUMBER_OF_TASKS 16`)
that implements the following daemon:
```
static int setjmp_longjmp_daemon(int argc, char *argv[])
{
for (int i = 0; i < NUMBER_OF_TASKS * 2; i++)
{
jmp_buf env;
volatile int count = 0;
if (setjmp(env) != UINT16_MAX)
{
foo(&env, ++count);
}
}
sem_post(&g_sem);
return EXIT_SUCCESS;
}
```
The main function also initializes a semaphore to avoid application
exiting before tasks return successfully:
```
sem_init(&g_sem, 0, -NUMBER_OF_TASKS);
```
Finally, the round-robin interval was lowered to 1ms to raise the
chances of the longjmp being interrupted by a context switch
(`CONFIG_RR_INTERVAL=1).
This setup was able to reproduce the problem prior to this patch
being applied.