Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Richard 祝发兴 - -IT
rt-thread
提交
5d36fa78
R
rt-thread
项目概览
Richard 祝发兴 - -IT
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
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,发现更多精彩内容 >>
提交
5d36fa78
编写于
5月 12, 2019
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[pthreads] Use pthread table for pthread management.
上级
b7cc4e9c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
207 addition
and
102 deletion
+207
-102
components/libc/pthreads/pthread.c
components/libc/pthreads/pthread.c
+194
-83
components/libc/pthreads/pthread.h
components/libc/pthreads/pthread.h
+2
-5
components/libc/pthreads/pthread_cond.c
components/libc/pthreads/pthread_cond.c
+1
-1
components/libc/pthreads/pthread_internal.h
components/libc/pthreads/pthread_internal.h
+2
-11
components/libc/pthreads/pthread_tls.c
components/libc/pthreads/pthread_tls.c
+8
-2
未找到文件。
components/libc/pthreads/pthread.c
浏览文件 @
5d36fa78
...
...
@@ -14,6 +14,104 @@
#include <sched.h>
#include "pthread_internal.h"
#include <rthw.h>
RT_DEFINE_SPINLOCK
(
pth_lock
);
_pthread_data_t
*
pth_table
[
PTHREAD_NUM_MAX
]
=
{
NULL
};
_pthread_data_t
*
_pthread_get_data
(
pthread_t
thread
)
{
_pthread_data_t
*
ptd
;
if
(
thread
>=
PTHREAD_NUM_MAX
)
return
NULL
;
rt_hw_spin_lock
(
&
pth_lock
);
ptd
=
pth_table
[
thread
];
rt_hw_spin_unlock
(
&
pth_lock
);
if
(
ptd
&&
ptd
->
magic
==
PTHREAD_MAGIC
)
return
ptd
;
return
NULL
;
}
pthread_t
_pthread_data_get_pth
(
_pthread_data_t
*
ptd
)
{
int
index
;
rt_hw_spin_lock
(
&
pth_lock
);
for
(
index
=
0
;
index
<
PTHREAD_NUM_MAX
;
index
++
)
{
if
(
pth_table
[
index
]
==
ptd
)
break
;
}
rt_hw_spin_unlock
(
&
pth_lock
);
return
index
;
}
pthread_t
_pthread_data_create
(
void
)
{
int
index
;
_pthread_data_t
*
ptd
=
NULL
;
ptd
=
(
_pthread_data_t
*
)
rt_malloc
(
sizeof
(
_pthread_data_t
));
if
(
!
ptd
)
return
PTHREAD_NUM_MAX
;
memset
(
ptd
,
0x0
,
sizeof
(
sizeof
(
_pthread_data_t
)));
ptd
->
canceled
=
0
;
ptd
->
cancelstate
=
PTHREAD_CANCEL_DISABLE
;
ptd
->
canceltype
=
PTHREAD_CANCEL_DEFERRED
;
ptd
->
magic
=
PTHREAD_MAGIC
;
rt_hw_spin_lock
(
&
pth_lock
);
for
(
index
=
0
;
index
<
PTHREAD_NUM_MAX
;
index
++
)
{
if
(
pth_table
[
index
]
==
NULL
)
{
pth_table
[
index
]
=
ptd
;
}
}
rt_hw_spin_unlock
(
&
pth_lock
);
return
index
;
}
void
_pthread_data_destroy
(
pthread_t
pth
)
{
_pthread_data_t
*
ptd
=
_pthread_get_data
(
pth
);
if
(
ptd
)
{
/* remove from pthread table */
rt_hw_spin_lock
(
&
pth_lock
);
pth_table
[
pth
]
=
NULL
;
rt_hw_spin_unlock
(
&
pth_lock
);
/* 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 */
rt_free
(
ptd
->
tid
->
stack_addr
);
}
/* clean stack addr pointer */
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
;
/* free ptd */
rt_free
(
ptd
);
}
}
int
pthread_system_init
(
void
)
{
/* initialize key area */
...
...
@@ -29,26 +127,11 @@ INIT_COMPONENT_EXPORT(pthread_system_init);
static
void
_pthread_destroy
(
_pthread_data_t
*
ptd
)
{
/* delete joinable semaphore */
if
(
ptd
->
joinable_sem
!=
RT_NULL
)
rt_sem_delete
(
ptd
->
joinable_sem
);
/* release thread resource */
if
(
ptd
->
attr
.
stackaddr
==
RT_NULL
)
pthread_t
pth
=
_pthread_data_get_pth
(
ptd
);
if
(
pth
!=
PTHREAD_NUM_MAX
)
{
/* release thread allocated stack */
rt_free
(
ptd
->
tid
->
stack_addr
);
_pthread_data_destroy
(
pth
);
}
/* clean stack addr pointer */
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
);
rt_free
(
ptd
);
return
;
}
...
...
@@ -56,7 +139,10 @@ static void _pthread_destroy(_pthread_data_t *ptd)
static
void
_pthread_cleanup
(
rt_thread_t
tid
)
{
_pthread_data_t
*
ptd
;
ptd
=
_pthread_get_data
(
tid
);
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
tid
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
/* clear cleanup function */
tid
->
cleanup
=
RT_NULL
;
...
...
@@ -84,29 +170,31 @@ static void pthread_entry_stub(void *parameter)
ptd
->
return_value
=
value
;
}
int
pthread_create
(
pthread_t
*
t
id
,
int
pthread_create
(
pthread_t
*
p
id
,
const
pthread_attr_t
*
attr
,
void
*
(
*
start
)(
void
*
),
void
*
parameter
)
{
int
re
sult
;
int
re
t
=
0
;
void
*
stack
;
char
name
[
RT_NAME_MAX
];
static
rt_uint16_t
pthread_number
=
0
;
pthread_t
pth_id
;
_pthread_data_t
*
ptd
;
/* tid shall be provided */
RT_ASSERT
(
t
id
!=
RT_NULL
);
RT_ASSERT
(
p
id
!=
RT_NULL
);
/* allocate posix thread data */
pt
d
=
(
_pthread_data_t
*
)
rt_malloc
(
sizeof
(
_pthread_data_t
)
);
if
(
pt
d
==
RT_NULL
)
return
ENOMEM
;
/* clean posix thread data memory */
rt_memset
(
ptd
,
0
,
sizeof
(
_pthread_data_t
))
;
ptd
->
canceled
=
0
;
ptd
->
cancelstate
=
PTHREAD_CANCEL_DISABLE
;
ptd
->
canceltype
=
PTHREAD_CANCEL_DEFERRED
;
ptd
->
magic
=
PTHREAD_MAGIC
;
pt
h_id
=
_pthread_data_create
(
);
if
(
pt
h_id
==
PTHREAD_NUM_MAX
)
{
ret
=
ENOMEM
;
goto
__exit
;
}
/* get pthread data */
ptd
=
_pthread_get_data
(
pth_id
)
;
if
(
attr
!=
RT_NULL
)
{
...
...
@@ -130,20 +218,16 @@ int pthread_create(pthread_t *tid,
if
(
stack
==
RT_NULL
)
{
rt_free
(
ptd
);
return
ENOMEM
;
ret
=
ENOMEM
;
goto
__exit
;
}
/* pthread is a static thread object */
ptd
->
tid
=
(
rt_thread_t
)
rt_malloc
(
sizeof
(
struct
rt_thread
));
if
(
ptd
->
tid
==
RT_NULL
)
{
if
(
ptd
->
attr
.
stackaddr
==
0
)
rt_free
(
stack
);
rt_free
(
ptd
);
return
ENOMEM
;
ret
=
ENOMEM
;
goto
__exit
;
}
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_JOINABLE
)
...
...
@@ -151,11 +235,8 @@ int pthread_create(pthread_t *tid,
ptd
->
joinable_sem
=
rt_sem_create
(
name
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
ptd
->
joinable_sem
==
RT_NULL
)
{
if
(
ptd
->
attr
.
stackaddr
!=
0
)
rt_free
(
stack
);
rt_free
(
ptd
);
return
ENOMEM
;
ret
=
ENOMEM
;
goto
__exit
;
}
}
else
...
...
@@ -172,37 +253,29 @@ int pthread_create(pthread_t *tid,
stack
,
ptd
->
attr
.
stacksize
,
ptd
->
attr
.
schedparam
.
sched_priority
,
5
)
!=
RT_EOK
)
{
if
(
ptd
->
attr
.
stackaddr
==
0
)
rt_free
(
stack
);
if
(
ptd
->
joinable_sem
!=
RT_NULL
)
rt_sem_delete
(
ptd
->
joinable_sem
);
rt_free
(
ptd
);
return
EINVAL
;
ret
=
EINVAL
;
goto
__exit
;
}
/* set pthread id */
*
tid
=
ptd
->
t
id
;
*
pid
=
pth_
id
;
/* set pthread cleanup function and ptd data */
(
*
tid
)
->
cleanup
=
_pthread_cleanup
;
(
*
tid
)
->
user_data
=
(
rt_uint32_t
)
ptd
;
ptd
->
tid
->
cleanup
=
_pthread_cleanup
;
ptd
->
tid
->
user_data
=
(
rt_uint32_t
)
ptd
;
/* start thread */
result
=
rt_thread_startup
(
*
tid
);
if
(
result
==
RT_EOK
)
if
(
rt_thread_startup
(
ptd
->
tid
)
==
RT_EOK
)
return
0
;
/* start thread failed */
rt_thread_detach
(
ptd
->
tid
);
if
(
ptd
->
attr
.
stackaddr
==
0
)
rt_free
(
stack
);
if
(
ptd
->
joinable_sem
!=
RT_NULL
)
rt_sem_delete
(
ptd
->
joinable_sem
);
rt_free
(
ptd
);
ret
=
EINVAL
;
return
EINVAL
;
__exit:
if
(
pth_id
!=
PTHREAD_NUM_MAX
)
_pthread_data_destroy
(
pth_id
);
return
ret
;
}
RTM_EXPORT
(
pthread_create
);
...
...
@@ -221,7 +294,7 @@ int pthread_detach(pthread_t thread)
goto
__exit
;
}
if
((
threa
d
->
stat
&
RT_THREAD_STAT_MASK
)
==
RT_THREAD_CLOSE
)
if
((
ptd
->
ti
d
->
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
)
...
...
@@ -270,13 +343,13 @@ int pthread_join(pthread_t thread, void **value_ptr)
_pthread_data_t
*
ptd
;
rt_err_t
result
;
if
(
thread
==
rt_thread_self
())
ptd
=
_pthread_get_data
(
thread
);
if
(
ptd
&&
ptd
->
tid
==
rt_thread_self
())
{
/* join self */
return
EDEADLK
;
}
ptd
=
_pthread_get_data
(
thread
);
if
(
ptd
->
attr
.
detachstate
==
PTHREAD_CREATE_DETACHED
)
return
EINVAL
;
/* join on a detached pthread */
...
...
@@ -299,13 +372,32 @@ int pthread_join(pthread_t thread, void **value_ptr)
}
RTM_EXPORT
(
pthread_join
);
pthread_t
pthread_self
(
void
)
{
rt_thread_t
tid
;
_pthread_data_t
*
ptd
;
tid
=
rt_thread_self
();
if
(
tid
==
NULL
)
return
PTHREAD_NUM_MAX
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
return
_pthread_data_get_pth
(
ptd
);
}
RTM_EXPORT
(
pthread_self
);
void
pthread_exit
(
void
*
value
)
{
_pthread_data_t
*
ptd
;
_pthread_cleanup_t
*
cleanup
;
extern
_pthread_key_data_t
_thread_keys
[
PTHREAD_KEY_MAX
];
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
rt_enter_critical
();
/* disable cancel */
...
...
@@ -382,7 +474,15 @@ RTM_EXPORT(pthread_atfork);
int
pthread_kill
(
pthread_t
thread
,
int
sig
)
{
#ifdef RT_USING_SIGNALS
return
rt_thread_kill
(
thread
,
sig
);
_pthread_data_t
*
ptd
;
ptd
=
_pthread_get_data
(
thread
);
if
(
ptd
)
{
return
rt_thread_kill
(
ptd
->
tid
,
sig
);
}
return
EINVAL
;
#else
return
ENOSYS
;
#endif
...
...
@@ -401,8 +501,10 @@ void pthread_cleanup_pop(int execute)
_pthread_data_t
*
ptd
;
_pthread_cleanup_t
*
cleanup
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
if
(
execute
)
...
...
@@ -428,8 +530,10 @@ void pthread_cleanup_push(void (*routine)(void *), void *arg)
_pthread_data_t
*
ptd
;
_pthread_cleanup_t
*
cleanup
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
cleanup
=
(
_pthread_cleanup_t
*
)
rt_malloc
(
sizeof
(
_pthread_cleanup_t
));
...
...
@@ -478,8 +582,10 @@ int pthread_setcancelstate(int state, int *oldstate)
{
_pthread_data_t
*
ptd
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
EINVAL
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
if
((
state
==
PTHREAD_CANCEL_ENABLE
)
||
(
state
==
PTHREAD_CANCEL_DISABLE
))
...
...
@@ -499,8 +605,10 @@ int pthread_setcanceltype(int type, int *oldtype)
{
_pthread_data_t
*
ptd
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
EINVAL
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
if
((
type
!=
PTHREAD_CANCEL_DEFERRED
)
&&
(
type
!=
PTHREAD_CANCEL_ASYNCHRONOUS
))
...
...
@@ -519,8 +627,10 @@ void pthread_testcancel(void)
int
cancel
=
0
;
_pthread_data_t
*
ptd
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
if
(
ptd
->
cancelstate
==
PTHREAD_CANCEL_ENABLE
)
...
...
@@ -534,14 +644,14 @@ int pthread_cancel(pthread_t thread)
{
_pthread_data_t
*
ptd
;
/* cancel self */
if
(
thread
==
rt_thread_self
())
return
0
;
/* get posix thread data */
ptd
=
_pthread_get_data
(
thread
);
RT_ASSERT
(
ptd
!=
RT_NULL
);
/* cancel self */
if
(
ptd
->
tid
==
rt_thread_self
())
return
0
;
/* set canceled */
if
(
ptd
->
cancelstate
==
PTHREAD_CANCEL_ENABLE
)
{
...
...
@@ -555,10 +665,11 @@ int pthread_cancel(pthread_t thread)
* thread (pthread_cleanup), it will move to defunct
* thread list and wait for handling in idle thread.
*/
rt_thread_detach
(
threa
d
);
rt_thread_detach
(
ptd
->
ti
d
);
}
}
return
0
;
}
RTM_EXPORT
(
pthread_cancel
);
components/libc/pthreads/pthread.h
浏览文件 @
5d36fa78
...
...
@@ -32,7 +32,7 @@ extern "C" {
#define PTHREAD_EXPLICIT_SCHED 0
#define PTHREAD_INHERIT_SCHED 1
typedef
rt_thread_t
pthread_t
;
typedef
long
pthread_t
;
typedef
long
pthread_condattr_t
;
typedef
long
pthread_rwlockattr_t
;
typedef
long
pthread_mutexattr_t
;
...
...
@@ -172,10 +172,7 @@ rt_inline int pthread_equal (pthread_t t1, pthread_t t2)
return
t1
==
t2
;
}
rt_inline
pthread_t
pthread_self
(
void
)
{
return
rt_thread_self
();
}
pthread_t
pthread_self
(
void
);
void
pthread_exit
(
void
*
value_ptr
);
int
pthread_once
(
pthread_once_t
*
once_control
,
void
(
*
init_routine
)
(
void
));
...
...
components/libc/pthreads/pthread_cond.c
浏览文件 @
5d36fa78
...
...
@@ -189,7 +189,7 @@ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond,
pthread_cond_init
(
cond
,
RT_NULL
);
/* The mutex was not owned by the current thread at the time of the call. */
if
(
mutex
->
lock
.
owner
!=
p
thread_self
())
if
(
mutex
->
lock
.
owner
!=
rt_
thread_self
())
return
-
RT_ERROR
;
/* unlock a mutex failed */
if
(
pthread_mutex_unlock
(
mutex
)
!=
0
)
...
...
components/libc/pthreads/pthread_internal.h
浏览文件 @
5d36fa78
...
...
@@ -30,6 +30,7 @@ struct _pthread_key_data
};
typedef
struct
_pthread_key_data
_pthread_key_data_t
;
#define PTHREAD_NUM_MAX 32
#define PTHREAD_MAGIC 0x70746873
struct
_pthread_data
{
...
...
@@ -56,17 +57,7 @@ struct _pthread_data
};
typedef
struct
_pthread_data
_pthread_data_t
;
rt_inline
_pthread_data_t
*
_pthread_get_data
(
pthread_t
thread
)
{
_pthread_data_t
*
ptd
;
RT_ASSERT
(
thread
!=
RT_NULL
);
ptd
=
(
_pthread_data_t
*
)
thread
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
RT_ASSERT
(
ptd
->
magic
==
PTHREAD_MAGIC
);
return
ptd
;
}
_pthread_data_t
*
_pthread_get_data
(
pthread_t
thread
);
int
clock_time_to_tick
(
const
struct
timespec
*
time
);
...
...
components/libc/pthreads/pthread_tls.c
浏览文件 @
5d36fa78
...
...
@@ -22,7 +22,10 @@ void *pthread_getspecific(pthread_key_t key)
{
struct
_pthread_data
*
ptd
;
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
NULL
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
NULL
);
if
(
ptd
->
tls
==
NULL
)
...
...
@@ -39,7 +42,10 @@ int pthread_setspecific(pthread_key_t key, const void *value)
{
struct
_pthread_data
*
ptd
;
ptd
=
_pthread_get_data
(
rt_thread_self
());
if
(
rt_thread_self
()
==
NULL
)
return
EINVAL
;
/* get pthread data from user data of thread */
ptd
=
(
_pthread_data_t
*
)
rt_thread_self
()
->
user_data
;
RT_ASSERT
(
ptd
!=
NULL
);
/* check tls area */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录