Skip to content

Commit 31e562b

Browse files
wangzhi16acassis
authored andcommitted
Revert "sched/group: move task group into task_tcb_s to improve performance"
This reverts commit 29e50ff. reason: Placing the main thread and the gourd in the same memory block, and allocating and freeing memory simultaneously, presents the following two problems: When the main thread creates a child thread and performs a detach operation, there is a possibility that the main thread may have exited, but the main thread's TCB (Transaction Control Block) may not have been released. This could potentially cause the main thread's TCB to be double-freed. The core contradiction in this problem lies in binding the main thread's TCB (Trust Container Registry) and the group together. When releasing the main thread's TCB, an additional check is needed to ensure the main thread was the last to leave the group. If this check and the free operation are atomically guaranteed, the logic is sound, and double freeing won't occur. However, this atomicity cannot be completely guaranteed. If other free operations cause a block, problems still arise. Signed-off-by: wangzhi16 <[email protected]>
1 parent 1fe3de3 commit 31e562b

File tree

11 files changed

+45
-75
lines changed

11 files changed

+45
-75
lines changed

include/nuttx/mm/map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void mm_map_unlock(void);
129129
* Name: mm_map_initialize
130130
*
131131
* Description:
132-
* Initialization function, called only by group_postinitialize
132+
* Initialization function, called only by group_initialize
133133
*
134134
* Input Parameters:
135135
* mm - Pointer to the mm_map structure to be initialized

include/nuttx/sched.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -746,10 +746,6 @@ struct task_tcb_s
746746
/* Common TCB fields ******************************************************/
747747

748748
struct tcb_s cmn; /* Common TCB fields */
749-
750-
/* Task Group *************************************************************/
751-
752-
struct task_group_s group; /* Shared task group data */
753749
};
754750

755751
/* struct pthread_tcb_s *****************************************************/

sched/group/group.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ void task_initialize(void);
5858

5959
/* Task group data structure management */
6060

61-
int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype);
62-
void group_postinitialize(FAR struct task_tcb_s *tcb);
61+
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype);
62+
void group_initialize(FAR struct task_tcb_s *tcb);
6363
#ifndef CONFIG_DISABLE_PTHREAD
6464
void group_bind(FAR struct pthread_tcb_s *tcb);
6565
void group_join(FAR struct pthread_tcb_s *tcb);

sched/group/group_create.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ static inline void group_inherit_identity(FAR struct task_group_s *group)
9292
****************************************************************************/
9393

9494
/****************************************************************************
95-
* Name: group_initialize
95+
* Name: group_allocate
9696
*
9797
* Description:
9898
* Create and a new task group structure for the specified TCB. This
9999
* function is called as part of the task creation sequence. The structure
100100
* allocated and zeroed, but otherwise uninitialized. The full creation
101101
* of the group of a two step process: (1) First, this function allocates
102102
* group structure early in the task creation sequence in order to provide
103-
* a group container, then (2) group_postinitialize() is called to set up
104-
* the group membership.
103+
* a group container, then (2) group_initialize() is called to set up the
104+
* group membership.
105105
*
106106
* Input Parameters:
107107
* tcb - The tcb in need of the task group.
@@ -116,7 +116,7 @@ static inline void group_inherit_identity(FAR struct task_group_s *group)
116116
*
117117
****************************************************************************/
118118

119-
int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
119+
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
120120
{
121121
FAR struct task_group_s *group;
122122
int ret;
@@ -138,7 +138,12 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
138138
}
139139
else
140140
{
141-
group = &tcb->group;
141+
group = kmm_zalloc(sizeof(struct task_group_s));
142+
}
143+
144+
if (!group)
145+
{
146+
return -ENOMEM;
142147
}
143148

144149
#if defined(CONFIG_MM_KERNEL_HEAP)
@@ -175,7 +180,7 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
175180
ret = task_init_info(group);
176181
if (ret < 0)
177182
{
178-
return ret;
183+
goto errout_with_group;
179184
}
180185

181186
nxrmutex_init(&group->tg_mutex);
@@ -193,17 +198,20 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
193198
#endif
194199

195200
return OK;
201+
202+
errout_with_group:
203+
kmm_free(group);
204+
return ret;
196205
}
197206

198207
/****************************************************************************
199-
* Name: group_postinitialize
208+
* Name: group_initialize
200209
*
201210
* Description:
202211
* Add the task as the initial member of the group. The full creation of
203212
* the group of a two step process: (1) First, this group structure is
204-
* allocated by group_initialize() early in the task creation sequence,
205-
* then (2) this function is called to set up the initial group
206-
* membership.
213+
* allocated by group_allocate() early in the task creation sequence, then
214+
* (2) this function is called to set up the initial group membership.
207215
*
208216
* Input Parameters:
209217
* tcb - The tcb in need of the task group.
@@ -217,7 +225,7 @@ int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
217225
*
218226
****************************************************************************/
219227

220-
void group_postinitialize(FAR struct task_tcb_s *tcb)
228+
void group_initialize(FAR struct task_tcb_s *tcb)
221229
{
222230
FAR struct task_group_s *group;
223231

sched/group/group_foreachchild.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ int group_foreachchild(FAR struct task_group_s *group,
6464
{
6565
FAR sq_entry_t *curr;
6666
FAR sq_entry_t *next;
67-
int ret = OK;
67+
int ret;
6868

6969
DEBUGASSERT(group);
7070

sched/group/group_leave.c

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include <errno.h>
3232
#include <debug.h>
3333

34-
#include <nuttx/nuttx.h>
3534
#include <nuttx/irq.h>
3635
#include <nuttx/fs/fs.h>
3736
#include <nuttx/net/net.h>
@@ -71,8 +70,7 @@
7170
*
7271
****************************************************************************/
7372

74-
static inline void
75-
group_release(FAR struct task_group_s *group, uint8_t ttype)
73+
static inline void group_release(FAR struct task_group_s *group)
7674
{
7775
/* Destroy the mutex */
7876

@@ -125,18 +123,13 @@ group_release(FAR struct task_group_s *group, uint8_t ttype)
125123
}
126124
#endif
127125

128-
/* Then drop the group freeing the allocated memory */
126+
/* Mark the group as deleted now */
129127

130-
#ifndef CONFIG_DISABLE_PTHREAD
131-
if (ttype == TCB_FLAG_TTYPE_PTHREAD)
132-
{
133-
/* Mark the group as deleted now */
128+
group->tg_flags |= GROUP_FLAG_DELETED;
134129

135-
group->tg_flags |= GROUP_FLAG_DELETED;
130+
/* Then drop the group freeing the allocated memory */
136131

137-
group_drop(group);
138-
}
139-
#endif
132+
group_drop(group);
140133
}
141134

142135
/****************************************************************************
@@ -178,12 +171,6 @@ void group_leave(FAR struct tcb_s *tcb)
178171
group = tcb->group;
179172
if (group)
180173
{
181-
/* In any event, we can detach the group from the TCB so that we won't
182-
* do this again.
183-
*/
184-
185-
tcb->group = NULL;
186-
187174
/* Remove the member from group. */
188175

189176
#ifdef HAVE_GROUP_MEMBERS
@@ -198,8 +185,14 @@ void group_leave(FAR struct tcb_s *tcb)
198185
{
199186
/* Yes.. Release all of the resource held by the task group */
200187

201-
group_release(group, tcb->flags & TCB_FLAG_TTYPE_MASK);
188+
group_release(group);
202189
}
190+
191+
/* In any event, we can detach the group from the TCB so that we won't
192+
* do this again.
193+
*/
194+
195+
tcb->group = NULL;
203196
}
204197
}
205198

@@ -226,8 +219,6 @@ void group_leave(FAR struct tcb_s *tcb)
226219

227220
void group_drop(FAR struct task_group_s *group)
228221
{
229-
FAR struct task_tcb_s *tcb;
230-
231222
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
232223
/* If there are threads waiting for this group to be freed, then we cannot
233224
* yet free the memory resources. Instead just mark the group deleted
@@ -242,17 +233,13 @@ void group_drop(FAR struct task_group_s *group)
242233
}
243234
else
244235
#endif
236+
245237
/* Finally, if no one needs the group and it has been deleted, remove it */
246238

247239
if (group->tg_flags & GROUP_FLAG_DELETED)
248240
{
249-
tcb = container_of(group, struct task_tcb_s, group);
250-
251241
/* Release the group container itself */
252242

253-
if (tcb->cmn.flags & TCB_FLAG_FREE_TCB)
254-
{
255-
kmm_free(tcb);
256-
}
243+
kmm_free(group);
257244
}
258245
}

sched/init/nx_start.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ static void idle_group_initialize(void)
445445
/* Allocate the IDLE group */
446446

447447
DEBUGVERIFY(
448-
group_initialize((FAR struct task_tcb_s *)tcb, tcb->flags));
448+
group_allocate((FAR struct task_tcb_s *)tcb, tcb->flags));
449449

450450
/* Initialize the task join */
451451

@@ -478,7 +478,7 @@ static void idle_group_initialize(void)
478478
* of child status in the IDLE group.
479479
*/
480480

481-
group_postinitialize((FAR struct task_tcb_s *)tcb);
481+
group_initialize((FAR struct task_tcb_s *)tcb);
482482
tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED;
483483
}
484484
}

sched/pthread/pthread_create.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
209209

210210
/* Allocate a TCB for the new task. */
211211

212-
ptcb = kmm_zalloc(sizeof(struct pthread_tcb_s));
212+
ptcb = (FAR struct pthread_tcb_s *)
213+
kmm_zalloc(sizeof(struct pthread_tcb_s));
213214
if (!ptcb)
214215
{
215216
serr("ERROR: Failed to allocate TCB\n");

sched/sched/sched_releasetcb.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ static void nxsched_releasepid(pid_t pid)
100100

101101
int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
102102
{
103-
#ifndef CONFIG_DISABLE_PTHREAD
104-
FAR struct task_tcb_s *ttcb;
105-
#endif
106103
int ret = OK;
107104

108105
if (tcb)
@@ -175,25 +172,6 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
175172
/* Destroy the pthread join mutex */
176173

177174
nxtask_joindestroy(tcb);
178-
179-
/* Task still referenced by pthread */
180-
181-
if (ttype == TCB_FLAG_TTYPE_TASK)
182-
{
183-
ttcb = (FAR struct task_tcb_s *)tcb;
184-
if (!sq_empty(&ttcb->group.tg_members)
185-
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
186-
|| ttcb->group.tg_nwaiters > 0
187-
#endif
188-
)
189-
{
190-
/* Mark the group as deleted now */
191-
192-
ttcb->group.tg_flags |= GROUP_FLAG_DELETED;
193-
194-
return ret;
195-
}
196-
}
197175
#endif
198176

199177
/* And, finally, release the TCB itself */

sched/task/task_fork.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
170170

171171
/* Allocate a new task group with the same privileges as the parent */
172172

173-
ret = group_initialize(child, ttype);
173+
ret = group_allocate(child, ttype);
174174
if (ret < 0)
175175
{
176176
goto errout_with_tcb;
@@ -257,7 +257,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
257257

258258
/* Now we have enough in place that we can join the group */
259259

260-
group_postinitialize(child);
260+
group_initialize(child);
261261
sinfo("parent=%p, returning child=%p\n", parent, child);
262262
return child;
263263

0 commit comments

Comments
 (0)