From 5bb496bfeec16c91cbfa938c8c2b521b22fd039b Mon Sep 17 00:00:00 2001
From: Gregory Nutt
Date: Thu, 2 Jan 2020 21:26:57 -0600
Subject: [PATCH 1/2] Documentation/NuttXCCodingStandard.html: Remove
requirement to decorate ignored returned values with (void).
---
Documentation/NuttXCCodingStandard.html | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Documentation/NuttXCCodingStandard.html b/Documentation/NuttXCCodingStandard.html
index 2b187b50fc110..74522f2ed2710 100644
--- a/Documentation/NuttXCCodingStandard.html
+++ b/Documentation/NuttXCCodingStandard.html
@@ -87,7 +87,7 @@ Table of Contents
NuttX C Coding Standard
- Last Updated: July 6, 2019
+ Last Updated: January 2, 2020
@@ -2182,9 +2182,8 @@
Checking Return Values.
Callers of internal OS functions should always check return values for an error.
At a minimum, a debug statement should indicate that an error has occurred.
- The calling logic intentionally ignores the returned value, then the function return value should be explicitly cast to (void) to indicate that the return value is intentionally ignored.
- An exception of for standard functions for which people have historically ignored the returned values, such as printf() or close.
- All calls to malloc or realloc must be checked for failures to allocate memory.
+ Ignored return values are always suspicious.
+ All calls to malloc or realloc, in particular, must be checked for failures to allocate memory to avoid use of NULL pointers.
From 99c7a464e4c0b7c6a0354a1711685021e2db92e1 Mon Sep 17 00:00:00 2001
From: Gregory Nutt
Date: Fri, 3 Jan 2020 09:13:05 -0600
Subject: [PATCH 2/2] TODO: Update TODO list
---
TODO | 80 ++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 53 insertions(+), 27 deletions(-)
diff --git a/TODO b/TODO
index 7a1728743ba2a..029a46fa7505a 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated November 21, 2019)
+NuttX TODO List (Last updated January 3, 2019)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -589,32 +589,58 @@ o SMP
can that occur? I think it can occur in the following
situation:
- CPU0 - Task A is running.
- - The CPU0 IDLE task is the only other task in the
- CPU0 ready-to-run list.
- CPU1 - Task B is running.
- - Task C is blocked but remains in the g_assignedtasks[]
- list because of a CPU affinity selection. Task C
- also holds the critical section which is temporarily
- relinquished because Task C is blocked by Task B.
- - The CPU1 IDLE task is at the end of the list.
-
- Actions:
- 1. Task A/CPU 0 takes the critical section.
- 2. Task B/CPU 1 suspends waiting for an event
- 3. Task C is restarted.
-
- Now both Task A and Task C hold the critical section.
-
- This problem has never been observed, but seems to be a
- possibility. I believe it could only occur if CPU affinity
- is used (otherwise, tasks will pend must as when pre-
- emption is disabled).
-
- A proper solution would probably involve re-designing how
- CPU affinity is implemented. The CPU1 IDLE thread should
- more appropriately run, but cannot because the Task C TCB
- is in the g_assignedtasks[] list.
+ The log below was reported is Nuttx running on two cores
+ Cortex-A7 architecture in SMP mode. You can notice see that
+ when sched_addreadytorun() was called, the g_cpu_irqset is 3.
+
+ sched_addreadytorun: irqset cpu 1, me 0 btcbname init, irqset 1 irqcount 2.
+ sched_addreadytorun: sched_addreadytorun line 338 g_cpu_irqset = 3.
+
+ This can happen, but only under a very certain condition.
+ g_cpu_irqset only exists to support this certain condition:
+
+ a. A task running on CPU 0 takes the critical section. So
+ g_cpu_irqset == 0x1.
+
+ b. A task exits on CPU 1 and a waiting, ready-to-run task
+ is re-started on CPU 1. This new task also holds the
+ critical section. So when the task is re-restarted on
+ CPU 1, we than have g_cpu_irqset == 0x3
+
+ So we are in a very perverse state! There are two tasks
+ running on two different CPUs and both hold the critical
+ section. I believe that is a dangerous situation and there
+ could be undiscovered bugs that could happen in that case.
+ However, as of this moment, I have not heard of any specific
+ problems caused by this weird behavior.
+
+ A possible solution would be to add a new task state that
+ would exist only for SMP.
+
+ - Add a new SMP-only task list and state. Say,
+ g_csection_wait[]. It should be prioritized.
+ - When a task acquires the critical section, all tasks in
+ g_readytorun[] that need the critical section would be
+ moved to g_csection_wait[].
+ - When any task is unblocked for any reason and moved to the
+ g_readytorun[] list, if that unblocked task needs the
+ critical section, it would also be moved to the
+ g_csection_wait[] list. No task that needs the critical
+ section can be in the ready-to-run list if the critical
+ section is not available.
+ - When the task releases the critical section, all tasks in
+ the g_csection_wait[] needs to be moved back to
+ g_readytorun[].
+ - This may result in a context switch. The tasks should be
+ moved back to g_readytorun[] higest priority first. If a
+ context switch occurs and the critical section to re-taken
+ by the re-started task, the lower priority tasks in
+ g_csection_wait[] must stay in that list.
+
+ That is really not as much work as it sounds. It is
+ something that could be done in 2-3 days of work if you know
+ what you are doing. Getting the proper test setup and
+ verifying the cahnge would be the more difficult task.
Status: Open
Priority: Unknown. Might be high, but first we would need to confirm