Skip to content

Commit 1ef0f02

Browse files
committed
sched/tcb: add a reference count to the TCB to prevent it from being deleted.
To replace the large lock with smaller ones and reduce the large locks related to the TCB, in many scenarios, we only need to ensure that the TCB won't be released instead of locking, thus reducing the possibility of lock recursion. Signed-off-by: hujun5 <hujun5@xiaomi.com>
1 parent ddad4fa commit 1ef0f02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+477
-156
lines changed

arch/risc-v/src/common/riscv_exception.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int riscv_exception(int mcause, void *regs, void *args)
111111
_alert("Segmentation fault in %s (PID %d: %s)\n", get_task_name(ptcb),
112112
tcb->pid, get_task_name(tcb));
113113

114+
nxsched_put_tcb(ptcb);
114115
tcb->flags |= TCB_FLAG_FORCED_CANCEL;
115116

116117
/* Return to _exit function in privileged mode with argument SIGSEGV */

drivers/note/note_driver.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,7 @@ FAR char *note_get_taskname(pid_t pid, FAR char *buf, size_t len)
21092109
if (tcb != NULL)
21102110
{
21112111
strlcpy(buf, tcb->name, len);
2112+
nxsched_put_tcb(tcb);
21122113
return buf;
21132114
}
21142115

drivers/syslog/vsyslog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <nuttx/streams.h>
3737
#include <nuttx/syslog/syslog.h>
3838

39+
#include "sched/sched.h"
3940
#include "syslog.h"
4041

4142
/****************************************************************************

fs/inode/fs_files.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg)
255255
ctcb = nxsched_get_tcb(pid);
256256
if (ctcb == NULL || ctcb->group == NULL || ctcb != tcb)
257257
{
258+
nxsched_put_tcb(ctcb);
258259
return;
259260
}
260261

@@ -264,6 +265,8 @@ static void task_fssync(FAR struct tcb_s *tcb, FAR void *arg)
264265
file_fsync(filep);
265266
file_put(filep);
266267
}
268+
269+
nxsched_put_tcb(ctcb);
267270
}
268271
}
269272
}

fs/procfs/fs_procfs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,7 @@ static int procfs_readdir(FAR struct inode *mountpt,
942942
/* Verify that the pid still refers to an active task/thread */
943943

944944
pid_t pid = level0->pid[index];
945-
FAR struct tcb_s *tcb = nxsched_get_tcb(pid);
946-
if (!tcb)
945+
if (!nxsched_verify_pid(pid))
947946
{
948947
ferr("ERROR: PID %d is no longer valid\n", pid);
949948
return -ENOENT;

fs/procfs/fs_procfsmeminfo.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer,
537537
}
538538

539539
tcb->flags |= TCB_FLAG_HEAP_DUMP;
540+
nxsched_put_tcb(tcb);
540541
return buflen;
541542
}
542543
else if ((p = strstr(buffer, "off")) != NULL)
@@ -550,6 +551,7 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer,
550551
}
551552

552553
tcb->flags &= ~TCB_FLAG_HEAP_DUMP;
554+
nxsched_put_tcb(tcb);
553555
return buflen;
554556
}
555557
#endif

fs/procfs/fs_procfsproc.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include <nuttx/lib/lib.h>
6363

6464
#include "fs_heap.h"
65+
#include "sched/sched.h"
6566

6667
#if !defined(CONFIG_SCHED_CPULOAD_NONE) || defined(CONFIG_SCHED_CRITMONITOR)
6768
# include <nuttx/clock.h>
@@ -1462,7 +1463,6 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath,
14621463
{
14631464
FAR struct proc_file_s *procfile;
14641465
FAR const struct proc_node_s *node;
1465-
FAR struct tcb_s *tcb;
14661466
FAR char *ptr;
14671467
unsigned long tmp;
14681468
pid_t pid;
@@ -1508,9 +1508,7 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath,
15081508
/* Now verify that a task with this task/thread ID exists */
15091509

15101510
pid = (pid_t)tmp;
1511-
1512-
tcb = nxsched_get_tcb(pid);
1513-
if (tcb == NULL)
1511+
if (!nxsched_verify_pid(pid))
15141512
{
15151513
ferr("ERROR: PID %d is no longer valid\n", pid);
15161514
return -ENOENT;
@@ -1663,6 +1661,8 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
16631661

16641662
leave_critical_section(flags);
16651663

1664+
nxsched_put_tcb(tcb);
1665+
16661666
/* Update the file offset */
16671667

16681668
if (ret > 0)
@@ -1714,6 +1714,7 @@ static ssize_t proc_write(FAR struct file *filep, FAR const char *buffer,
17141714
break;
17151715
}
17161716

1717+
nxsched_put_tcb(tcb);
17171718
return ret;
17181719
}
17191720

@@ -1769,7 +1770,6 @@ static int proc_opendir(FAR const char *relpath,
17691770
{
17701771
FAR struct proc_dir_s *procdir;
17711772
FAR const struct proc_node_s *node;
1772-
FAR struct tcb_s *tcb;
17731773
unsigned long tmp;
17741774
FAR char *ptr;
17751775
pid_t pid;
@@ -1819,9 +1819,7 @@ static int proc_opendir(FAR const char *relpath,
18191819
/* Now verify that a task with this task/thread ID exists */
18201820

18211821
pid = (pid_t)tmp;
1822-
1823-
tcb = nxsched_get_tcb(pid);
1824-
if (tcb == NULL)
1822+
if (!nxsched_verify_pid(pid))
18251823
{
18261824
ferr("ERROR: PID %d is not valid\n", pid);
18271825
return -ENOENT;
@@ -1911,7 +1909,6 @@ static int proc_readdir(FAR struct fs_dirent_s *dir,
19111909
{
19121910
FAR struct proc_dir_s *procdir;
19131911
FAR const struct proc_node_s *node = NULL;
1914-
FAR struct tcb_s *tcb;
19151912
unsigned int index;
19161913
pid_t pid;
19171914
int ret;
@@ -1939,9 +1936,7 @@ static int proc_readdir(FAR struct fs_dirent_s *dir,
19391936
/* Verify that the pid still refers to an active task/thread */
19401937

19411938
pid = procdir->pid;
1942-
1943-
tcb = nxsched_get_tcb(pid);
1944-
if (tcb == NULL)
1939+
if (!nxsched_verify_pid(pid))
19451940
{
19461941
ferr("ERROR: PID %d is no longer valid\n", pid);
19471942
return -ENOENT;
@@ -2013,7 +2008,6 @@ static int proc_rewinddir(struct fs_dirent_s *dir)
20132008
static int proc_stat(const char *relpath, struct stat *buf)
20142009
{
20152010
FAR const struct proc_node_s *node;
2016-
FAR struct tcb_s *tcb;
20172011
unsigned long tmp;
20182012
FAR char *ptr;
20192013
pid_t pid;
@@ -2057,9 +2051,7 @@ static int proc_stat(const char *relpath, struct stat *buf)
20572051
/* Now verify that a task with this task/thread ID exists */
20582052

20592053
pid = (pid_t)tmp;
2060-
2061-
tcb = nxsched_get_tcb(pid);
2062-
if (tcb == NULL)
2054+
if (!nxsched_verify_pid(pid))
20632055
{
20642056
ferr("ERROR: PID %d is no longer valid\n", pid);
20652057
return -ENOENT;

include/nuttx/mm/mm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
((node) != NULL && (dump)->pid == (node)->pid)
149149
# define MM_DUMP_LEAK(dump, node) \
150150
((node) != NULL && (dump)->pid == PID_MM_LEAK && (node)->pid >= 0 && \
151-
nxsched_get_tcb((node)->pid) == NULL)
151+
!nxsched_verify_pid((node)->pid))
152152
#else
153153
# define MM_DUMP_ALLOC(dump,node) ((dump)->pid == PID_MM_ALLOC)
154154
# define MM_DUMP_SEQNO(dump,node) (true)

include/nuttx/sched.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
#define TCB_FLAG_JOIN_COMPLETED (1 << 14) /* Bit 14: Pthread join completed */
112112
#define TCB_FLAG_FREE_TCB (1 << 15) /* Bit 15: Free tcb after exit */
113113
#define TCB_FLAG_PREEMPT_SCHED (1 << 16) /* Bit 16: tcb is PREEMPT_SCHED */
114+
#define TCB_FLAG_KILL_PROCESSING (1 << 17) /* Bit 17: tcb is killed */
114115

115116
/* Values for struct task_group tg_flags */
116117

@@ -727,6 +728,16 @@ struct tcb_s
727728
size_t level_deepest;
728729
size_t level;
729730
#endif
731+
732+
/* The total number that we are referenced by other tasks and
733+
* The total number of other tasks that we referenced.
734+
*/
735+
736+
atomic_t refs;
737+
738+
/* When we exit, we need post this sem. */
739+
740+
sem_t exit_sem;
730741
};
731742

732743
/* struct task_tcb_s ********************************************************/
@@ -904,25 +915,21 @@ FAR struct tcb_s *nxsched_self(void);
904915
void nxsched_foreach(nxsched_foreach_t handler, FAR void *arg);
905916

906917
/****************************************************************************
907-
* Name: nxsched_get_tcb
918+
* Name: nxsched_get_tcb/nxsched_put_tcb
908919
*
909920
* Description:
910-
* Given a task ID, this function will return the a pointer to the
911-
* corresponding TCB (or NULL if there is no such task ID).
912-
*
913-
* NOTE: This function holds a critical section while examining TCB data
914-
* data structures but releases that critical section before returning.
915-
* When it is released, the TCB may become unstable. If the caller
916-
* requires absolute stability while using the TCB, then the caller
917-
* should establish the critical section BEFORE calling this function and
918-
* hold that critical section as long as necessary.
921+
* Given a task ID,
922+
* Obtain a valid TCB and increment the corresponding reference count to
923+
* prevent it from being released. nxsched_get_tcb and nxsched_put_tcb
924+
* must be called in pairs to ensure the proper release of the TCB.
919925
*
920926
****************************************************************************/
921927

922928
FAR struct tcb_s *nxsched_get_tcb(pid_t pid);
929+
void nxsched_put_tcb(FAR struct tcb_s *tcb);
923930

924931
/****************************************************************************
925-
* Name: nxsched_releasepid
932+
* Name: nxsched_release_tcb
926933
*
927934
* Description:
928935
* When a task is destroyed, this function must be called to make its

libs/libc/gdbstub/lib_gdbstub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,8 @@ static void gdb_get_registers(FAR struct gdb_state_s *state)
10281028
*(FAR uintptr_t *)(reg + g_tcbinfo.reg_off.p[i]);
10291029
}
10301030
}
1031+
1032+
nxsched_put_tcb(tcb);
10311033
}
10321034

10331035
/****************************************************************************
@@ -1424,6 +1426,7 @@ static int gdb_query(FAR struct gdb_state_s *state)
14241426
get_task_name(tcb), thread_state, tcb->sched_priority,
14251427
tcb->adj_stack_size);
14261428

1429+
nxsched_put_tcb(tcb);
14271430
ret = gdb_bin2hex(state->pkt_buf, sizeof(state->pkt_buf),
14281431
thread_info, strlen(thread_info));
14291432

@@ -1502,6 +1505,7 @@ static int gdb_is_thread_active(FAR struct gdb_state_s *state)
15021505

15031506
state->pid = pid - 1;
15041507
gdb_send_ok_packet(state);
1508+
nxsched_put_tcb(tcb);
15051509
return ret;
15061510
}
15071511

@@ -1558,6 +1562,7 @@ static int gdb_thread_context(FAR struct gdb_state_s *state)
15581562
}
15591563

15601564
state->pid = pid - 1;
1565+
nxsched_put_tcb(tcb);
15611566
}
15621567

15631568
gdb_send_ok_packet(state);

0 commit comments

Comments
 (0)