Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Xiaobo07
rt-thread
提交
9f5a9b6b
R
rt-thread
项目概览
Xiaobo07
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9f5a9b6b
编写于
5月 10, 2022
作者:
L
liuxianliang
提交者:
guo
5月 18, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[modify] the recycle logic about resource of pthread.
上级
9ab2094e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
119 addition
and
108 deletion
+119
-108
components/libc/compilers/common/stdlib.c
components/libc/compilers/common/stdlib.c
+5
-0
components/libc/posix/pthreads/pthread.c
components/libc/posix/pthreads/pthread.c
+98
-99
src/idle.c
src/idle.c
+16
-9
未找到文件。
components/libc/compilers/common/stdlib.c
浏览文件 @
9f5a9b6b
...
...
@@ -20,8 +20,13 @@ void __rt_libc_exit(int status)
if
(
self
!=
RT_NULL
)
{
#ifdef RT_USING_PTHREADS
extern
void
pthread_exit
(
void
*
value
);
pthread_exit
((
void
*
)
status
);
#else
LOG_E
(
"thread:%s exit:%d!"
,
self
->
name
,
status
);
rt_thread_control
(
self
,
RT_THREAD_CTRL_CLOSE
,
RT_NULL
);
#endif
}
}
...
...
components/libc/posix/pthreads/pthread.c
浏览文件 @
9f5a9b6b
...
...
@@ -8,6 +8,7 @@
* 2018-01-26 Bernard Fix pthread_detach issue for a none-joinable
* thread.
* 2019-02-07 Bernard Add _pthread_destroy to release pthread resource.
* 2022-05-10 xiangxistu Modify the recycle logic about resource of pthread.
*/
#include <rthw.h>
...
...
@@ -87,15 +88,18 @@ pthread_t _pthread_data_create(void)
return
index
;
}
void
_pthread_data_destroy
(
pthread_t
pth
)
void
_pthread_data_destroy
(
_pthread_data_t
*
ptd
)
{
RT_DECLARE_SPINLOCK
(
pth_lock
);
extern
_pthread_key_data_t
_thread_keys
[
PTHREAD_KEY_MAX
];
_pthread_data_t
*
ptd
=
_pthread_get_data
(
pth
);
pthread_t
pth
;
if
(
ptd
)
{
/* destruct thread local key */
/* if this thread create the local thread data,
* destruct thread local key
*/
if
(
ptd
->
tls
!=
RT_NULL
)
{
void
*
data
;
...
...
@@ -115,6 +119,7 @@ void _pthread_data_destroy(pthread_t pth)
ptd
->
tls
=
RT_NULL
;
}
pth
=
_pthread_data_get_pth
(
ptd
);
/* remove from pthread table */
rt_hw_spin_lock
(
&
pth_lock
);
pth_table
[
pth
]
=
NULL
;
...
...
@@ -122,81 +127,58 @@ void _pthread_data_destroy(pthread_t pth)
/* delete joinable semaphore */
if
(
ptd
->
joinable_sem
!=
RT_NULL
)
rt_sem_delete
(
ptd
->
joinable_sem
);
/* release thread resource */
if
(
ptd
->
attr
.
stackaddr
==
RT_NULL
)
{
/* release thread allocated stack */
if
(
ptd
->
tid
)
{
rt_free
(
ptd
->
tid
->
stack_addr
);
}
rt_sem_delete
(
ptd
->
joinable_sem
);
ptd
->
joinable_sem
=
RT_NULL
;
}
/* clean stack addr pointer */
if
(
ptd
->
tid
)
ptd
->
tid
->
stack_addr
=
RT_NULL
;
/*
* if this thread create the local thread data,
* delete it
*/
if
(
ptd
->
tls
!=
RT_NULL
)
rt_free
(
ptd
->
tls
);
rt_free
(
ptd
->
tid
);
/* clean magic */
ptd
->
magic
=
0x0
;
/* clear the "ptd->tid->user_data" */
ptd
->
tid
->
user_data
=
RT_NULL
;
/* free ptd */
rt_free
(
ptd
);
}
}
static
void
_pthread_
destroy
(
_pthread_data_t
*
pt
d
)
static
void
_pthread_
cleanup
(
rt_thread_t
ti
d
)
{
pthread_t
pth
=
_pthread_data_get_pth
(
ptd
);
if
(
pth
!=
PTHREAD_NUM_MAX
)
{
_pthread_data_destroy
(
pth
);
}
/* clear cleanup function */
tid
->
cleanup
=
RT_NULL
;
/* restore tid stack */
rt_free
(
tid
->
stack_addr
);
return
;
/* restore tid control block */
rt_free
(
tid
);
}
static
void
_pthread_cleanup
(
rt_thread_t
tid
)
static
void
pthread_entry_stub
(
void
*
parameter
)
{
void
*
value
;
_pthread_data_t
*
ptd
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
tid
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
ptd
=
(
_pthread_data_t
*
)
parameter
;
/* clear cleanup function */
tid
->
cleanup
=
RT_NULL
;
/* execute pthread entry */
value
=
ptd
->
thread_entry
(
ptd
->
thread_parameter
);
/* According to "detachstate" to whether or not to recycle resource immediately */
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_JOINABLE
)
{
/* set value */
ptd
->
return_value
=
value
;
rt_sem_release
(
ptd
->
joinable_sem
);
}
else
{
/* release pthread resource */
_pthread_destroy
(
ptd
);
_pthread_d
ata_d
estroy
(
ptd
);
}
}
static
void
pthread_entry_stub
(
void
*
parameter
)
{
void
*
value
;
_pthread_data_t
*
ptd
;
ptd
=
(
_pthread_data_t
*
)
parameter
;
/* execute pthread entry */
value
=
ptd
->
thread_entry
(
ptd
->
thread_parameter
);
/* set value */
ptd
->
return_value
=
value
;
}
int
pthread_create
(
pthread_t
*
pid
,
const
pthread_attr_t
*
attr
,
void
*
(
*
start
)(
void
*
),
void
*
parameter
)
...
...
@@ -311,7 +293,9 @@ int pthread_create(pthread_t *pid,
__exit:
if
(
pth_id
!=
PTHREAD_NUM_MAX
)
_pthread_data_destroy
(
pth_id
);
{
_pthread_data_destroy
(
ptd
);
}
return
ret
;
}
RTM_EXPORT
(
pthread_create
);
...
...
@@ -327,7 +311,6 @@ int pthread_detach(pthread_t thread)
goto
__exit
;
}
rt_enter_critical
();
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_DETACHED
)
{
/* The implementation has detected that the value specified by thread does not refer
...
...
@@ -339,27 +322,8 @@ int pthread_detach(pthread_t thread)
if
((
ptd
->
tid
->
stat
&
RT_THREAD_STAT_MASK
)
==
RT_THREAD_CLOSE
)
{
/* this defunct pthread is not handled by idle */
if
(
rt_sem_trytake
(
ptd
->
joinable_sem
)
!=
RT_EOK
)
{
rt_sem_release
(
ptd
->
joinable_sem
);
/* change to detach state */
ptd
->
attr
.
detachstate
=
PTHREAD_CREATE_DETACHED
;
/* detach joinable semaphore */
if
(
ptd
->
joinable_sem
)
{
rt_sem_delete
(
ptd
->
joinable_sem
);
ptd
->
joinable_sem
=
RT_NULL
;
}
}
else
{
/* destroy this pthread */
_pthread_destroy
(
ptd
);
}
/* destroy this pthread */
_pthread_data_destroy
(
ptd
);
goto
__exit
;
}
else
...
...
@@ -376,7 +340,6 @@ int pthread_detach(pthread_t thread)
}
__exit:
rt_exit_critical
();
return
ret
;
}
RTM_EXPORT
(
pthread_detach
);
...
...
@@ -412,7 +375,7 @@ int pthread_join(pthread_t thread, void **value_ptr)
*
value_ptr
=
ptd
->
return_value
;
/* destroy this pthread */
_pthread_destroy
(
ptd
);
_pthread_d
ata_d
estroy
(
ptd
);
}
else
{
...
...
@@ -507,9 +470,12 @@ void pthread_exit(void *value)
{
_pthread_data_t
*
ptd
;
_pthread_cleanup_t
*
cleanup
;
extern
_pthread_key_data_t
_thread_keys
[
PTHREAD_KEY_MAX
]
;
rt_thread_t
tid
;
if
(
rt_thread_self
()
==
NULL
)
return
;
if
(
rt_thread_self
()
==
RT_NULL
)
{
return
;
}
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
...
...
@@ -521,7 +487,10 @@ void pthread_exit(void *value)
ptd
->
return_value
=
value
;
rt_exit_critical
();
/* invoke pushed cleanup */
/*
* When use pthread_exit to exit.
* invoke pushed cleanup
*/
while
(
ptd
->
cleanup
!=
RT_NULL
)
{
cleanup
=
ptd
->
cleanup
;
...
...
@@ -532,29 +501,30 @@ void pthread_exit(void *value)
rt_free
(
cleanup
);
}
/* destruct thread local key */
if
(
ptd
->
tls
!=
RT_NULL
)
{
void
*
data
;
rt_uint32_t
index
;
/* get the info aboult "tid" early */
tid
=
ptd
->
tid
;
for
(
index
=
0
;
index
<
PTHREAD_KEY_MAX
;
index
++
)
{
if
(
_thread_keys
[
index
].
is_used
)
{
data
=
ptd
->
tls
[
index
];
if
(
data
&&
_thread_keys
[
index
].
destructor
)
_thread_keys
[
index
].
destructor
(
data
);
}
}
/* release tls area */
rt_free
(
ptd
->
tls
);
ptd
->
tls
=
RT_NULL
;
/* According to "detachstate" to whether or not to recycle resource immediately */
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_JOINABLE
)
{
/* set value */
rt_sem_release
(
ptd
->
joinable_sem
);
}
else
{
/* release pthread resource */
_pthread_data_destroy
(
ptd
);
}
/* detach thread */
rt_thread_detach
(
ptd
->
tid
);
/*
* second: detach thread.
* this thread will be removed from scheduler list
* and because there is a cleanup function in the
* thread (pthread_cleanup), it will move to defunct
* thread list and wait for handling in idle thread.
*/
rt_thread_detach
(
tid
);
/* reschedule thread */
rt_schedule
();
}
...
...
@@ -765,6 +735,8 @@ RTM_EXPORT(pthread_testcancel);
int
pthread_cancel
(
pthread_t
thread
)
{
_pthread_data_t
*
ptd
;
_pthread_cleanup_t
*
cleanup
;
rt_thread_t
tid
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
thread
);
...
...
@@ -772,6 +744,7 @@ int pthread_cancel(pthread_t thread)
{
return
EINVAL
;
}
tid
=
ptd
->
tid
;
/* cancel self */
if
(
ptd
->
tid
==
rt_thread_self
())
...
...
@@ -784,13 +757,39 @@ int pthread_cancel(pthread_t thread)
if
(
ptd
->
canceltype
==
PTHREAD_CANCEL_ASYNCHRONOUS
)
{
/*
* to detach thread.
* When use pthread_cancel to exit.
* invoke pushed cleanup
*/
while
(
ptd
->
cleanup
!=
RT_NULL
)
{
cleanup
=
ptd
->
cleanup
;
ptd
->
cleanup
=
cleanup
->
next
;
cleanup
->
cleanup_func
(
cleanup
->
parameter
);
/* release this cleanup function */
rt_free
(
cleanup
);
}
/* According to "detachstate" to whether or not to recycle resource immediately */
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_JOINABLE
)
{
/* set value */
rt_sem_release
(
ptd
->
joinable_sem
);
}
else
{
/* release pthread resource */
_pthread_data_destroy
(
ptd
);
}
/*
* second: detach thread.
* this thread will be removed from scheduler list
* and because there is a cleanup function in the
* thread (pthread_cleanup), it will move to defunct
* thread list and wait for handling in idle thread.
*/
rt_thread_detach
(
ptd
->
tid
);
rt_thread_detach
(
tid
);
}
}
...
...
src/idle.c
浏览文件 @
9f5a9b6b
...
...
@@ -194,6 +194,7 @@ static void rt_defunct_execute(void)
while
(
1
)
{
rt_thread_t
thread
;
rt_bool_t
object_is_systemobject
;
void
(
*
cleanup
)(
struct
rt_thread
*
tid
);
#ifdef RT_USING_MODULE
...
...
@@ -212,32 +213,38 @@ static void rt_defunct_execute(void)
dlmodule_destroy
(
module
);
}
#endif
/* invoke thread cleanup */
cleanup
=
thread
->
cleanup
;
if
(
cleanup
!=
RT_NULL
)
{
cleanup
(
thread
);
}
#ifdef RT_USING_SIGNALS
rt_thread_free_sig
(
thread
);
#endif
/* store the point of "thread->cleanup" avoid to lose */
cleanup
=
thread
->
cleanup
;
/* if it's a system object, not delete it */
if
(
rt_object_is_systemobject
((
rt_object_t
)
thread
)
==
RT_TRUE
)
object_is_systemobject
=
rt_object_is_systemobject
((
rt_object_t
)
thread
);
if
(
object_is_systemobject
==
RT_TRUE
)
{
/* detach this object */
rt_object_detach
((
rt_object_t
)
thread
);
}
else
/* invoke thread cleanup */
if
(
cleanup
!=
RT_NULL
)
{
cleanup
(
thread
);
}
#ifdef RT_USING_HEAP
/* if need free, delete it */
if
(
object_is_systemobject
==
RT_FALSE
)
{
/* release thread's stack */
RT_KERNEL_FREE
(
thread
->
stack_addr
);
/* delete thread object */
rt_object_delete
((
rt_object_t
)
thread
);
#endif
}
#endif
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录