Change every occurence of up_switch_context to use this_task() as the first parameter.
"nxsched_add_readytorun" returns "true" if context switch is required. "nxsched_add_readytorun"
typically could only switch the assigned/running task to the one which is passed in as parameter.
But this is not strictly guaranteed in SMP; if other CPUs tweak with affinities or priorities,
it may be possible that the running task after the call is changed, but is some other
task from the readytorun list (and it should be, if there is higher priority one available or the
affinity of the added task prevents it to be scheduled in, but the previous head of the readytorun
list should run.
this_task() is always the correct one to switch to, since it always points to the tcb which was
just switched in by the nxsched_add_readytorun.
This is also a precursor to re-writing the SMP queue logic to remove pending lists for SMP.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
after this commits
commit e7fa4cae6cbf567266985c8072db1f51ad480943
Author: Yanfeng Liu <yfliu2008@qq.com>
Date: Fri May 17 06:11:52 2024 +0800
sched/tcb: use shared group for kthreads
all kernel thread share group idle
and should not dup filelist to this group
Signed-off-by: guohao15 <guohao15@xiaomi.com>
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch is a rework of the NuttX file descriptor implementation. The
goal is two-fold:
1. Improve POSIX compliance. The old implementation tied file description
to inode only, not the file struct. POSIX however dictates otherwise.
2. Fix a bug with descriptor duplication (dup2() and dup3()). There is
an existing race condition with this POSIX API that currently results
in a kernel side crash.
The crash occurs when a partially open / closed file descriptor is
duplicated. The reason for the crash is that even if the descriptor is
closed, the file might still be in use by the kernel (due to e.g. ongoing
write to file). The open file data is changed by file_dup3() and this
causes a crash in the device / drivers themselves as they lose access to
the inode and private data.
The fix is done by separating struct file into file and file descriptor
structs. The file struct can live on even if the descriptor is closed,
fixing the crash. This also fixes the POSIX issue, as two descriptors
can now point to the same file.
Signed-off-by: Ville Juven <ville.juven@unikie.com>
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
When using pthread_kill, the signal should be delivered to the
specified thread. Current implementation, however, may add the
signal to the groups pending list, if the signal is masked at the
time of dispatch. From the group's pending list it can be delivered
to any thread of the group, which is wrong.
Fix this by adding a new field "FAR struct tcb_s *tcb" to
"struct sigpendq", marking if the signal needs to be delivered
to a specific thread. Use NULL for the value if delivery to any
thread in the group is ok.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
The file descriptors of kernel threads should be clean and should
not be generated based on user threads. Instead, an idle thread
hould be chosen.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Kthreads can share the group data so that to reduce overheads.
This implements shared kthread group via:
- use `tcb_s` instead of `task_tcb_s` for kthreads
- use `g_kthread_group` when creating kthreads
- use stackargs to start tasks and kthreads
see pull/12320 for test logs.
Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
1. add support to join main task
| static pthread_t self;
|
| static void *join_task(void *arg)
| {
| int ret;
| ret = pthread_join(self, NULL); <--- /* Fix Task could not be joined */
| return NULL;
| }
|
| int main(int argc, char *argv[])
| {
| pthread_t thread;
|
| self = pthread_self();
|
| pthread_create(&thread, NULL, join_task, NULL);
| sleep(1);
|
| pthread_exit(NULL);
| return 0;
| }
2. Detach active thread will not alloc for additional join, just update the task flag.
3. Remove the return value waiting lock logic (data_sem),
the return value will be stored in the waiting tcb.
4. Revise the return value of pthread_join(), consistent with linux
e.g:
Joining a detached and canceled thread should return EINVAL, not ESRCH
https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_join.html
[EINVAL]
The value specified by thread does not refer to a joinable thread.
NOTE:
This PR will not increase stack usage, but struct tcb_s will increase 32 bytes.
Signed-off-by: chao an <anchao@lixiang.com>
The delete flag is not synchronized with the life cycle of the group,
if the flag set before waitpid(), the tcb will be mistakenly deleted
by group_del_waiter(), use-after-free will happen.
Regression by:
| commit 29e50ffa73 (origin/master, origin/HEAD)
| Author: chao an <anchao@lixiang.com>
| Date: Mon Mar 4 09:19:27 2024 +0800
|
| sched/group: move task group into task_tcb_s to improve performance
|
| move task group into task_tcb_s to avoid access allocator to improve performance
|
| for Task Termination, the time consumption will be reduced ~2us (Tricore TC397 300MHZ):
| 15.97(us) -> 13.55(us)
|
| Signed-off-by: chao an <anchao@lixiang.com>
Signed-off-by: chao an <anchao@lixiang.com>
move task group into task_tcb_s to avoid access allocator to improve performance
for Task Termination, the time consumption will be reduced ~2us (Tricore TC397 300MHZ):
15.97(us) -> 13.55(us)
Signed-off-by: chao an <anchao@lixiang.com>
Skip the child wait if here is only self in member list,
since the members of the task group should be 1 if task exit.
Fix Regression issue that the task could not terminate normally.
Signed-off-by: chao an <anchao@lixiang.com>
Change the type of task group member to single list chain to
avoid accessing the memory allocator to improve the performance
Signed-off-by: chao an <anchao@lixiang.com>
The maximum startup parameters have been checked accordingly in nxtask_setup_stackargs(),
let us save argument counter to avoid limit check.
Signed-off-by: chao an <anchao@lixiang.com>
Task group could find from process id, replace group_findbypid to
task_getgroup to simplify the search logic
Signed-off-by: chao an <anchao@lixiang.com>
The task files should consult the "spawn action" and "O_CLOEXEC flags"
to determine further whether the file should be duplicated.
This PR will further optimize file list duplicating to avoid the performance
regression caused by additional file operations.
Signed-off-by: chao an <anchao@xiaomi.com>
This moves task / thread cancel point logic from the NuttX kernel into
libc, while the data needed by the cancel point logic is moved to TLS.
The change is an enabler to move user-space APIs to libc as well, for
a coherent user/kernel separation.
reproduce:
static void *pthread(void *arg)
{
system(arg);
}
void test (int argc, char *argv[])
{
pthread_create(&pthread0, &attr, pthread, argv[1]);
pthread_create(&pthread1, &attr, pthread, argv[2]);
}
only one pthread system() returnd, othres hanged
rootcause:
As we known, system() will create a new task called:
system -c XX
The example:
parent group child groups
pthread0 -> waitpid() -> system -c ps -> exit() -> nxtask_signalparent()
pthread1 -> waitpid() -> system -c ls -> exit() -> nxtask_signalparent()
Each child group exit with function nxtask_signalparent(),
As we expect:
system -c ps will signal pthread0
system -c ls will signal pthread1
But actually:
system -c ps will signal pthread0/1
system -c ls will signal pthread0/1
As the spec, we know, this behavior is normal:
https://man7.org/linux/man-pages/man2/sigwaitinfo.2.html
So for this situation, when the signo is SIGCHLD, we broadcast.
Signed-off-by: ligd <liguiding1@xiaomi.com>
1. Update all CMakeLists.txt to adapt to new layout
2. Fix cmake build break
3. Update all new file license
4. Fully compatible with current compilation environment(use configure.sh or cmake as you choose)
------------------
How to test
From within nuttx/. Configure:
cmake -B build -DBOARD_CONFIG=sim/nsh -GNinja
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake -B build -DBOARD_CONFIG=sabre-6quad/smp -GNinja
cmake -B build -DBOARD_CONFIG=lm3s6965-ek/qemu-flat -GNinja
(or full path in custom board) :
cmake -B build -DBOARD_CONFIG=$PWD/boards/sim/sim/sim/configs/nsh -GNinja
This uses ninja generator (install with sudo apt install ninja-build). To build:
$ cmake --build build
menuconfig:
$ cmake --build build -t menuconfig
--------------------------
2. cmake/build: reformat the cmake style by cmake-format
https://github.com/cheshirekow/cmake_format
$ pip install cmakelang
$ for i in `find -name CMakeLists.txt`;do cmake-format $i -o $i;done
$ for i in `find -name *\.cmake`;do cmake-format $i -o $i;done
Co-authored-by: Matias N <matias@protobits.dev>
Signed-off-by: chao an <anchao@xiaomi.com>
Fixed ltp_stress_mqueues_multi_send_rev_1 test issue:
In SMP mode, tg_members will operate on different cores.
Adding interrupt locking operations ensures that the operation
of tg_members will not be interrupted by other cores.
Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
Store the old environment in a local context so another temporary address
environment can be selected. This can happen especially when a process
is being loaded (the new process's mappings are temporarily instantiated)
and and interrupt occurs.
- Remove the temporary "saved" variable when temporarily changing MMU
mappings to access another process's memory. The fact that it has an
address environment is enough to make the choice
- Restore nxflat_addrenv_restore-macro. It was accidentally lost when
the address environment handling was re-factored.
Do not allow a deferred cancellation if the group is exiting, it is too
dangerous to allow the threads to execute any user space code after the
exit has started.
If the cancelled thread is not inside a cancellation point, just kill it
immediately via asynchronous cancellation. This will create far less
problems than allowing it to continue running user code.