Add the blank line required by nxstyle after the SMP-local declaration in
the profiling timer handler.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Round the usable profiling buffer size down to complete unsigned short
counters before deriving highpc. Without this, an odd-sized buffer can
allow the timer handler to increment a counter that extends one byte past
the buffer.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
When waitpid(-1) finds an exited child in the retained status list, honor
WNOWAIT instead of unconditionally removing and freeing the child entry.
This makes the any-child path consistent with the specific-PID and SIGCHLD
paths.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
The base firmware and an FDPIC module disagree about what a function
pointer is. Firmware is not built FDPIC, so to it a pointer is a code
address and it branches there. A module passes the address of a two word
descriptor instead, because its code and data are placed independently and
a bare code address would leave the callee unable to find its own data. A
firmware routine that takes a callback therefore branches into the
module's data segment and faults.
So the ten entry points that can be handed a callback by a module resolve
the descriptor before storing or branching to it: qsort, bsearch,
pthread_create, signal, sigaction, task_create and task_create_with_stack,
task_spawn, pthread_once, scandir, and mq_notify and timer_create with
SIGEV_THREAD.
Which one resolves matters as much as that one does. Resolving twice would
take an already resolved code address for a descriptor and read two words
from the instruction stream, so each pointer is resolved exactly once, at
the outermost point that sees it. signal() passes its argument through
untouched because sigaction() and then nxsig_action() will resolve it,
which covers a module calling sigaction() directly as well. qsort() is
split so that the public entry resolves and the recursive implementation
does not. scandir() resolves its filter but not its comparison function,
which it hands to qsort().
Whether a caller is a module at all is asked of the PIC base register,
which up_initial_state() sets only for a task that has a D-Space. A plain
kernel task therefore reads zero and is left alone.
SIGEV_THREAD is the case the register cannot answer, because the callback
runs later on a work queue worker that carries no module's base at all.
The base is captured instead when the notification is registered, in the
module's own context, and installed around the call.
All of it is behind CONFIG_FDPIC, which defaults off. Built for
mps3-an547:picostest both ways; with it off the entry points compile to
what they were.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
nxsem_init(), nxsem_destroy(), nxmutex_init(), nxmutex_destroy(),
nxrmutex_init() and nxrmutex_destroy() cannot fail, so promising a
negated errno value on failure documents an error that is never returned.
The coding standard asks the returned value description to identify all
error values of a function, and there are none, so state that OK is
always returned.
Follows "sched/semaphore: Remove the return value check of
nxsem_init/nxmutex_init", which removed the last checks of these values.
Assisted-by: DeepSeek Harness:deepseek-flash
Signed-off-by: rongbaichuan <rongbaichuan1027@163.com>
nxsem_init(), nxsem_destroy(), nxmutex_init() and nxmutex_destroy()
always return OK, so checking the result only leaves dead code: the
compiler cannot remove it, because these are cross-translation-unit calls
and the nxrmutex_destroy() test is duplicated into every inlined call
site.
Apply the convention already established in commit a47a36bc5b (PR #7473)
to the two definitions which still test the value and to the 54 remaining
call sites. No signature or prototype is changed.
Testing: stm32f103-minimum:nsh builds with -Os without new warnings.
Assisted-by: DeepSeek Harness:deepseek-flash
Signed-off-by: rongbaichuan <rongbaichuan1027@163.com>
Increase MOD_LINELEN from 64 to 256 so complete /proc/modules lines fit the formatting buffer on 64-bit targets.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Add the required blank line between the intcount declaration and the
following statement.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
irq_callback() passed snprintf()'s would-have-written length to
procfs_memcpy(). If an IRQ line exceeded IRQ_LINELEN, the copy could read
beyond the formatting buffer.
Use procfs_snprintf() so the copy is limited to the bytes actually written.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
modprocfs_callback() formatted each line into line[64] with snprintf()
and passed snprintf()'s return value, the length the line would have
had, to procfs_memcpy() as the source length. A module name longer
than a few characters therefore made the copy read past the end of
the line buffer and hand kernel heap memory to the reader, and grew
totalsize by the difference.
Use procfs_snprintf(), which returns the length actually written, as
the other procfs entries already do.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
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 <matteo.golin@gmail.com>
Allocate the new handler node independently of the initial chain
conversion so handlers beyond the second are appended instead of silently
dropped. Delay vector conversion until both required nodes are available
to avoid leaving a partially constructed chain on allocation failure.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Store the jail as an absolute path on the task group, copy it to
children, and free it when the last member leaves.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
1. nxsched_process_timer: call clock_update_wall_time() under
CONFIG_CLOCK_TIMEKEEPING so that wall time is updated on timer
events during tickless operation.
2. clock_timekeeping_get_wall_time: call clock_update_wall_time()
before sampling the base and counter.
3. clock_timekeeping: allow overriding NTP_MAX_ADJUST with
CONFIG_CLOCK_ADJTIME_SLEWLIMIT_PPM if configured.
4. Use clock_t consistently for counter values in clock_timekeeping.c.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Convert failures from CLOCK_FD lookup and PTP_CLOCK_GETRES into the public
clock_getres() convention of returning ERROR and setting errno. This keeps
dynamic PTP clocks consistent with the other clock_getres() error paths.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Move the critical-monitor update after PID hash entry validation and keep
the scheduler critical section held so the TCB remains stable. Invalid or
stale PIDs now return -ESRCH instead of passing a NULL TCB to
nxsched_update_critmon().
Also add the declaration spacing required by nxstyle in the modified file.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Move RTC synchronization outside the non-timekeeping branch so setting
CLOCK_REALTIME also updates the RTC when CONFIG_CLOCK_TIMEKEEPING is
enabled. This prevents corrected wall time from reverting to an older RTC
value after restart.
Preserve the existing low-priority work queue path for RTC drivers that may
block while updating hardware.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Remove pending IRQ work before clearing its callback state, and guard the
worker callback against a concurrent detach. This prevents detached worked
IRQs from invoking a NULL function pointer.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Only call kthread_delete for a valid positive PID and always clear the IRQ
thread slot afterward. This makes detach on an unused IRQ, including a
repeated detach, a safe no-op instead of deleting the calling task.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Return ENOMEM and leave the IRQ detached when no custom work queue can be
created or all queue slots are occupied. Also release the queue mutex on
the full-table path and avoid caching a failed queue creation.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Store the thread PID only after kthread_create succeeds. This prevents a
negative error value from making subsequent attachment attempts fail with
EINVAL after a transient thread creation failure.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
strlcpy() was given sizeof(tcb->name), i.e. CONFIG_TASK_NAME_SIZE + 1,
but the documented caller contract is a buffer of CONFIG_TASK_NAME_SIZE
bytes (include/sys/prctl.h). When a task name is exactly
CONFIG_TASK_NAME_SIZE chars (the normal result of nxtask_setup_name()
truncation), the terminating NUL lands one byte past the caller buffer.
Pass CONFIG_TASK_NAME_SIZE to strlcpy() so the copy is truncated
in-bounds, and drop the stale forced-NUL line left over from the strncpy
era (it ran after the overflow had already happened).
Before:
```
guard byte placed right after a CONFIG_TASK_NAME_SIZE caller buffer
reads 0x00 (expected 0xAA) after the call: strlcpy writes its
terminating NUL one byte past the buffer when the task name is exactly
CONFIG_TASK_NAME_SIZE chars.
```
After:
```
strlcpy(name, tcb->name, CONFIG_TASK_NAME_SIZE) writes at most
CONFIG_TASK_NAME_SIZE bytes; the caller buffer stays intact.
```
Testing:
Simulated (sim:nsh, CONFIG_TASK_NAME_SIZE=31).
Build and run:
```
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake --build build -j$(nproc)
echo hello | ./build/nuttx
```
then run "hello" at the NSH prompt.
The test was carried by apps/examples/hello/hello_main.c (scratch only,
not part of this commit); its diff:
```
--- a/examples/hello/hello_main.c
+++ b/examples/hello/hello_main.c
@@ -24,6 +24,8 @@
#include <nuttx/config.h>
#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
/****************************************************************************
* Public Functions
@@ -35,6 +37,55 @@
int main(int argc, FAR char *argv[])
{
+ /* Longest-legal task name: exactly CONFIG_TASK_NAME_SIZE chars, the
+ * normal result of nxtask_setup_name() truncation.
+ */
+
+ static const char longname[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ /* Caller buffer per the documented prctl(PR_GET_NAME) contract, with a
+ * guard byte immediately after it to detect the 1-byte overflow.
+ */
+
+ struct
+ {
+ char buf[CONFIG_TASK_NAME_SIZE];
+ volatile unsigned char guard;
+ } s;
+
+ _Static_assert(sizeof(longname) - 1 > CONFIG_TASK_NAME_SIZE,
+ "test name must exceed CONFIG_TASK_NAME_SIZE");
+
printf("Hello, World!!\n");
+ printf("prctl test: CONFIG_TASK_NAME_SIZE=%d\n", CONFIG_TASK_NAME_SIZE);
+
+ s.guard = 0xaa;
+ s.buf[0] = '\0';
+
+ if (prctl(PR_SET_NAME, (unsigned long)longname) != 0)
+ {
+ printf("prctl test: PR_SET_NAME failed\n");
+ return 1;
+ }
+
+ if (prctl(PR_GET_NAME, (unsigned long)s.buf) != 0)
+ {
+ printf("prctl test: PR_GET_NAME failed\n");
+ return 1;
+ }
+
+ printf("prctl test: guard=0x%02x (expected 0xaa), name len=%zu, "
+ "last char=0x%02x\n",
s.guard, strlen(s.buf), (unsigned char)s.buf[strlen(s.buf)]);
+
+ if (s.guard != 0xaa)
+ {
+ printf("prctl test: FAIL - terminating NUL written 1 byte past "
+ "the caller buffer\n");
+ return 1;
+ }
+
+ printf("prctl test: PASS - caller buffer intact\n");
return 0;
}
```
Before the fix:
```
prctl test: guard=0x00 (expected 0xaa), name len=30, last char=0x00
prctl test: FAIL - terminating NUL written 1 byte past the caller buffer
```
After the fix:
```
prctl test: guard=0xaa (expected 0xaa), name len=30, last char=0x00
prctl test: PASS - caller buffer intact
```
Assisted-by: Claude Code (GLM-5.3) <claude@anthropic.com>
Signed-off-by: Junbo Zheng <zhengjunbo1@xiaomi.com>
work_cancel() used to return -ENOENT when the work structure was not
in the queue, and callers depend on that: aio_cancel() tears down the
AIO container (file_put() + aioc_free()) only when work_cancel()
reports success, because a work item that is not queued may already be
executing on a worker thread (see the comment in fs/aio/aio_cancel.c).
Since commit 6f72f5481d ("sched/wqueue: Refactor delayed and periodical
workqueue") work_cancel() returns OK unconditionally, and commit
d2e01b9055 ("sched/wqueue: harden custom queue lifecycle") kept that
behaviour and dropped -ENOENT from the function documentation. Under
SMP the LTP aio_cancel tests then free the aio container and its file
while the lpwork thread is still executing aio_write_worker() on it,
which ends in a page fault in file_write() (f_inode == NULL) and a
panic.
Return -ENOENT again when the work is not queued, and document it.
For the synchronous variant "not queued" alone does not tell whether
the callback is running: the worker scan does, so report OK when a
running callback was found and waited for, and -ENOENT only when the
work was neither queued nor running.
Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
Clamp each wall-clock adjustment in both positive and negative directions, then subtract the applied amount from the remaining adjustment. This makes adjtime converge to zero and prevents large negative adjustments from slewing the clock in the wrong direction.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
CLOCK_TIMEKEEPING already provides a software-based adjtime implementation. Exclude the generic adjtime state and entry point when timekeeping is enabled, while retaining clock_adjtime support for PTP clocks.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
spawn_execattrs() discards the return value from nxsched_set_scheduler(). As a result, an invalid scheduling policy or parameter is silently ignored and the spawn operation continues with the original scheduling configuration.
Store and return the result from nxsched_set_scheduler() so that the caller can tear down the child task when applying the requested scheduler attributes fails. Update the function comments to describe the existing error return behavior.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Sporadic scheduling parameters are processed independently by sched_setparam(), sched_setscheduler(), and pthread_create(). The three paths currently validate different subsets of the parameters.
In particular, pthread_create() does not validate sched_ss_max_repl and only requires the replenishment period to be greater than the budget, while the scheduler interfaces enforce the implementation's 50 percent duty-cycle limit.
Add nxsched_validate_sporadic() to validate the common parameters and convert the replenishment period and budget to ticks. Use it from all paths that directly initialize or update sporadic scheduler state.
Express the duty-cycle check using division to avoid overflow when doubling a clock_t value.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
nxsched_set_param() applied the sporadic parameters and restarted the
replenishment timer in set_sporadic_param() before nxsched_reprioritize()
rejected an out-of-range priority with EINVAL, leaving stale sporadic
state (e.g. a truncated hi_priority) behind on failure.
Validate sched_priority up front so the error path is atomic.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Commit 2ec7d90eba refactored sched_setparam() into set_sporadic_param()
but moved the apply logic into the former reject branch without
inverting the condition. As a result sched_setparam() rejects valid
sporadic parameters (repl >= 2 * budget) with EINVAL and accepts
invalid ones, tripping the DEBUGASSERT in sched_sporadic.c or wrapping
the replenishment calculation.
Invert the condition to match process_sporadic() in sched_setscheduler.c.
Fixes: 2ec7d90eba ("sched_setparam.c: coverity HIS_metric_violation: RETURN")
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
waitid() documents WNOWAIT support but exited_child() unconditionally
removed and freed the child status entry, so a second wait on the same
child failed with ECHILD. Debug builds were also inconsistent: the
options mask rejected WNOWAIT entirely with ENOSYS.
Pass options down to exited_child() and skip the discard when WNOWAIT
is set, matching waitpid(), and add WNOWAIT to the debug options mask.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Replace a literal 100000 with the USEC_PER_SEC macro in the oneshot
timer restart calculation. This bug causes incorrect timeout values
when CONFIG_SCHED_CPULOAD_TICKSPERSEC=1, though defaults are not
affected. Present since 2016 (commit 300361539a).
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Add a NULL check for the param argument before dereferencing
param->sched_priority. The sibling functions sched_setparam and
sched_getparam already have this check; sched_setscheduler was
the only one missing it, allowing a NULL pointer dereference
via sched_setscheduler(0, SCHED_FIFO, NULL).
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Compare ctcb->group->tg_ppid against rtcb->group->tg_pid (the group
leader PID) instead of rtcb->pid in waitid() and in the
!CONFIG_SCHED_CHILD_STATUS path of waitpid(). Commit ece224a7e3
("handle waitpid waitting tcb->group is NULL") rewrote the
comparisons this way when adding the ctcb->group NULL guard,
regressing what 90be95bb89 had correct: a non-group-leader thread
calling waitid(P_PID) or waitpid() on a child always gets ECHILD.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Protect the environment release in clearenv() with the task group mutex.
This prevents concurrent environment operations from racing with cleanup.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Remove the per-arch testset implementation from the spinlock layer.
The testset abstraction predates the unified spinlock.h API and is no
longer used now that all arches provide spin_lock_irqsave()/
spin_unlock_irqrestore() directly. Drop the per-arch *_testset.{c,S}
implementations and spinlock.h files for arm, sim, sparc, tricore,
x86_64, and xtensa, along with the CXD56_TESTSET,
CXD56_TESTSET_WITH_HWSEM, and CXD56_ATOMIC_WITH_HWSEM Kconfig options
in arch/arm/src/cxd56xx, and simplify the CXD56 semaphore pool loop
in cxd56_sph.c to a single unconditional range.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Fix checkpatch "Missing blank line after declarations" errors in
drivers/timers/arch_timer.c and sched/sched/sched_processtickless.c.
These are pre-existing issues, not introduced by the recent tickless
RR series.
Assisted-by: Zhipu GLM-5.3
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
In tickless mode, the scheduler timer is stopped whenever the currently
running task requires no time slicing (CLOCK_MAX). When a SCHED_RR task
was later switched in, nothing re-armed the timer, so the task could run
indefinitely without round-robin rotation.
Also, when a SCHED_RR task was preempted, its timeslice counter was not
decremented for the time already consumed, effectively giving the task
"bonus" CPU time when resumed.
Solve both by performing RR accounting on context switches:
- nxsched_suspend_roundrobin() charges the elapsed execution time
against the timeslice of the RR task being switched out
- nxsched_resume_roundrobin() restarts the scheduler timer for the
remaining timeslice of the RR task being switched in, so the timer
is always armed while an RR task is running
This also removes the previous workaround in nxsched_process_timer
that triggered the scheduler on every timer tick.
Assisted-by: Zhipu GLM-5.3
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
In tickless mode, the scheduler timer is stopped whenever the currently
running task requires no time slicing (CLOCK_MAX). When a SCHED_RR task
was later switched in, nothing re-armed the timer, so the task could run
indefinitely without round-robin rotation.
Reassess the scheduler timer in nxsched_switch_context() before the
context switch when the task being switched in uses round-robin
scheduling, so that the timer is always armed while an RR task is
running. Hooking into nxsched_switch_context() covers all context
switch paths (task context switch, interrupt exit, syscall and task
exit) since every architecture calls it on every switch.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
In hrtimer_start_absolute, when a pending hrtimer is removed (was the
head) and reinserted with a later expiration time, the reprogram flag
remains true but the hrtimer is no longer the earliest timer in the
queue. The old code passed hrtimer->expired to hrtimer_reprogram, which
was incorrect. Use hrtimer_get_first()->expired to ensure the hardware
timer is reprogrammed with the actual earliest timer's expiration time.
Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
The context-switch merge assigned the current timestamp to run_time instead of run_start. This overwrote the accumulated runtime and left the next elapsed-time calculation with a stale start value when critical-monitor CPU load accounting was disabled.
Store the timestamp in run_start under the thread runtime monitor configuration, matching the former resume path.
Fixes: b2a69ba781 ("sched: merge nxsched_suspend/resume_critmon")
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
The premp_start member was renamed to preemp_start, but the old name was reintroduced when the critical monitor switch paths were merged.
Use the current struct tcb_s field name so configurations with preemption monitoring enabled build successfully.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Add the blank lines required between local declarations and statements so sched_critmonitor.c passes nxstyle.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Replace the local EINTR retry loop with
nxsem_wait_uninterruptible(). This keeps the master implementation
aligned with the semaphore API without changing cancellation behavior.
Keep the cleanup separate so release branches where the helper is
unavailable can use the lifecycle commit without a downstream
compatibility patch.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
Factor the common queueing logic used by work_queue_wq() and
work_queue_next_wq() into a private helper.
Preserve existing timing semantics: regular work calculates its absolute
expiration before taking the queue lock, while periodic work advances the
previous expiration under the lock.
This is a code deduplication change with no public API or behavior changes.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
Prevent work_queue_free() from destroying predefined queues or freeing a
custom queue from one of its own callbacks. Mark teardown under the queue
lock, reject new submissions, return pending work to its owner, and wait for
every worker before releasing queue resources.
Clean up partially created worker pools, reject invalid delays, safely
replace pending periodic work, and make synchronous cancellation wait for
every concurrent callback using the same work structure.
Tested on an STM32H7 PX4 FMUv6C with the matching ostest suite in Flat and
Protected kernel builds.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
set_sporadic_param() tested rtcb (the calling task) instead of tcb (the
task being modified). A cross-task sched_setparam() therefore either
skipped the sporadic parameter update entirely or, when the calling
task was itself sporadic, reset a task that had no sporadic state.
Use tcb consistently and drop the now-unused rtcb argument.
Signed-off-by: yushuailong <yyyusl@qq.com>
The policy flag bits were cleared before the switch statement, so the
checks testing whether the task was previously SCHED_SPORADIC could
never be true. As a result nxsched_stop_sporadic() was never called
when a sporadic task switched to SCHED_FIFO/SCHED_RR, leaking the
sporadic state, and a sporadic-to-sporadic reconfiguration ran
initialize instead of reset.
Clear the policy flag bits only after the previous policy has been
evaluated, right before the new policy bits are set.
Signed-off-by: yushuailong <yyyusl@qq.com>
nxsched_stop_sporadic() freed tcb->sporadic but left
TCB_FLAG_SCHED_SPORADIC set in tcb->flags. On thread exit,
nxtask_recover() calls nxsched_stop_sporadic() and the final context
switch in up_exit() then sees the stale SPORADIC policy flag and calls
nxsched_suspend_sporadic() on a TCB whose sporadic state is already
freed, tripping DEBUGASSERT(tcb->sporadic) and hanging the system
(reproduced by ostest sporadic_test on sim, present on master).
Clear the policy bits inside nxsched_stop_sporadic() so every caller
leaves the TCB in a consistent state.
Signed-off-by: yushuailong <yyyusl@qq.com>
Rename atomic_fetch_add/sub/or/and/xor to atomic_add/sub/or/and/xor
to avoid conflicts with the C/C++ standard library naming. The
atomic_fetch_xxx naming is reserved by the standard; keeping it causes
function name conflicts when source files indirectly include both
<nuttx/atomic.h> and <atomic>/<stdatomic.h>.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
clock_gettime(CLOCK_MONOTONIC) reads g_system_ticks, which is only
refreshed when a timer expiration is processed. On SCHED_TICKLESS an
idle system has no timeout armed, so the clock returns 0 before the
first expiration and a frozen value afterwards.
This regressed in commit c7b6442974, which switched CLOCK_MONOTONIC to
the sched tick counter to exclude suspended time. Excluding suspend time
needs explicit accounting maintained by PM code, the tick counter cannot
provide it on tickless.
Restore the live read. On non-tickless builds clock_systime_timespec()
falls back to the same tick counter, so behavior there is unchanged.
Verified on qemu-intel64, nrf52840-dk and rv-virt.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code