Skip to content

Commit 05bb1a5

Browse files
committed
添加idle回收资源的修改
1 parent da701d6 commit 05bb1a5

File tree

5 files changed

+168
-42
lines changed

5 files changed

+168
-42
lines changed

include/rtthread.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ void rt_thread_idle_init(void);
168168
rt_err_t rt_thread_idle_sethook(void (*hook)(void));
169169
rt_err_t rt_thread_idle_delhook(void (*hook)(void));
170170
#endif
171-
void rt_thread_idle_excute(void);
172171
rt_thread_t rt_thread_idle_gethandler(void);
173172

174173
/*
@@ -187,6 +186,7 @@ rt_uint16_t rt_critical_level(void);
187186

188187
#ifdef RT_USING_HOOK
189188
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
189+
void rt_scheduler_switchto_sethook(void (*hook)(struct rt_thread *tid));
190190
#endif
191191

192192
#ifdef RT_USING_SMP
@@ -396,6 +396,10 @@ rt_err_t rt_mq_recv(rt_mq_t mq,
396396
rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg);
397397
#endif
398398

399+
/* defunct */
400+
void rt_thread_defunct_enqueue(rt_thread_t thread);
401+
rt_thread_t rt_thread_defunct_dequeue(void);
402+
399403
/*
400404
* spinlock
401405
*/

src/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ config IDLE_THREAD_STACK_SIZE
9898
int "The stack size of idle thread"
9999
default 256
100100

101+
config SYSTEM_THREAD_STACK_SIZE
102+
int "The stack size of system thread (for defunct etc.)"
103+
depends on RT_USING_SMP
104+
default IDLE_THREAD_STACK_SIZE
105+
101106
config RT_USING_TIMER_SOFT
102107
bool "Enable software timer with a timer thread"
103108
default y

src/idle.c

Lines changed: 133 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,22 @@
4444
#define _CPUS_NR 1
4545
#endif /* RT_USING_SMP */
4646

47-
extern rt_list_t rt_thread_defunct;
47+
static rt_list_t _rt_thread_defunct = RT_LIST_OBJECT_INIT(_rt_thread_defunct);;
4848

4949
static struct rt_thread idle[_CPUS_NR];
5050
ALIGN(RT_ALIGN_SIZE)
5151
static rt_uint8_t rt_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE];
5252

53+
#ifdef RT_USING_SMP
54+
#ifndef SYSTEM_THREAD_STACK_SIZE
55+
#define SYSTEM_THREAD_STACK_SIZE IDLE_THREAD_STACK_SIZE
56+
#endif
57+
static struct rt_thread rt_system_thread;
58+
ALIGN(RT_ALIGN_SIZE)
59+
static rt_uint8_t rt_system_stack[SYSTEM_THREAD_STACK_SIZE];
60+
static struct rt_semaphore system_sem;
61+
#endif
62+
5363
#ifdef RT_USING_IDLE_HOOK
5464
#ifndef RT_IDLE_HOOK_LIST_SIZE
5565
#define RT_IDLE_HOOK_LIST_SIZE 4
@@ -127,62 +137,132 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void))
127137

128138
#endif /* RT_USING_IDLE_HOOK */
129139

130-
#ifdef RT_USING_HEAP
140+
#ifdef RT_USING_MODULE
131141
/* Return whether there is defunctional thread to be deleted. */
132142
rt_inline int _has_defunct_thread(void)
133143
{
134144
/* The rt_list_isempty has prototype of "int rt_list_isempty(const rt_list_t *l)".
135-
* So the compiler has a good reason that the rt_thread_defunct list does
136-
* not change within rt_thread_idle_excute thus optimize the "while" loop
145+
* So the compiler has a good reason that the _rt_thread_defunct list does
146+
* not change within rt_thread_defunct_exceute thus optimize the "while" loop
137147
* into a "if".
138148
*
139149
* So add the volatile qualifier here. */
140-
const volatile rt_list_t *l = (const volatile rt_list_t *)&rt_thread_defunct;
150+
const volatile rt_list_t *l = (const volatile rt_list_t *)&_rt_thread_defunct;
141151

142152
return l->next != l;
143153
}
144-
#endif /* RT_USING_HEAP */
154+
#endif /* RT_USING_MODULE */
155+
156+
/* enqueue a thread to defunct queue
157+
* it must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable
158+
*/
159+
void rt_thread_defunct_enqueue(rt_thread_t thread)
160+
{
161+
rt_list_insert_after(&_rt_thread_defunct, &thread->tlist);
162+
#ifdef RT_USING_SMP
163+
rt_sem_release(&system_sem);
164+
#endif
165+
}
166+
167+
/* dequeue a thread from defunct queue
168+
* it must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable
169+
*/
170+
rt_thread_t rt_thread_defunct_dequeue(void)
171+
{
172+
rt_thread_t thread = RT_NULL;
173+
rt_list_t *l = &_rt_thread_defunct;
174+
175+
if (l->next != l)
176+
{
177+
thread = rt_list_entry(l->next,
178+
struct rt_thread,
179+
tlist);
180+
rt_list_remove(&(thread->tlist));
181+
}
182+
return thread;
183+
}
145184

146185
/**
147186
* @ingroup Thread
148187
*
149188
* This function will perform system background job when system idle.
150189
*/
151-
void rt_thread_idle_excute(void)
190+
static void rt_defunct_execute(void)
152191
{
153-
/* Loop until there is no dead thread. So one call to rt_thread_idle_excute
192+
/* Loop until there is no dead thread. So one call to rt_defunct_execute
154193
* will do all the cleanups. */
155-
/* disable interrupt */
156-
157-
RT_DEBUG_NOT_IN_INTERRUPT;
158-
159-
#ifdef RT_USING_HEAP
160194
while (1)
161195
{
162196
rt_base_t lock;
163197
rt_thread_t thread;
198+
void (*cleanup)(struct rt_thread *tid);
164199

200+
#ifdef RT_USING_MODULE
201+
struct rt_dlmodule *module = RT_NULL;
202+
#endif
203+
RT_DEBUG_NOT_IN_INTERRUPT;
204+
205+
/* disable interrupt */
165206
lock = rt_hw_interrupt_disable();
166207

208+
#ifdef RT_USING_MODULE
167209
/* check whether list is empty */
168210
if (!_has_defunct_thread())
169211
{
170212
rt_hw_interrupt_enable(lock);
171213
break;
172214
}
173215
/* get defunct thread */
174-
thread = rt_list_entry(rt_thread_defunct.next,
216+
thread = rt_list_entry(_rt_thread_defunct.next,
175217
struct rt_thread,
176218
tlist);
219+
module = (struct rt_dlmodule*)thread->module_id;
220+
if (module)
221+
{
222+
dlmodule_destroy(module);
223+
}
177224
/* remove defunct thread */
178225
rt_list_remove(&(thread->tlist));
179-
/* release thread's stack */
180-
RT_KERNEL_FREE(thread->stack_addr);
181-
/* delete thread object */
182-
rt_object_delete((rt_object_t)thread);
183-
rt_hw_interrupt_enable(lock);
226+
#else
227+
thread = rt_thread_defunct_dequeue();
228+
if (!thread)
229+
{
230+
rt_hw_interrupt_enable(lock);
231+
break;
232+
}
233+
#endif
234+
/* invoke thread cleanup */
235+
cleanup = thread->cleanup;
236+
if (cleanup != RT_NULL)
237+
{
238+
rt_hw_interrupt_enable(lock);
239+
cleanup(thread);
240+
lock = rt_hw_interrupt_disable();
241+
}
242+
243+
#ifdef RT_USING_SIGNALS
244+
rt_thread_free_sig(thread);
245+
#endif
246+
247+
/* if it's a system object, not delete it */
248+
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
249+
{
250+
/* detach this object */
251+
rt_object_detach((rt_object_t)thread);
252+
/* enable interrupt */
253+
rt_hw_interrupt_enable(lock);
254+
}
255+
else
256+
{
257+
rt_hw_interrupt_enable(lock);
258+
#ifdef RT_USING_HEAP
259+
/* release thread's stack */
260+
RT_KERNEL_FREE(thread->stack_addr);
261+
/* delete thread object */
262+
rt_object_delete((rt_object_t)thread);
263+
#endif
264+
}
184265
}
185-
#endif /* RT_USING_HEAP */
186266
}
187267

188268
extern void rt_system_power_manager(void);
@@ -214,13 +294,27 @@ static void rt_thread_idle_entry(void *parameter)
214294
}
215295
#endif /* RT_USING_IDLE_HOOK */
216296

217-
rt_thread_idle_excute();
297+
#ifndef RT_USING_SMP
298+
rt_defunct_execute();
299+
#endif /* RT_USING_SMP */
300+
218301
#ifdef RT_USING_PM
219302
rt_system_power_manager();
220303
#endif /* RT_USING_PM */
221304
}
222305
}
223306

307+
#ifdef RT_USING_SMP
308+
static void rt_thread_system_entry(void *parameter)
309+
{
310+
while (1)
311+
{
312+
rt_sem_take(&system_sem, RT_WAITING_FOREVER);
313+
rt_defunct_execute();
314+
}
315+
}
316+
#endif
317+
224318
/**
225319
* @ingroup SystemInit
226320
*
@@ -250,6 +344,24 @@ void rt_thread_idle_init(void)
250344
/* startup */
251345
rt_thread_startup(&idle[i]);
252346
}
347+
348+
#ifdef RT_USING_SMP
349+
RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2);
350+
351+
rt_sem_init(&system_sem, "defunct", 1, RT_IPC_FLAG_FIFO);
352+
353+
/* create defunct thread */
354+
rt_thread_init(&rt_system_thread,
355+
"tsystem",
356+
rt_thread_system_entry,
357+
RT_NULL,
358+
rt_system_stack,
359+
sizeof(rt_system_stack),
360+
RT_THREAD_PRIORITY_MAX - 2,
361+
32);
362+
/* startup */
363+
rt_thread_startup(&rt_system_thread);
364+
#endif
253365
}
254366

255367
/**

src/scheduler.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ struct rt_thread *rt_current_thread = RT_NULL;
4747
rt_uint8_t rt_current_priority;
4848
#endif /* RT_USING_SMP */
4949

50-
rt_list_t rt_thread_defunct;
51-
5250
#ifdef RT_USING_HOOK
5351
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
5452

@@ -224,9 +222,6 @@ void rt_system_scheduler_init(void)
224222
/* initialize ready table */
225223
rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table));
226224
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
227-
228-
/* initialize thread defunct */
229-
rt_list_init(&rt_thread_defunct);
230225
}
231226

232227
/**

src/thread.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
#include <rthw.h>
3333
#include <rtthread.h>
3434

35-
extern rt_list_t rt_thread_defunct;
36-
3735
#ifdef RT_USING_HOOK
3836
static void (*rt_thread_suspend_hook)(rt_thread_t thread);
3937
static void (*rt_thread_resume_hook) (rt_thread_t thread);
@@ -131,7 +129,7 @@ static void _rt_thread_exit(void)
131129
else
132130
{
133131
/* insert to defunct thread list */
134-
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
132+
rt_thread_defunct_enqueue(thread);
135133
}
136134

137135
/* switch to next task */
@@ -379,17 +377,22 @@ rt_err_t rt_thread_detach(rt_thread_t thread)
379377
/* release thread timer */
380378
rt_timer_detach(&(thread->thread_timer));
381379

382-
/* disable interrupt */
383-
lock = rt_hw_interrupt_disable();
384-
385380
/* change stat */
386381
thread->stat = RT_THREAD_CLOSE;
387382

388-
/* detach thread object */
389-
rt_object_detach((rt_object_t)thread);
390-
391-
/* enable interrupt */
392-
rt_hw_interrupt_enable(lock);
383+
if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE)
384+
{
385+
rt_object_detach((rt_object_t)thread);
386+
}
387+
else
388+
{
389+
/* disable interrupt */
390+
lock = rt_hw_interrupt_disable();
391+
/* insert to defunct thread list */
392+
rt_thread_defunct_enqueue(thread);
393+
/* enable interrupt */
394+
rt_hw_interrupt_enable(lock);
395+
}
393396

394397
return RT_EOK;
395398
}
@@ -484,7 +487,7 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
484487
thread->stat = RT_THREAD_CLOSE;
485488

486489
/* insert to defunct thread list */
487-
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
490+
rt_thread_defunct_enqueue(thread);
488491

489492
/* enable interrupt */
490493
rt_hw_interrupt_enable(lock);
@@ -847,12 +850,12 @@ rt_err_t rt_thread_resume(rt_thread_t thread)
847850

848851
rt_timer_stop(&thread->thread_timer);
849852

850-
/* enable interrupt */
851-
rt_hw_interrupt_enable(temp);
852-
853853
/* insert to schedule ready list */
854854
rt_schedule_insert_thread(thread);
855855

856+
/* enable interrupt */
857+
rt_hw_interrupt_enable(temp);
858+
856859
RT_OBJECT_HOOK_CALL(rt_thread_resume_hook, (thread));
857860
return RT_EOK;
858861
}
@@ -867,6 +870,7 @@ RTM_EXPORT(rt_thread_resume);
867870
void rt_thread_timeout(void *parameter)
868871
{
869872
struct rt_thread *thread;
873+
register rt_base_t temp;
870874

871875
thread = (struct rt_thread *)parameter;
872876

@@ -875,6 +879,9 @@ void rt_thread_timeout(void *parameter)
875879
RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND);
876880
RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
877881

882+
/* disable interrupt */
883+
temp = rt_hw_interrupt_disable();
884+
878885
/* set error number */
879886
thread->error = -RT_ETIMEOUT;
880887

@@ -884,6 +891,9 @@ void rt_thread_timeout(void *parameter)
884891
/* insert to schedule ready list */
885892
rt_schedule_insert_thread(thread);
886893

894+
/* enable interrupt */
895+
rt_hw_interrupt_enable(temp);
896+
887897
/* do schedule */
888898
rt_schedule();
889899
}

0 commit comments

Comments
 (0)