Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yunqingabc
rt-thread
提交
8ab2b287
R
rt-thread
项目概览
yunqingabc
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8ab2b287
编写于
6月 26, 2013
作者:
Y
yiyue.fang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Embedded GPLv2 license in pthreads
上级
773990ab
变更
18
展开全部
隐藏空白更改
内联
并排
Showing
18 changed file
with
2368 addition
and
1746 deletion
+2368
-1746
components/pthreads/clock_time.c
components/pthreads/clock_time.c
+86
-71
components/pthreads/mqueue.c
components/pthreads/mqueue.c
+231
-187
components/pthreads/mqueue.h
components/pthreads/mqueue.h
+56
-26
components/pthreads/posix_types.h
components/pthreads/posix_types.h
+176
-151
components/pthreads/pthread.c
components/pthreads/pthread.c
+404
-356
components/pthreads/pthread.h
components/pthreads/pthread.h
+88
-71
components/pthreads/pthread_attr.c
components/pthreads/pthread_attr.c
+109
-69
components/pthreads/pthread_barrier.c
components/pthreads/pthread_barrier.c
+81
-42
components/pthreads/pthread_cond.c
components/pthreads/pthread_cond.c
+153
-107
components/pthreads/pthread_internal.h
components/pthreads/pthread_internal.h
+52
-28
components/pthreads/pthread_mutex.c
components/pthreads/pthread_mutex.c
+153
-108
components/pthreads/pthread_rwlock.c
components/pthreads/pthread_rwlock.c
+287
-220
components/pthreads/pthread_spin.c
components/pthreads/pthread_spin.c
+54
-22
components/pthreads/pthread_tls.c
components/pthreads/pthread_tls.c
+72
-43
components/pthreads/sched.c
components/pthreads/sched.c
+33
-9
components/pthreads/sched.h
components/pthreads/sched.h
+29
-6
components/pthreads/semaphore.c
components/pthreads/semaphore.c
+272
-222
components/pthreads/semaphore.h
components/pthreads/semaphore.h
+32
-8
未找到文件。
components/pthreads/clock_time.c
浏览文件 @
8ab2b287
...
...
@@ -3,15 +3,26 @@
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2012-12-08 Bernard fix the issue of _timevalue.tv_usec initialization,
* which found by Rob <rdent@iinet.net.au>
*/
#include <rtthread.h>
#include <pthread.h>
...
...
@@ -26,11 +37,11 @@ void clock_time_system_init()
device
=
rt_device_find
(
"rtc"
);
if
(
device
!=
RT_NULL
)
{
/* get realtime seconds */
/* get realtime seconds */
rt_device_control
(
device
,
RT_DEVICE_CTRL_RTC_GET_TIME
,
&
time
);
}
/* get tick */
/* get tick */
tick
=
rt_tick_get
();
_timevalue
.
tv_usec
=
(
tick
%
RT_TICK_PER_SECOND
)
*
MICROSECOND_PER_TICK
;
...
...
@@ -39,102 +50,106 @@ void clock_time_system_init()
int
clock_time_to_tick
(
const
struct
timespec
*
time
)
{
int
tick
;
int
nsecond
,
second
;
struct
timespec
tp
;
RT_ASSERT
(
time
!=
RT_NULL
);
tick
=
RT_WAITING_FOREVER
;
if
(
time
!=
NULL
)
{
/* get current tp */
clock_gettime
(
CLOCK_REALTIME
,
&
tp
);
if
((
time
->
tv_nsec
-
tp
.
tv_nsec
)
<
0
)
{
nsecond
=
NANOSECOND_PER_SECOND
-
(
tp
.
tv_nsec
-
time
->
tv_nsec
);
second
=
time
->
tv_sec
-
tp
.
tv_sec
-
1
;
}
else
{
nsecond
=
time
->
tv_nsec
-
tp
.
tv_nsec
;
second
=
time
->
tv_sec
-
tp
.
tv_sec
;
}
tick
=
second
*
RT_TICK_PER_SECOND
+
nsecond
*
RT_TICK_PER_SECOND
/
NANOSECOND_PER_SECOND
;
if
(
tick
<
0
)
tick
=
0
;
}
return
tick
;
int
tick
;
int
nsecond
,
second
;
struct
timespec
tp
;
RT_ASSERT
(
time
!=
RT_NULL
);
tick
=
RT_WAITING_FOREVER
;
if
(
time
!=
NULL
)
{
/* get current tp */
clock_gettime
(
CLOCK_REALTIME
,
&
tp
);
if
((
time
->
tv_nsec
-
tp
.
tv_nsec
)
<
0
)
{
nsecond
=
NANOSECOND_PER_SECOND
-
(
tp
.
tv_nsec
-
time
->
tv_nsec
);
second
=
time
->
tv_sec
-
tp
.
tv_sec
-
1
;
}
else
{
nsecond
=
time
->
tv_nsec
-
tp
.
tv_nsec
;
second
=
time
->
tv_sec
-
tp
.
tv_sec
;
}
tick
=
second
*
RT_TICK_PER_SECOND
+
nsecond
*
RT_TICK_PER_SECOND
/
NANOSECOND_PER_SECOND
;
if
(
tick
<
0
)
tick
=
0
;
}
return
tick
;
}
RTM_EXPORT
(
clock_time_to_tick
);
int
clock_getres
(
clockid_t
clockid
,
struct
timespec
*
res
)
int
clock_getres
(
clockid_t
clockid
,
struct
timespec
*
res
)
{
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
res
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
res
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
res
->
tv_sec
=
0
;
res
->
tv_nsec
=
NANOSECOND_PER_SECOND
/
RT_TICK_PER_SECOND
;
res
->
tv_sec
=
0
;
res
->
tv_nsec
=
NANOSECOND_PER_SECOND
/
RT_TICK_PER_SECOND
;
return
0
;
return
0
;
}
RTM_EXPORT
(
clock_getres
);
int
clock_gettime
(
clockid_t
clockid
,
struct
timespec
*
tp
)
int
clock_gettime
(
clockid_t
clockid
,
struct
timespec
*
tp
)
{
rt_tick_t
tick
;
rt_tick_t
tick
;
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
tp
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
tp
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
/* get tick */
tick
=
rt_tick_get
();
/* get tick */
tick
=
rt_tick_get
();
tp
->
tv_sec
=
_timevalue
.
tv_sec
+
tick
/
RT_TICK_PER_SECOND
;
tp
->
tv_nsec
=
(
_timevalue
.
tv_usec
+
(
tick
%
RT_TICK_PER_SECOND
)
*
NANOSECOND_PER_TICK
)
*
1000
;
return
0
;
tp
->
tv_sec
=
_timevalue
.
tv_sec
+
tick
/
RT_TICK_PER_SECOND
;
tp
->
tv_nsec
=
(
_timevalue
.
tv_usec
+
(
tick
%
RT_TICK_PER_SECOND
)
*
NANOSECOND_PER_TICK
)
*
1000
;
return
0
;
}
RTM_EXPORT
(
clock_gettime
);
int
clock_settime
(
clockid_t
clockid
,
const
struct
timespec
*
tp
)
int
clock_settime
(
clockid_t
clockid
,
const
struct
timespec
*
tp
)
{
int
second
;
rt_tick_t
tick
;
int
second
;
rt_tick_t
tick
;
rt_device_t
device
;
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
tp
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
if
((
clockid
!=
CLOCK_REALTIME
)
||
(
tp
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
/* get second */
second
=
tp
->
tv_sec
;
/* get tick */
/* get second */
second
=
tp
->
tv_sec
;
/* get tick */
tick
=
rt_tick_get
();
/* update timevalue */
/* update timevalue */
_timevalue
.
tv_usec
=
MICROSECOND_PER_SECOND
-
(
tick
%
RT_TICK_PER_SECOND
)
*
MICROSECOND_PER_TICK
;
_timevalue
.
tv_sec
=
second
-
tick
/
RT_TICK_PER_SECOND
-
1
;
/* update for RTC device */
/* update for RTC device */
device
=
rt_device_find
(
"rtc"
);
if
(
device
!=
RT_NULL
)
{
/* set realtime seconds */
/* set realtime seconds */
rt_device_control
(
device
,
RT_DEVICE_CTRL_RTC_SET_TIME
,
&
second
);
}
else
return
-
1
;
else
return
-
1
;
return
0
;
return
0
;
}
RTM_EXPORT
(
clock_settime
);
components/pthreads/mqueue.c
浏览文件 @
8ab2b287
/*
* File : mqueue.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
*/
#include "mqueue.h"
#include "pthread_internal.h"
...
...
@@ -5,266 +28,285 @@ static mqd_t posix_mq_list = RT_NULL;
static
struct
rt_semaphore
posix_mq_lock
;
void
posix_mq_system_init
()
{
rt_sem_init
(
&
posix_mq_lock
,
"pmq"
,
1
,
RT_IPC_FLAG_FIFO
);
rt_sem_init
(
&
posix_mq_lock
,
"pmq"
,
1
,
RT_IPC_FLAG_FIFO
);
}
rt_inline
void
posix_mq_insert
(
mqd_t
pmq
)
{
pmq
->
next
=
posix_mq_list
;
posix_mq_list
=
pmq
;
pmq
->
next
=
posix_mq_list
;
posix_mq_list
=
pmq
;
}
static
void
posix_mq_delete
(
mqd_t
pmq
)
{
mqd_t
iter
;
if
(
posix_mq_list
==
pmq
)
{
posix_mq_list
=
pmq
->
next
;
rt_mq_delete
(
pmq
->
mq
);
rt_free
(
pmq
);
return
;
}
for
(
iter
=
posix_mq_list
;
iter
->
next
!=
RT_NULL
;
iter
=
iter
->
next
)
{
if
(
iter
->
next
==
pmq
)
{
/* delete this mq */
if
(
pmq
->
next
!=
RT_NULL
)
iter
->
next
=
pmq
->
next
;
else
iter
->
next
=
RT_NULL
;
/* delete RT-Thread mqueue */
rt_mq_delete
(
pmq
->
mq
);
rt_free
(
pmq
);
return
;
}
}
mqd_t
iter
;
if
(
posix_mq_list
==
pmq
)
{
posix_mq_list
=
pmq
->
next
;
rt_mq_delete
(
pmq
->
mq
);
rt_free
(
pmq
);
return
;
}
for
(
iter
=
posix_mq_list
;
iter
->
next
!=
RT_NULL
;
iter
=
iter
->
next
)
{
if
(
iter
->
next
==
pmq
)
{
/* delete this mq */
if
(
pmq
->
next
!=
RT_NULL
)
iter
->
next
=
pmq
->
next
;
else
iter
->
next
=
RT_NULL
;
/* delete RT-Thread mqueue */
rt_mq_delete
(
pmq
->
mq
);
rt_free
(
pmq
);
return
;
}
}
}
static
mqd_t
posix_mq_find
(
const
char
*
name
)
{
mqd_t
iter
;
rt_object_t
object
;
mqd_t
iter
;
rt_object_t
object
;
for
(
iter
=
posix_mq_list
;
iter
!=
RT_NULL
;
iter
=
iter
->
next
)
{
object
=
(
rt_object_t
)(
iter
->
mq
);
for
(
iter
=
posix_mq_list
;
iter
!=
RT_NULL
;
iter
=
iter
->
next
)
{
object
=
(
rt_object_t
)(
iter
->
mq
);
if
(
strncmp
(
object
->
name
,
name
,
RT_NAME_MAX
)
==
0
)
{
return
iter
;
}
}
if
(
strncmp
(
object
->
name
,
name
,
RT_NAME_MAX
)
==
0
)
{
return
iter
;
}
}
return
RT_NULL
;
return
RT_NULL
;
}
int
mq_setattr
(
mqd_t
mqdes
,
const
struct
mq_attr
*
mqstat
,
struct
mq_attr
*
omqstat
)
int
mq_setattr
(
mqd_t
mqdes
,
const
struct
mq_attr
*
mqstat
,
struct
mq_attr
*
omqstat
)
{
rt_set_errno
(
-
RT_ERROR
);
return
-
1
;
rt_set_errno
(
-
RT_ERROR
);
return
-
1
;
}
RTM_EXPORT
(
mq_setattr
);
int
mq_getattr
(
mqd_t
mqdes
,
struct
mq_attr
*
mqstat
)
{
if
((
mqdes
==
RT_NULL
)
||
mqstat
==
RT_NULL
)
{
rt_set_errno
(
EBADF
);
return
-
1
;
}
mqstat
->
mq_maxmsg
=
mqdes
->
mq
->
max_msgs
;
mqstat
->
mq_msgsize
=
mqdes
->
mq
->
msg_size
;
mqstat
->
mq_curmsgs
=
0
;
mqstat
->
mq_flags
=
0
;
return
0
;
if
((
mqdes
==
RT_NULL
)
||
mqstat
==
RT_NULL
)
{
rt_set_errno
(
EBADF
);
return
-
1
;
}
mqstat
->
mq_maxmsg
=
mqdes
->
mq
->
max_msgs
;
mqstat
->
mq_msgsize
=
mqdes
->
mq
->
msg_size
;
mqstat
->
mq_curmsgs
=
0
;
mqstat
->
mq_flags
=
0
;
return
0
;
}
RTM_EXPORT
(
mq_getattr
);
mqd_t
mq_open
(
const
char
*
name
,
int
oflag
,
...)
{
mqd_t
mqdes
;
va_list
arg
;
mode_t
mode
;
struct
mq_attr
*
attr
=
RT_NULL
;
mqd_t
mqdes
;
va_list
arg
;
mode_t
mode
;
struct
mq_attr
*
attr
=
RT_NULL
;
/* lock posix mqueue list */
rt_sem_take
(
&
posix_mq_lock
,
RT_WAITING_FOREVER
);
mqdes
=
RT_NULL
;
if
(
oflag
&
O_CREAT
)
{
va_start
(
arg
,
oflag
);
mode
=
(
mode_t
)
va_arg
(
arg
,
unsigned
int
);
mode
=
mode
;
attr
=
(
struct
mq_attr
*
)
va_arg
(
arg
,
struct
mq_attr
*
);
va_end
(
arg
);
if
(
oflag
&
O_EXCL
)
{
if
(
posix_mq_find
(
name
)
!=
RT_NULL
)
{
rt_set_errno
(
EEXIST
);
goto
__return
;
}
}
mqdes
=
(
mqd_t
)
rt_malloc
(
sizeof
(
struct
mqdes
));
if
(
mqdes
==
RT_NULL
)
{
rt_set_errno
(
ENFILE
);
goto
__return
;
}
/* create RT-Thread message queue */
mqdes
->
mq
=
rt_mq_create
(
name
,
attr
->
mq_msgsize
,
attr
->
mq_maxmsg
,
RT_IPC_FLAG_FIFO
);
if
(
mqdes
->
mq
==
RT_NULL
)
/* create failed */
{
rt_set_errno
(
ENFILE
);
goto
__return
;
}
/* initialize reference count */
mqdes
->
refcount
=
1
;
mqdes
->
unlinked
=
0
;
/* insert mq to posix mq list */
posix_mq_insert
(
mqdes
);
}
else
{
/* find mqueue */
mqdes
=
posix_mq_find
(
name
);
if
(
mqdes
!=
RT_NULL
)
{
mqdes
->
refcount
++
;
/* increase reference count */
}
else
{
rt_set_errno
(
ENOENT
);
goto
__return
;
}
}
rt_sem_release
(
&
posix_mq_lock
);
return
mqdes
;
if
(
oflag
&
O_CREAT
)
{
va_start
(
arg
,
oflag
);
mode
=
(
mode_t
)
va_arg
(
arg
,
unsigned
int
);
mode
=
mode
;
attr
=
(
struct
mq_attr
*
)
va_arg
(
arg
,
struct
mq_attr
*
);
va_end
(
arg
);
if
(
oflag
&
O_EXCL
)
{
if
(
posix_mq_find
(
name
)
!=
RT_NULL
)
{
rt_set_errno
(
EEXIST
);
goto
__return
;
}
}
mqdes
=
(
mqd_t
)
rt_malloc
(
sizeof
(
struct
mqdes
));
if
(
mqdes
==
RT_NULL
)
{
rt_set_errno
(
ENFILE
);
goto
__return
;
}
/* create RT-Thread message queue */
mqdes
->
mq
=
rt_mq_create
(
name
,
attr
->
mq_msgsize
,
attr
->
mq_maxmsg
,
RT_IPC_FLAG_FIFO
);
if
(
mqdes
->
mq
==
RT_NULL
)
/* create failed */
{
rt_set_errno
(
ENFILE
);
goto
__return
;
}
/* initialize reference count */
mqdes
->
refcount
=
1
;
mqdes
->
unlinked
=
0
;
/* insert mq to posix mq list */
posix_mq_insert
(
mqdes
);
}
else
{
/* find mqueue */
mqdes
=
posix_mq_find
(
name
);
if
(
mqdes
!=
RT_NULL
)
{
mqdes
->
refcount
++
;
/* increase reference count */
}
else
{
rt_set_errno
(
ENOENT
);
goto
__return
;
}
}
rt_sem_release
(
&
posix_mq_lock
);
return
mqdes
;
__return:
/* release lock */
rt_sem_release
(
&
posix_mq_lock
);
/* release allocated memory */
if
(
mqdes
!=
RT_NULL
)
{
if
(
mqdes
->
mq
!=
RT_NULL
)
{
/* delete RT-Thread message queue */
rt_mq_delete
(
mqdes
->
mq
);
}
rt_free
(
mqdes
);
}
return
RT_NULL
;
/* release lock */
rt_sem_release
(
&
posix_mq_lock
);
/* release allocated memory */
if
(
mqdes
!=
RT_NULL
)
{
if
(
mqdes
->
mq
!=
RT_NULL
)
{
/* delete RT-Thread message queue */
rt_mq_delete
(
mqdes
->
mq
);
}
rt_free
(
mqdes
);
}
return
RT_NULL
;
}
RTM_EXPORT
(
mq_open
);
ssize_t
mq_receive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
)
{
rt_err_t
result
;
rt_err_t
result
;
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
result
=
rt_mq_recv
(
mqdes
->
mq
,
msg_ptr
,
msg_len
,
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
msg_len
;
result
=
rt_mq_recv
(
mqdes
->
mq
,
msg_ptr
,
msg_len
,
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
msg_len
;
rt_set_errno
(
EBADF
);
return
-
1
;
rt_set_errno
(
EBADF
);
return
-
1
;
}
RTM_EXPORT
(
mq_receive
);
int
mq_send
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
)
{
rt_err_t
result
;
rt_err_t
result
;
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
return
-
1
;
}
result
=
rt_mq_send
(
mqdes
->
mq
,
(
void
*
)
msg_ptr
,
msg_len
);
if
(
result
==
RT_EOK
)
return
0
;
result
=
rt_mq_send
(
mqdes
->
mq
,
(
void
*
)
msg_ptr
,
msg_len
);
if
(
result
==
RT_EOK
)
return
0
;
rt_set_errno
(
EBADF
);
rt_set_errno
(
EBADF
);
return
-
1
;
return
-
1
;
}
RTM_EXPORT
(
mq_send
);
ssize_t
mq_timedreceive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
,
const
struct
timespec
*
abs_timeout
)
ssize_t
mq_timedreceive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
,
const
struct
timespec
*
abs_timeout
)
{
int
tick
;
rt_err_t
result
;
int
tick
;
rt_err_t
result
;
/* parameters check */
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
/* parameters check */
if
((
mqdes
==
RT_NULL
)
||
(
msg_ptr
==
RT_NULL
))
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
return
-
1
;
}
tick
=
clock_time_to_tick
(
abs_timeout
);
tick
=
clock_time_to_tick
(
abs_timeout
);
result
=
rt_mq_recv
(
mqdes
->
mq
,
msg_ptr
,
msg_len
,
tick
);
if
(
result
==
RT_EOK
)
return
msg_len
;
result
=
rt_mq_recv
(
mqdes
->
mq
,
msg_ptr
,
msg_len
,
tick
);
if
(
result
==
RT_EOK
)
return
msg_len
;
if
(
result
==
-
RT_ETIMEOUT
)
rt_set_errno
(
ETIMEDOUT
);
else
rt_set_errno
(
EBADMSG
);
if
(
result
==
-
RT_ETIMEOUT
)
rt_set_errno
(
ETIMEDOUT
);
else
rt_set_errno
(
EBADMSG
);
return
-
1
;
return
-
1
;
}
RTM_EXPORT
(
mq_timedreceive
);
int
mq_timedsend
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
,
const
struct
timespec
*
abs_timeout
)
int
mq_timedsend
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
,
const
struct
timespec
*
abs_timeout
)
{
/* RT-Thread does not support timed send */
return
mq_send
(
mqdes
,
msg_ptr
,
msg_len
,
msg_prio
);
/* RT-Thread does not support timed send */
return
mq_send
(
mqdes
,
msg_ptr
,
msg_len
,
msg_prio
);
}
RTM_EXPORT
(
mq_timedsend
);
int
mq_notify
(
mqd_t
mqdes
,
const
struct
sigevent
*
notification
)
{
rt_set_errno
(
-
RT_ERROR
);
return
-
1
;
rt_set_errno
(
-
RT_ERROR
);
return
-
1
;
}
RTM_EXPORT
(
mq_notify
);
int
mq_close
(
mqd_t
mqdes
)
{
if
(
mqdes
==
RT_NULL
)
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
if
(
mqdes
==
RT_NULL
)
{
rt_set_errno
(
EINVAL
);
return
-
1
;
}
/* lock posix mqueue list */
rt_sem_take
(
&
posix_mq_lock
,
RT_WAITING_FOREVER
);
mqdes
->
refcount
--
;
if
(
mqdes
->
refcount
==
0
)
{
/* delete from posix mqueue list */
if
(
mqdes
->
unlinked
)
posix_mq_delete
(
mqdes
);
/* delete from posix mqueue list */
if
(
mqdes
->
unlinked
)
posix_mq_delete
(
mqdes
);
}
rt_sem_release
(
&
posix_mq_lock
);
...
...
@@ -274,26 +316,28 @@ RTM_EXPORT(mq_close);
int
mq_unlink
(
const
char
*
name
)
{
mqd_t
pmq
;
mqd_t
pmq
;
/* lock posix mqueue list */
rt_sem_take
(
&
posix_mq_lock
,
RT_WAITING_FOREVER
);
pmq
=
posix_mq_find
(
name
);
if
(
pmq
!=
RT_NULL
)
{
pmq
->
unlinked
=
1
;
if
(
pmq
->
refcount
==
0
)
{
/* remove this mqueue */
posix_mq_delete
(
pmq
);
}
pmq
->
unlinked
=
1
;
if
(
pmq
->
refcount
==
0
)
{
/* remove this mqueue */
posix_mq_delete
(
pmq
);
}
rt_sem_release
(
&
posix_mq_lock
);
return
0
;
}
rt_sem_release
(
&
posix_mq_lock
);
/* no this entry */
rt_set_errno
(
ENOENT
);
return
-
1
;
}
RTM_EXPORT
(
mq_unlink
);
components/pthreads/mqueue.h
浏览文件 @
8ab2b287
/*
* File : mqueue.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __MQUEUE_H__
#define __MQUEUE_H__
...
...
@@ -6,38 +29,45 @@
struct
mqdes
{
/* reference count and unlinked */
rt_uint16_t
refcount
;
rt_uint16_t
unlinked
;
/* RT-Thread message queue */
rt_mq_t
mq
;
/* next posix mqueue */
struct
mqdes
*
next
;
/* reference count and unlinked */
rt_uint16_t
refcount
;
rt_uint16_t
unlinked
;
/* RT-Thread message queue */
rt_mq_t
mq
;
/* next posix mqueue */
struct
mqdes
*
next
;
};
typedef
struct
mqdes
*
mqd_t
;
struct
mq_attr
{
long
mq_flags
;
/* Message queue flags. */
long
mq_maxmsg
;
/* Maximum number of messages. */
long
mq_msgsize
;
/* Maximum message size. */
long
mq_curmsgs
;
/* Number of messages currently queued. */
long
mq_flags
;
/* Message queue flags. */
long
mq_maxmsg
;
/* Maximum number of messages. */
long
mq_msgsize
;
/* Maximum message size. */
long
mq_curmsgs
;
/* Number of messages currently queued. */
};
int
mq_close
(
mqd_t
mqdes
);
int
mq_getattr
(
mqd_t
mqdes
,
struct
mq_attr
*
mqstat
);
int
mq_notify
(
mqd_t
mqdes
,
const
struct
sigevent
*
notification
);
mqd_t
mq_open
(
const
char
*
name
,
int
oflag
,
...);
ssize_t
mq_receive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
);
int
mq_send
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
);
int
mq_setattr
(
mqd_t
mqdes
,
const
struct
mq_attr
*
mqstat
,
struct
mq_attr
*
omqstat
);
ssize_t
mq_timedreceive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
,
const
struct
timespec
*
abs_timeout
);
int
mq_timedsend
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
,
const
struct
timespec
*
abs_timeout
);
int
mq_unlink
(
const
char
*
name
);
int
mq_close
(
mqd_t
mqdes
);
int
mq_getattr
(
mqd_t
mqdes
,
struct
mq_attr
*
mqstat
);
int
mq_notify
(
mqd_t
mqdes
,
const
struct
sigevent
*
notification
);
mqd_t
mq_open
(
const
char
*
name
,
int
oflag
,
...);
ssize_t
mq_receive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
);
int
mq_send
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
);
int
mq_setattr
(
mqd_t
mqdes
,
const
struct
mq_attr
*
mqstat
,
struct
mq_attr
*
omqstat
);
ssize_t
mq_timedreceive
(
mqd_t
mqdes
,
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
*
msg_prio
,
const
struct
timespec
*
abs_timeout
);
int
mq_timedsend
(
mqd_t
mqdes
,
const
char
*
msg_ptr
,
size_t
msg_len
,
unsigned
msg_prio
,
const
struct
timespec
*
abs_timeout
);
int
mq_unlink
(
const
char
*
name
);
#endif
components/pthreads/posix_types.h
浏览文件 @
8ab2b287
/*
* File : posix_types.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __POSIX_TYPES_H__
#define __POSIX_TYPES_H__
...
...
@@ -19,177 +42,179 @@
#else
/* ARM compiler and IAR compiler */
#if defined(__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)
#if defined(__CC_ARM) || defined(__IAR_SYSTEMS_ICC__)
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
typedef
rt_int32_t
clockid_t
;
typedef
rt_int32_t
key_t
;
/* Used for interprocess communication. */
typedef
rt_int32_t
pid_t
;
/* Used for process IDs and process group IDs. */
typedef
signed
long
ssize_t
;
/* Used for a count of bytes or an error indication. */
typedef
signed
long
time_t
;
/* Used for time in seconds. */
typedef
rt_int32_t
key_t
;
/* Used for interprocess communication. */
typedef
rt_int32_t
pid_t
;
/* Used for process IDs and process group IDs. */
typedef
signed
long
ssize_t
;
/* Used for a count of bytes or an error indication. */
typedef
signed
long
time_t
;
/* Used for time in seconds. */
struct
timespec
{
time_t
tv_sec
;
/* seconds */
long
tv_nsec
;
/* nanoseconds */
struct
timespec
{
time_t
tv_sec
;
/* seconds */
long
tv_nsec
;
/* nanoseconds */
};
struct
timeval
{
struct
timeval
{
long
tv_sec
;
/* seconds */
long
tv_usec
;
/* microseconds */
};
/* errno definitions */
#define EPERM
1
/* Operation not permitted */
#define ENOENT
2
/* No such file or directory */
#define ESRCH
3
/* No such process */
#define EINTR
4
/* Interrupted system call */
#define EIO
5
/* I/O error */
#define ENXIO
6
/* No such device or address */
#define E2BIG
7
/* Arg list too long */
#define ENOEXEC
8
/* Exec format error */
#define EBADF
9
/* Bad file number */
#define ECHILD
10
/* No child processes */
#define EAGAIN
11
/* Try again */
#define ENOMEM
12
/* Out of memory */
#define EACCES
13
/* Permission denied */
#define EFAULT
14
/* Bad address */
#define ENOTBLK
15
/* Block device required */
#define EBUSY
16
/* Device or resource busy */
#define EEXIST
17
/* File exists */
#define EXDEV
18
/* Cross-device link */
#define ENODEV
19
/* No such device */
#define ENOTDIR
20
/* Not a directory */
#define EISDIR
21
/* Is a directory */
#define EINVAL
22
/* Invalid argument */
#define ENFILE
23
/* File table overflow */
#define EMFILE
24
/* Too many open files */
#define ENOTTY
25
/* Not a typewriter */
#define ETXTBSY
26
/* Text file busy */
#define EFBIG
27
/* File too large */
#define ENOSPC
28
/* No space left on device */
#define ESPIPE
29
/* Illegal seek */
#define EROFS
30
/* Read-only file system */
#define EMLINK
31
/* Too many links */
#define EPIPE
32
/* Broken pipe */
#define EDOM
33
/* Math argument out of domain of func */
#define ERANGE
34
/* Math result not representable */
#define ENOMSG
35
/* No message of desired type */
#define EIDRM
36
/* Identifier removed */
#define ECHRNG
37
/* Channel number out of range */
#define EL2NSYNC
38
/* Level 2 not synchronized */
#define EL3HLT
39
/* Level 3 halted */
#define EL3RST
40
/* Level 3 reset */
#define ELNRNG
41
/* Link number out of range */
#define EUNATCH
42
/* Protocol driver not attached */
#define ENOCSI
43
/* No CSI structure available */
#define EL2HLT
44
/* Level 2 halted */
#define EDEADLK
45
/* Resource deadlock would occur */
#define ENOLCK
46
/* No record locks available */
#define EBADE
50
/* Invalid exchange */
#define EBADR
51
/* Invalid request descriptor */
#define EXFULL
52
/* Exchange full */
#define ENOANO
53
/* No anode */
#define EBADRQC
54
/* Invalid request code */
#define EBADSLT
55
/* Invalid slot */
#define EDEADLOCK
56
/* File locking deadlock error */
#define EBFONT
59
/* Bad font file format */
#define ENOSTR
60
/* Device not a stream */
#define ENODATA
61
/* No data available */
#define ETIME
62
/* Timer expired */
#define ENOSR
63
/* Out of streams resources */
#define ENONET
64
/* Machine is not on the network */
#define ENOPKG
65
/* Package not installed */
#define EREMOTE
66
/* Object is remote */
#define ENOLINK
67
/* Link has been severed */
#define EADV
68
/* Advertise error */
#define ESRMNT
69
/* Srmount error */
#define ECOMM
70
/* Communication error on send */
#define EPROTO
71
/* Protocol error */
#define EDOTDOT
73
/* RFS specific error */
#define EMULTIHOP
74
/* Multihop attempted */
#define EBADMSG
77
/* Not a data message */
#define ENAMETOOLONG
78
/* File name too long */
#define EOVERFLOW
79
/* Value too large for defined data type */
#define ENOTUNIQ
80
/* Name not unique on network */
#define EBADFD
81
/* File descriptor in bad state */
#define EREMCHG
82
/* Remote address changed */
#define ELIBACC
83
/* Can not access a needed shared library */
#define ELIBBAD
84
/* Accessing a corrupted shared library */
#define ELIBSCN
85
/* .lib section in a.out corrupted */
#define ELIBMAX
86
/* Attempting to link in too many shared libraries */
#define ELIBEXEC
87
/* Cannot exec a shared library directly */
#define EILSEQ
88
/* Illegal byte sequence */
#define ENOSYS
89
/* Function not implemented */
#define ELOOP
90
/* Too many symbolic links encountered */
#define ERESTART
91
/* Interrupted system call should be restarted */
#define ESTRPIPE
92
/* Streams pipe error */
#define ENOTEMPTY
93
/* Directory not empty */
#define EUSERS
94
/* Too many users */
#define ENOTSOCK
95
/* Socket operation on non-socket */
#define EDESTADDRREQ
96
/* Destination address required */
#define EMSGSIZE
97
/* Message too long */
#define EPROTOTYPE
98
/* Protocol wrong type for socket */
#define ENOPROTOOPT
99
/* Protocol not available */
#define EPROTONOSUPPORT
120
/* Protocol not supported */
#define ESOCKTNOSUPPORT
121
/* Socket type not supported */
#define EOPNOTSUPP
122
/* Operation not supported on transport endpoint */
#define ENOTSUP
EOPNOTSUPP
/* Operation not supported on transport endpoint */
#define EPFNOSUPPORT
123
/* Protocol family not supported */
#define EAFNOSUPPORT
124
/* Address family not supported by protocol */
#define EADDRINUSE
125
/* Address already in use */
#define EADDRNOTAVAIL
126
/* Cannot assign requested address */
#define ENETDOWN
127
/* Network is down */
#define ENETUNREACH
128
/* Network is unreachable */
#define ENETRESET
129
/* Network dropped connection because of reset */
#define ECONNABORTED
130
/* Software caused connection abort */
#define ECONNRESET
131
/* Connection reset by peer */
#define ENOBUFS
132
/* No buffer space available */
#define EISCONN
133
/* Transport endpoint is already connected */
#define ENOTCONN
134
/* Transport endpoint is not connected */
#define EUCLEAN
135
/* Structure needs cleaning */
#define ENOTNAM
137
/* Not a XENIX named type file */
#define ENAVAIL
138
/* No XENIX semaphores available */
#define EISNAM
139
/* Is a named type file */
#define EREMOTEIO
140
/* Remote I/O error */
#define EINIT
141
/* Reserved */
#define EREMDEV
142
/* Error 142 */
#define ESHUTDOWN
143
/* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS
144
/* Too many references: cannot splice */
#define ETIMEDOUT
145
/* Connection timed out */
#define ECONNREFUSED
146
/* Connection refused */
#define EHOSTDOWN
147
/* Host is down */
#define EHOSTUNREACH
148
/* No route to host */
#define EWOULDBLOCK
EAGAIN
/* Operation would block */
#define EALREADY
149
/* Operation already in progress */
#define EINPROGRESS
150
/* Operation now in progress */
#define ESTALE
151
/* Stale NFS file handle */
#define ECANCELED
158
/* AIO operation canceled */
#define ENOMEDIUM
159
/* No medium found */
#define EMEDIUMTYPE
160
/* Wrong medium type */
#define
ENOKEY 161
/* Required key not available */
#define
EKEYEXPIRED 162
/* Key has expired */
#define
EKEYREVOKED 163
/* Key has been revoked */
#define
EKEYREJECTED 164
/* Key was rejected by service */
#define EDQUOT
1133
/* Quota exceeded */
#define EPERM
1
/* Operation not permitted */
#define ENOENT
2
/* No such file or directory */
#define ESRCH
3
/* No such process */
#define EINTR
4
/* Interrupted system call */
#define EIO
5
/* I/O error */
#define ENXIO
6
/* No such device or address */
#define E2BIG
7
/* Arg list too long */
#define ENOEXEC
8
/* Exec format error */
#define EBADF
9
/* Bad file number */
#define ECHILD
10
/* No child processes */
#define EAGAIN
11
/* Try again */
#define ENOMEM
12
/* Out of memory */
#define EACCES
13
/* Permission denied */
#define EFAULT
14
/* Bad address */
#define ENOTBLK
15
/* Block device required */
#define EBUSY
16
/* Device or resource busy */
#define EEXIST
17
/* File exists */
#define EXDEV
18
/* Cross-device link */
#define ENODEV
19
/* No such device */
#define ENOTDIR
20
/* Not a directory */
#define EISDIR
21
/* Is a directory */
#define EINVAL
22
/* Invalid argument */
#define ENFILE
23
/* File table overflow */
#define EMFILE
24
/* Too many open files */
#define ENOTTY
25
/* Not a typewriter */
#define ETXTBSY
26
/* Text file busy */
#define EFBIG
27
/* File too large */
#define ENOSPC
28
/* No space left on device */
#define ESPIPE
29
/* Illegal seek */
#define EROFS
30
/* Read-only file system */
#define EMLINK
31
/* Too many links */
#define EPIPE
32
/* Broken pipe */
#define EDOM
33
/* Math argument out of domain of func */
#define ERANGE
34
/* Math result not representable */
#define ENOMSG
35
/* No message of desired type */
#define EIDRM
36
/* Identifier removed */
#define ECHRNG
37
/* Channel number out of range */
#define EL2NSYNC
38
/* Level 2 not synchronized */
#define EL3HLT
39
/* Level 3 halted */
#define EL3RST
40
/* Level 3 reset */
#define ELNRNG
41
/* Link number out of range */
#define EUNATCH
42
/* Protocol driver not attached */
#define ENOCSI
43
/* No CSI structure available */
#define EL2HLT
44
/* Level 2 halted */
#define EDEADLK
45
/* Resource deadlock would occur */
#define ENOLCK
46
/* No record locks available */
#define EBADE
50
/* Invalid exchange */
#define EBADR
51
/* Invalid request descriptor */
#define EXFULL
52
/* Exchange full */
#define ENOANO
53
/* No anode */
#define EBADRQC
54
/* Invalid request code */
#define EBADSLT
55
/* Invalid slot */
#define EDEADLOCK
56
/* File locking deadlock error */
#define EBFONT
59
/* Bad font file format */
#define ENOSTR
60
/* Device not a stream */
#define ENODATA
61
/* No data available */
#define ETIME
62
/* Timer expired */
#define ENOSR
63
/* Out of streams resources */
#define ENONET
64
/* Machine is not on the network */
#define ENOPKG
65
/* Package not installed */
#define EREMOTE
66
/* Object is remote */
#define ENOLINK
67
/* Link has been severed */
#define EADV
68
/* Advertise error */
#define ESRMNT
69
/* Srmount error */
#define ECOMM
70
/* Communication error on send */
#define EPROTO
71
/* Protocol error */
#define EDOTDOT
73
/* RFS specific error */
#define EMULTIHOP
74
/* Multihop attempted */
#define EBADMSG
77
/* Not a data message */
#define ENAMETOOLONG
78
/* File name too long */
#define EOVERFLOW
79
/* Value too large for defined data type */
#define ENOTUNIQ
80
/* Name not unique on network */
#define EBADFD
81
/* File descriptor in bad state */
#define EREMCHG
82
/* Remote address changed */
#define ELIBACC
83
/* Can not access a needed shared library */
#define ELIBBAD
84
/* Accessing a corrupted shared library */
#define ELIBSCN
85
/* .lib section in a.out corrupted */
#define ELIBMAX
86
/* Attempting to link in too many shared libraries */
#define ELIBEXEC
87
/* Cannot exec a shared library directly */
#define EILSEQ
88
/* Illegal byte sequence */
#define ENOSYS
89
/* Function not implemented */
#define ELOOP
90
/* Too many symbolic links encountered */
#define ERESTART
91
/* Interrupted system call should be restarted */
#define ESTRPIPE
92
/* Streams pipe error */
#define ENOTEMPTY
93
/* Directory not empty */
#define EUSERS
94
/* Too many users */
#define ENOTSOCK
95
/* Socket operation on non-socket */
#define EDESTADDRREQ
96
/* Destination address required */
#define EMSGSIZE
97
/* Message too long */
#define EPROTOTYPE
98
/* Protocol wrong type for socket */
#define ENOPROTOOPT
99
/* Protocol not available */
#define EPROTONOSUPPORT
120
/* Protocol not supported */
#define ESOCKTNOSUPPORT
121
/* Socket type not supported */
#define EOPNOTSUPP
122
/* Operation not supported on transport endpoint */
#define ENOTSUP
EOPNOTSUPP
/* Operation not supported on transport endpoint */
#define EPFNOSUPPORT
123
/* Protocol family not supported */
#define EAFNOSUPPORT
124
/* Address family not supported by protocol */
#define EADDRINUSE
125
/* Address already in use */
#define EADDRNOTAVAIL
126
/* Cannot assign requested address */
#define ENETDOWN
127
/* Network is down */
#define ENETUNREACH
128
/* Network is unreachable */
#define ENETRESET
129
/* Network dropped connection because of reset */
#define ECONNABORTED
130
/* Software caused connection abort */
#define ECONNRESET
131
/* Connection reset by peer */
#define ENOBUFS
132
/* No buffer space available */
#define EISCONN
133
/* Transport endpoint is already connected */
#define ENOTCONN
134
/* Transport endpoint is not connected */
#define EUCLEAN
135
/* Structure needs cleaning */
#define ENOTNAM
137
/* Not a XENIX named type file */
#define ENAVAIL
138
/* No XENIX semaphores available */
#define EISNAM
139
/* Is a named type file */
#define EREMOTEIO
140
/* Remote I/O error */
#define EINIT
141
/* Reserved */
#define EREMDEV
142
/* Error 142 */
#define ESHUTDOWN
143
/* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS
144
/* Too many references: cannot splice */
#define ETIMEDOUT
145
/* Connection timed out */
#define ECONNREFUSED
146
/* Connection refused */
#define EHOSTDOWN
147
/* Host is down */
#define EHOSTUNREACH
148
/* No route to host */
#define EWOULDBLOCK
EAGAIN
/* Operation would block */
#define EALREADY
149
/* Operation already in progress */
#define EINPROGRESS
150
/* Operation now in progress */
#define ESTALE
151
/* Stale NFS file handle */
#define ECANCELED
158
/* AIO operation canceled */
#define ENOMEDIUM
159
/* No medium found */
#define EMEDIUMTYPE
160
/* Wrong medium type */
#define
ENOKEY 161
/* Required key not available */
#define
EKEYEXPIRED 162
/* Key has expired */
#define
EKEYREVOKED 163
/* Key has been revoked */
#define
EKEYREJECTED 164
/* Key was rejected by service */
#define EDQUOT
1133
/* Quota exceeded */
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#else
typedef
rt_uint16_t
mode_t
;
#define O_RDONLY
0x0000000
#define O_WRONLY
0x0000001
#define O_RDWR
0x0000002
#define O_ACCMODE
0x0000003
#define O_CREAT
0x0000100
#define O_EXCL
0x0000200
#define O_TRUNC
0x0001000
#define O_APPEND
0x0002000
#define O_DIRECTORY
0x0200000
#define O_RDONLY
0x0000000
#define O_WRONLY
0x0000001
#define O_RDWR
0x0000002
#define O_ACCMODE
0x0000003
#define O_CREAT
0x0000100
#define O_EXCL
0x0000200
#define O_TRUNC
0x0001000
#define O_APPEND
0x0002000
#define O_DIRECTORY
0x0200000
#endif
#elif defined (__GNUC__)
/* GNU GCC Compiler, with minilibc */
#elif defined (__GNUC__)
/* GNU GCC Compiler, with minilibc */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
...
...
components/pthreads/pthread.c
浏览文件 @
8ab2b287
此差异已折叠。
点击以展开。
components/pthreads/pthread.h
浏览文件 @
8ab2b287
...
...
@@ -3,31 +3,42 @@
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#ifndef __PTHREAD_H__
#define __PTHREAD_H__
#include <rtthread.h>
#include <posix_types.h>
#define PTHREAD_KEY_MAX
8
#define PTHREAD_KEY_MAX
8
#define PTHREAD_COND_INITIALIZER
{-1, 0}
#define PTHREAD_RWLOCK_INITIALIZER
{-1, 0}
#define PTHREAD_MUTEX_INITIALIZER
{-1, 0}
#define PTHREAD_COND_INITIALIZER
{-1, 0}
#define PTHREAD_RWLOCK_INITIALIZER
{-1, 0}
#define PTHREAD_MUTEX_INITIALIZER
{-1, 0}
#define PTHREAD_CREATE_JOINABLE
0x00
#define PTHREAD_CREATE_DETACHED
0x01
#define PTHREAD_CREATE_JOINABLE
0x00
#define PTHREAD_CREATE_DETACHED
0x01
#define PTHREAD_EXPLICIT_SCHED
0
#define PTHREAD_INHERIT_SCHED
1
#define PTHREAD_EXPLICIT_SCHED
0
#define PTHREAD_INHERIT_SCHED
1
typedef
rt_thread_t
pthread_t
;
typedef
long
pthread_condattr_t
;
...
...
@@ -38,15 +49,17 @@ typedef long pthread_barrierattr_t;
typedef
int
pthread_key_t
;
typedef
int
pthread_once_t
;
enum
{
PTHREAD_CANCEL_ASYNCHRONOUS
=
0
,
PTHREAD_CANCEL_ENABLE
,
PTHREAD_CANCEL_DEFERRED
,
PTHREAD_CANCEL_DISABLE
,
PTHREAD_CANCELED
enum
{
PTHREAD_CANCEL_ASYNCHRONOUS
=
0
,
PTHREAD_CANCEL_ENABLE
,
PTHREAD_CANCEL_DEFERRED
,
PTHREAD_CANCEL_DISABLE
,
PTHREAD_CANCELED
};
enum
{
enum
{
PTHREAD_MUTEX_NORMAL
=
0
,
PTHREAD_MUTEX_RECURSIVE
=
1
,
PTHREAD_MUTEX_ERRORCHECK
=
2
,
...
...
@@ -56,72 +69,73 @@ enum {
};
/* init value for pthread_once_t */
#define PTHREAD_ONCE_INIT
0
#define PTHREAD_ONCE_INIT
0
enum
{
PTHREAD_PRIO_INHERIT
=
0
,
PTHREAD_PRIO_NONE
,
PTHREAD_PRIO_PROTECT
,
enum
{
PTHREAD_PRIO_INHERIT
=
0
,
PTHREAD_PRIO_NONE
,
PTHREAD_PRIO_PROTECT
,
};
#define PTHREAD_PROCESS_PRIVATE 0
#define PTHREAD_PROCESS_SHARED 1
#define PTHREAD_SCOPE_PROCESS
0
#define PTHREAD_SCOPE_SYSTEM
1
#define PTHREAD_SCOPE_PROCESS
0
#define PTHREAD_SCOPE_SYSTEM
1
struct
pthread_attr
{
void
*
stack_base
;
rt_uint16_t
stack_size
;
/* stack size of thread */
void
*
stack_base
;
rt_uint16_t
stack_size
;
/* stack size of thread */
rt_uint8_t
priority
;
/* priority of thread */
rt_uint8_t
detachstate
;
/* detach state */
rt_uint8_t
policy
;
/* scheduler policy */
rt_uint8_t
inheritsched
;
/* Inherit parent prio/policy */
rt_uint8_t
priority
;
/* priority of thread */
rt_uint8_t
detachstate
;
/* detach state */
rt_uint8_t
policy
;
/* scheduler policy */
rt_uint8_t
inheritsched
;
/* Inherit parent prio/policy */
};
typedef
struct
pthread_attr
pthread_attr_t
;
struct
pthread_mutex
{
pthread_mutexattr_t
attr
;
struct
rt_mutex
lock
;
pthread_mutexattr_t
attr
;
struct
rt_mutex
lock
;
};
typedef
struct
pthread_mutex
pthread_mutex_t
;
struct
pthread_cond
{
pthread_condattr_t
attr
;
struct
rt_semaphore
sem
;
pthread_condattr_t
attr
;
struct
rt_semaphore
sem
;
};
typedef
struct
pthread_cond
pthread_cond_t
;
struct
pthread_rwlock
{
pthread_rwlockattr_t
attr
;
pthread_rwlockattr_t
attr
;
pthread_mutex_t
rw_mutex
;
/* basic lock on this struct */
pthread_cond_t
rw_condreaders
;
/* for reader threads waiting */
pthread_cond_t
rw_condwriters
;
/* for writer threads waiting */
pthread_mutex_t
rw_mutex
;
/* basic lock on this struct */
pthread_cond_t
rw_condreaders
;
/* for reader threads waiting */
pthread_cond_t
rw_condwriters
;
/* for writer threads waiting */
int
rw_nwaitreaders
;
/* the number of reader threads waiting */
int
rw_nwaitwriters
;
/* the number of writer threads waiting */
int
rw_refcount
;
/* 0: unlocked, -1: locked by writer, > 0 locked by n readers */
int
rw_nwaitreaders
;
/* the number of reader threads waiting */
int
rw_nwaitwriters
;
/* the number of writer threads waiting */
int
rw_refcount
;
/* 0: unlocked, -1: locked by writer, > 0 locked by n readers */
};
typedef
struct
pthread_rwlock
pthread_rwlock_t
;
/* spinlock implementation, (ADVANCED REALTIME THREADS)*/
struct
pthread_spinlock
{
int
lock
;
int
lock
;
};
typedef
struct
pthread_spinlock
pthread_spinlock_t
;
struct
pthread_barrier
{
int
count
;
pthread_cond_t
cond
;
pthread_mutex_t
mutex
;
int
count
;
pthread_cond_t
cond
;
pthread_mutex_t
mutex
;
};
typedef
struct
pthread_barrier
pthread_barrier_t
;
...
...
@@ -131,19 +145,19 @@ int pthread_attr_init(pthread_attr_t *attr);
int
pthread_system_init
(
void
);
int
pthread_create
(
pthread_t
*
tid
,
const
pthread_attr_t
*
attr
,
void
*
(
*
start
)
(
void
*
),
void
*
arg
);
void
*
(
*
start
)
(
void
*
),
void
*
arg
);
int
pthread_detach
(
pthread_t
thread
);
int
pthread_join
(
pthread_t
thread
,
void
**
value_ptr
);
rt_inline
int
pthread_equal
(
pthread_t
t1
,
pthread_t
t2
)
{
return
t1
==
t2
;
return
t1
==
t2
;
}
rt_inline
pthread_t
pthread_self
(
void
)
{
return
rt_thread_self
();
return
rt_thread_self
();
}
void
pthread_exit
(
void
*
value_ptr
);
...
...
@@ -182,9 +196,9 @@ int pthread_condattr_init(pthread_condattr_t *attr);
/* ADVANCED REALTIME feature in IEEE Std 1003.1, 2004 Edition */
int
pthread_condattr_getclock
(
const
pthread_condattr_t
*
attr
,
clockid_t
*
clock_id
);
clockid_t
*
clock_id
);
int
pthread_condattr_setclock
(
pthread_condattr_t
*
attr
,
clockid_t
clock_id
);
clockid_t
clock_id
);
int
pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
attr
);
int
pthread_cond_destroy
(
pthread_cond_t
*
cond
);
...
...
@@ -192,9 +206,9 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
int
pthread_cond_signal
(
pthread_cond_t
*
cond
);
int
pthread_cond_wait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
);
int
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
);
int
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
);
/* pthread rwlock interface */
int
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
attr
);
...
...
@@ -231,36 +245,39 @@ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshar
int
pthread_barrierattr_setpshared
(
pthread_barrierattr_t
*
attr
,
int
pshared
);
int
pthread_barrier_destroy
(
pthread_barrier_t
*
barrier
);
int
pthread_barrier_init
(
pthread_barrier_t
*
barrier
,
const
pthread_barrierattr_t
*
attr
,
unsigned
count
);
int
pthread_barrier_init
(
pthread_barrier_t
*
barrier
,
const
pthread_barrierattr_t
*
attr
,
unsigned
count
);
int
pthread_barrier_wait
(
pthread_barrier_t
*
barrier
);
/* Signal Generation and Delivery, P1003.1b-1993, p. 63
NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
sigev_notify_attributes to the sigevent structure. */
union
sigval
{
int
sival_int
;
/* Integer signal value */
void
*
sival_ptr
;
/* Pointer signal value */
union
sigval
{
int
sival_int
;
/* Integer signal value */
void
*
sival_ptr
;
/* Pointer signal value */
};
struct
sigevent
{
int
sigev_notify
;
/* Notification type */
int
sigev_signo
;
/* Signal number */
union
sigval
sigev_value
;
/* Signal value */
void
(
*
sigev_notify_function
)(
union
sigval
);
struct
sigevent
{
int
sigev_notify
;
/* Notification type */
int
sigev_signo
;
/* Signal number */
union
sigval
sigev_value
;
/* Signal value */
void
(
*
sigev_notify_function
)(
union
sigval
);
/* Notification function */
pthread_attr_t
*
sigev_notify_attributes
;
/* Notification Attributes */
pthread_attr_t
*
sigev_notify_attributes
;
/* Notification Attributes */
};
/* posix clock and timer */
#define MILLISECOND_PER_SECOND
1000UL
#define MICROSECOND_PER_SECOND
1000000UL
#define NANOSECOND_PER_SECOND
1000000000UL
#define MILLISECOND_PER_SECOND
1000UL
#define MICROSECOND_PER_SECOND
1000000UL
#define NANOSECOND_PER_SECOND
1000000000UL
#define MILLISECOND_PER_TICK
(MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define MICROSECOND_PER_TICK
(MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define NANOSECOND_PER_TICK
(NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define MILLISECOND_PER_TICK
(MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define MICROSECOND_PER_TICK
(MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define NANOSECOND_PER_TICK
(NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND)
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
...
...
components/pthreads/pthread_attr.c
浏览文件 @
8ab2b287
/*
* File : pthread_attr.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <rtthread.h>
#include "pthread.h"
#include "sched.h"
#include <string.h>
#define DEFAULT_STACK_SIZE
2048
#define DEFAULT_PRIORITY
(RT_THREAD_PRIORITY_MAX/2 + RT_THREAD_PRIORITY_MAX/4)
#define DEFAULT_STACK_SIZE
2048
#define DEFAULT_PRIORITY
(RT_THREAD_PRIORITY_MAX/2 + RT_THREAD_PRIORITY_MAX/4)
const
pthread_attr_t
pthread_default_attr
=
{
0
,
/* stack base */
DEFAULT_STACK_SIZE
,
/* stack size */
DEFAULT_PRIORITY
,
/* priority */
PTHREAD_CREATE_JOINABLE
,
/* detach state */
SCHED_FIFO
,
/* scheduler policy */
PTHREAD_INHERIT_SCHED
/* Inherit parent prio/policy */
0
,
/* stack base */
DEFAULT_STACK_SIZE
,
/* stack size */
DEFAULT_PRIORITY
,
/* priority */
PTHREAD_CREATE_JOINABLE
,
/* detach state */
SCHED_FIFO
,
/* scheduler policy */
PTHREAD_INHERIT_SCHED
/* Inherit parent prio/policy */
};
int
pthread_attr_init
(
pthread_attr_t
*
attr
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
*
attr
=
pthread_default_attr
;
*
attr
=
pthread_default_attr
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_init
);
int
pthread_attr_destroy
(
pthread_attr_t
*
attr
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
memset
(
attr
,
0
,
sizeof
(
pthread_attr_t
));
memset
(
attr
,
0
,
sizeof
(
pthread_attr_t
));
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_destroy
);
int
pthread_attr_setdetachstate
(
pthread_attr_t
*
attr
,
int
state
)
int
pthread_attr_setdetachstate
(
pthread_attr_t
*
attr
,
int
state
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
if
(
state
!=
PTHREAD_CREATE_JOINABLE
&&
state
!=
PTHREAD_CREATE_DETACHED
)
return
EINVAL
;
if
(
state
!=
PTHREAD_CREATE_JOINABLE
&&
state
!=
PTHREAD_CREATE_DETACHED
)
return
EINVAL
;
attr
->
detachstate
=
state
;
attr
->
detachstate
=
state
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_setdetachstate
);
int
pthread_attr_getdetachstate
(
pthread_attr_t
const
*
attr
,
int
*
state
)
int
pthread_attr_getdetachstate
(
pthread_attr_t
const
*
attr
,
int
*
state
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
*
state
=
(
int
)
attr
->
detachstate
;
*
state
=
(
int
)
attr
->
detachstate
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_getdetachstate
);
int
pthread_attr_setschedpolicy
(
pthread_attr_t
*
attr
,
int
policy
)
int
pthread_attr_setschedpolicy
(
pthread_attr_t
*
attr
,
int
policy
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
attr
->
policy
=
policy
;
return
0
;
attr
->
policy
=
policy
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_setschedpolicy
);
int
pthread_attr_getschedpolicy
(
pthread_attr_t
const
*
attr
,
int
*
policy
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
*
policy
=
(
int
)
attr
->
policy
;
*
policy
=
(
int
)
attr
->
policy
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_getschedpolicy
);
int
pthread_attr_setschedparam
(
pthread_attr_t
*
attr
,
struct
sched_param
const
*
param
)
int
pthread_attr_setschedparam
(
pthread_attr_t
*
attr
,
struct
sched_param
const
*
param
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
param
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
param
!=
RT_NULL
);
attr
->
priority
=
param
->
sched_priority
;
attr
->
priority
=
param
->
sched_priority
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_setschedparam
);
int
pthread_attr_getschedparam
(
pthread_attr_t
const
*
attr
,
struct
sched_param
*
param
)
int
pthread_attr_getschedparam
(
pthread_attr_t
const
*
attr
,
struct
sched_param
*
param
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
param
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
param
!=
RT_NULL
);
param
->
sched_priority
=
attr
->
priority
;
return
0
;
param
->
sched_priority
=
attr
->
priority
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_getschedparam
);
int
pthread_attr_setstacksize
(
pthread_attr_t
*
attr
,
size_t
stack_size
)
int
pthread_attr_setstacksize
(
pthread_attr_t
*
attr
,
size_t
stack_size
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
attr
->
stack_size
=
stack_size
;
attr
->
stack_size
=
stack_size
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_setstacksize
);
int
pthread_attr_getstacksize
(
pthread_attr_t
const
*
attr
,
size_t
*
stack_size
)
int
pthread_attr_getstacksize
(
pthread_attr_t
const
*
attr
,
size_t
*
stack_size
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
*
stack_size
=
attr
->
stack_size
;
*
stack_size
=
attr
->
stack_size
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_getstacksize
);
int
pthread_attr_setstackaddr
(
pthread_attr_t
*
attr
,
void
*
stack_addr
)
int
pthread_attr_setstackaddr
(
pthread_attr_t
*
attr
,
void
*
stack_addr
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
return
ENOTSUP
;
RT_ASSERT
(
attr
!=
RT_NULL
);
return
ENOTSUP
;
}
RTM_EXPORT
(
pthread_attr_setstackaddr
);
int
pthread_attr_getstackaddr
(
pthread_attr_t
const
*
attr
,
void
**
stack_addr
)
int
pthread_attr_getstackaddr
(
pthread_attr_t
const
*
attr
,
void
**
stack_addr
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
return
ENOTSUP
;
RT_ASSERT
(
attr
!=
RT_NULL
);
return
ENOTSUP
;
}
RTM_EXPORT
(
pthread_attr_getstackaddr
);
int
pthread_attr_setstack
(
pthread_attr_t
*
attr
,
void
*
stack_base
,
size_t
stack_size
)
int
pthread_attr_setstack
(
pthread_attr_t
*
attr
,
void
*
stack_base
,
size_t
stack_size
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
attr
->
stack_base
=
stack_base
;
attr
->
stack_size
=
RT_ALIGN_DOWN
(
stack_size
,
RT_ALIGN_SIZE
);
attr
->
stack_base
=
stack_base
;
attr
->
stack_size
=
RT_ALIGN_DOWN
(
stack_size
,
RT_ALIGN_SIZE
);
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_setstack
);
int
pthread_attr_getstack
(
pthread_attr_t
const
*
attr
,
void
**
stack_base
,
size_t
*
stack_size
)
int
pthread_attr_getstack
(
pthread_attr_t
const
*
attr
,
void
**
stack_base
,
size_t
*
stack_size
)
{
RT_ASSERT
(
attr
!=
RT_NULL
);
RT_ASSERT
(
attr
!=
RT_NULL
);
*
stack_base
=
attr
->
stack_base
;
*
stack_size
=
attr
->
stack_size
;
*
stack_base
=
attr
->
stack_base
;
*
stack_size
=
attr
->
stack_size
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_attr_getstack
);
int
pthread_attr_setguardsize
(
pthread_attr_t
*
attr
,
size_t
guard_size
)
int
pthread_attr_setguardsize
(
pthread_attr_t
*
attr
,
size_t
guard_size
)
{
return
ENOTSUP
;
return
ENOTSUP
;
}
int
pthread_attr_getguardsize
(
pthread_attr_t
const
*
attr
,
size_t
*
guard_size
)
int
pthread_attr_getguardsize
(
pthread_attr_t
const
*
attr
,
size_t
*
guard_size
)
{
return
ENOTSUP
;
return
ENOTSUP
;
}
RTM_EXPORT
(
pthread_attr_getguardsize
);
...
...
components/pthreads/pthread_barrier.c
浏览文件 @
8ab2b287
/*
* File : pthread_barrier.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <pthread.h>
int
pthread_barrierattr_destroy
(
pthread_barrierattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
return
0
;
if
(
!
attr
)
return
EINVAL
;
return
0
;
}
RTM_EXPORT
(
pthread_barrierattr_destroy
);
int
pthread_barrierattr_init
(
pthread_barrierattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_barrierattr_init
);
int
pthread_barrierattr_getpshared
(
const
pthread_barrierattr_t
*
attr
,
int
*
pshared
)
int
pthread_barrierattr_getpshared
(
const
pthread_barrierattr_t
*
attr
,
int
*
pshared
)
{
if
(
!
attr
)
return
EINVAL
;
*
pshared
=
(
int
)
*
attr
;
if
(
!
attr
)
return
EINVAL
;
*
pshared
=
(
int
)
*
attr
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_barrierattr_getpshared
);
int
pthread_barrierattr_setpshared
(
pthread_barrierattr_t
*
attr
,
int
pshared
)
{
if
(
!
attr
)
return
EINVAL
;
if
(
pshared
==
PTHREAD_PROCESS_PRIVATE
)
attr
=
PTHREAD_PROCESS_PRIVATE
;
if
(
!
attr
)
return
EINVAL
;
if
(
pshared
==
PTHREAD_PROCESS_PRIVATE
)
attr
=
PTHREAD_PROCESS_PRIVATE
;
return
EINVAL
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_barrierattr_setpshared
);
int
pthread_barrier_destroy
(
pthread_barrier_t
*
barrier
)
{
rt_err_t
result
;
rt_err_t
result
;
if
(
!
barrier
)
return
EINVAL
;
if
(
!
barrier
)
return
EINVAL
;
result
=
pthread_cond_destroy
(
&
(
barrier
->
cond
));
result
=
pthread_cond_destroy
(
&
(
barrier
->
cond
));
return
result
;
return
result
;
}
RTM_EXPORT
(
pthread_barrier_destroy
);
int
pthread_barrier_init
(
pthread_barrier_t
*
barrier
,
const
pthread_barrierattr_t
*
attr
,
unsigned
count
)
int
pthread_barrier_init
(
pthread_barrier_t
*
barrier
,
const
pthread_barrierattr_t
*
attr
,
unsigned
count
)
{
if
(
!
barrier
)
return
EINVAL
;
if
(
attr
&&
(
*
attr
!=
PTHREAD_PROCESS_PRIVATE
))
return
EINVAL
;
if
(
!
barrier
)
return
EINVAL
;
if
(
attr
&&
(
*
attr
!=
PTHREAD_PROCESS_PRIVATE
))
return
EINVAL
;
barrier
->
count
=
count
;
pthread_cond_init
(
&
(
barrier
->
cond
),
NULL
);
pthread_mutex_init
(
&
(
barrier
->
mutex
),
NULL
);
barrier
->
count
=
count
;
pthread_cond_init
(
&
(
barrier
->
cond
),
NULL
);
pthread_mutex_init
(
&
(
barrier
->
mutex
),
NULL
);
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_barrier_init
);
int
pthread_barrier_wait
(
pthread_barrier_t
*
barrier
)
{
rt_err_t
result
;
if
(
!
barrier
)
return
EINVAL
;
result
=
pthread_mutex_lock
(
&
(
barrier
->
mutex
));
if
(
result
!=
0
)
return
EINVAL
;
if
(
barrier
->
count
==
0
)
result
=
EINVAL
;
else
{
barrier
->
count
-=
1
;
if
(
barrier
->
count
==
0
)
/* broadcast condition */
pthread_cond_broadcast
(
&
(
barrier
->
cond
));
else
pthread_cond_wait
(
&
(
barrier
->
cond
),
&
(
barrier
->
mutex
));
}
pthread_mutex_unlock
(
&
(
barrier
->
mutex
));
return
result
;
rt_err_t
result
;
if
(
!
barrier
)
return
EINVAL
;
result
=
pthread_mutex_lock
(
&
(
barrier
->
mutex
));
if
(
result
!=
0
)
return
EINVAL
;
if
(
barrier
->
count
==
0
)
result
=
EINVAL
;
else
{
barrier
->
count
-=
1
;
if
(
barrier
->
count
==
0
)
/* broadcast condition */
pthread_cond_broadcast
(
&
(
barrier
->
cond
));
else
pthread_cond_wait
(
&
(
barrier
->
cond
),
&
(
barrier
->
mutex
));
}
pthread_mutex_unlock
(
&
(
barrier
->
mutex
));
return
result
;
}
RTM_EXPORT
(
pthread_barrier_wait
);
components/pthreads/pthread_cond.c
浏览文件 @
8ab2b287
/*
* File : pthread_cond.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <pthread.h>
#include "pthread_internal.h"
int
pthread_condattr_destroy
(
pthread_condattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
if
(
!
attr
)
return
EINVAL
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_destroy
);
int
pthread_condattr_init
(
pthread_condattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_init
);
int
pthread_condattr_getclock
(
const
pthread_condattr_t
*
attr
,
clockid_t
*
clock_id
)
clockid_t
*
clock_id
)
{
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_getclock
);
int
pthread_condattr_setclock
(
pthread_condattr_t
*
attr
,
clockid_t
clock_id
)
clockid_t
clock_id
)
{
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_setclock
);
int
pthread_condattr_getpshared
(
const
pthread_condattr_t
*
attr
,
int
*
pshared
)
{
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
*
pshared
=
PTHREAD_PROCESS_PRIVATE
;
*
pshared
=
PTHREAD_PROCESS_PRIVATE
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_getpshared
);
int
pthread_condattr_setpshared
(
pthread_condattr_t
*
attr
,
int
pshared
)
{
if
((
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
&&
(
pshared
!=
PTHREAD_PROCESS_SHARED
))
return
EINVAL
;
if
((
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
&&
(
pshared
!=
PTHREAD_PROCESS_SHARED
))
{
return
EINVAL
;
}
if
(
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
return
ENOSYS
;
if
(
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
return
ENOSYS
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_condattr_setpshared
);
int
pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
attr
)
{
rt_err_t
result
;
char
cond_name
[
RT_NAME_MAX
];
static
rt_uint16_t
cond_num
=
0
;
rt_err_t
result
;
char
cond_name
[
RT_NAME_MAX
];
static
rt_uint16_t
cond_num
=
0
;
/* parameter check */
if
(
cond
==
RT_NULL
)
return
EINVAL
;
if
((
attr
!=
RT_NULL
)
&&
(
*
attr
!=
PTHREAD_PROCESS_PRIVATE
))
return
EINVAL
;
/* parameter check */
if
(
cond
==
RT_NULL
)
return
EINVAL
;
if
((
attr
!=
RT_NULL
)
&&
(
*
attr
!=
PTHREAD_PROCESS_PRIVATE
))
return
EINVAL
;
rt_snprintf
(
cond_name
,
sizeof
(
cond_name
),
"cond%02d"
,
cond_num
++
);
rt_snprintf
(
cond_name
,
sizeof
(
cond_name
),
"cond%02d"
,
cond_num
++
);
cond
->
attr
=
*
attr
;
result
=
rt_sem_init
(
&
cond
->
sem
,
cond_name
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
result
!=
RT_EOK
)
return
EINVAL
;
cond
->
attr
=
*
attr
;
result
=
rt_sem_init
(
&
cond
->
sem
,
cond_name
,
0
,
RT_IPC_FLAG_FIFO
);
if
(
result
!=
RT_EOK
)
return
EINVAL
;
/* detach the object from system object container */
rt_object_detach
(
&
(
cond
->
sem
.
parent
.
parent
));
/* detach the object from system object container */
rt_object_detach
(
&
(
cond
->
sem
.
parent
.
parent
));
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_cond_init
);
int
pthread_cond_destroy
(
pthread_cond_t
*
cond
)
{
rt_err_t
result
;
if
(
cond
==
RT_NULL
)
return
EINVAL
;
if
(
cond
->
attr
==
-
1
)
return
0
;
/* which is not initialized */
rt_err_t
result
;
if
(
cond
==
RT_NULL
)
return
EINVAL
;
if
(
cond
->
attr
==
-
1
)
return
0
;
/* which is not initialized */
result
=
rt_sem_trytake
(
&
(
cond
->
sem
));
if
(
result
!=
RT_EOK
)
return
EBUSY
;
result
=
rt_sem_trytake
(
&
(
cond
->
sem
));
if
(
result
!=
RT_EOK
)
return
EBUSY
;
/* clean condition */
rt_memset
(
cond
,
0
,
sizeof
(
pthread_cond_t
));
cond
->
attr
=
-
1
;
/* clean condition */
rt_memset
(
cond
,
0
,
sizeof
(
pthread_cond_t
));
cond
->
attr
=
-
1
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_cond_destroy
);
int
pthread_cond_broadcast
(
pthread_cond_t
*
cond
)
{
rt_err_t
result
;
if
(
cond
->
attr
==
-
1
)
pthread_cond_init
(
cond
,
RT_NULL
);
rt_enter_critical
();
while
(
1
)
{
/* try to take condition semaphore */
result
=
rt_sem_trytake
(
&
(
cond
->
sem
));
if
(
result
==
-
RT_ETIMEOUT
)
{
/* it's timeout, release this semaphore */
rt_sem_release
(
&
(
cond
->
sem
));
}
else
if
(
result
==
RT_EOK
)
{
/* has taken this semaphore, release it */
rt_sem_release
(
&
(
cond
->
sem
));
break
;
}
else
{
rt_exit_critical
();
return
EINVAL
;
}
}
rt_exit_critical
();
return
0
;
rt_err_t
result
;
if
(
cond
->
attr
==
-
1
)
pthread_cond_init
(
cond
,
RT_NULL
);
rt_enter_critical
();
while
(
1
)
{
/* try to take condition semaphore */
result
=
rt_sem_trytake
(
&
(
cond
->
sem
));
if
(
result
==
-
RT_ETIMEOUT
)
{
/* it's timeout, release this semaphore */
rt_sem_release
(
&
(
cond
->
sem
));
}
else
if
(
result
==
RT_EOK
)
{
/* has taken this semaphore, release it */
rt_sem_release
(
&
(
cond
->
sem
));
break
;
}
else
{
rt_exit_critical
();
return
EINVAL
;
}
}
rt_exit_critical
();
return
0
;
}
RTM_EXPORT
(
pthread_cond_broadcast
);
int
pthread_cond_signal
(
pthread_cond_t
*
cond
)
{
rt_err_t
result
;
rt_err_t
result
;
if
(
cond
->
attr
==
-
1
)
pthread_cond_init
(
cond
,
RT_NULL
);
if
(
cond
->
attr
==
-
1
)
pthread_cond_init
(
cond
,
RT_NULL
);
result
=
rt_sem_release
(
&
(
cond
->
sem
));
if
(
result
==
RT_EOK
)
return
0
;
result
=
rt_sem_release
(
&
(
cond
->
sem
));
if
(
result
==
RT_EOK
)
return
0
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_cond_signal
);
rt_err_t
_pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
rt_int32_t
timeout
)
rt_err_t
_pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
rt_int32_t
timeout
)
{
rt_err_t
result
;
if
(
!
cond
||
!
mutex
)
return
-
RT_ERROR
;
/* check whether initialized */
if
(
cond
->
attr
==
-
1
)
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
!=
pthread_self
())
return
-
RT_ERROR
;
/* unlock a mutex failed */
if
(
pthread_mutex_unlock
(
mutex
)
!=
0
)
return
-
RT_ERROR
;
result
=
rt_sem_take
(
&
(
cond
->
sem
),
timeout
);
/* lock mutex again */
pthread_mutex_lock
(
mutex
);
return
result
;
rt_err_t
result
;
if
(
!
cond
||
!
mutex
)
return
-
RT_ERROR
;
/* check whether initialized */
if
(
cond
->
attr
==
-
1
)
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
!=
pthread_self
())
return
-
RT_ERROR
;
/* unlock a mutex failed */
if
(
pthread_mutex_unlock
(
mutex
)
!=
0
)
return
-
RT_ERROR
;
result
=
rt_sem_take
(
&
(
cond
->
sem
),
timeout
);
/* lock mutex again */
pthread_mutex_lock
(
mutex
);
return
result
;
}
RTM_EXPORT
(
_pthread_cond_timedwait
);
int
pthread_cond_wait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
)
{
rt_err_t
result
;
rt_err_t
result
;
result
=
_pthread_cond_timedwait
(
cond
,
mutex
,
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
0
;
result
=
_pthread_cond_timedwait
(
cond
,
mutex
,
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
0
;
return
EINVAL
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_cond_wait
);
int
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
)
int
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
)
{
int
timeout
;
rt_err_t
result
;
int
timeout
;
rt_err_t
result
;
timeout
=
clock_time_to_tick
(
abstime
);
result
=
_pthread_cond_timedwait
(
cond
,
mutex
,
timeout
);
if
(
result
==
RT_EOK
)
return
0
;
if
(
result
==
-
RT_ETIMEOUT
)
return
ETIMEDOUT
;
timeout
=
clock_time_to_tick
(
abstime
);
result
=
_pthread_cond_timedwait
(
cond
,
mutex
,
timeout
);
if
(
result
==
RT_EOK
)
return
0
;
if
(
result
==
-
RT_ETIMEOUT
)
return
ETIMEDOUT
;
return
EINVAL
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_cond_timedwait
);
components/pthreads/pthread_internal.h
浏览文件 @
8ab2b287
/*
* File : pthread_internal.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#ifndef __PTHREAD_INTERNAL_H__
#define __PTHREAD_INTERNAL_H__
...
...
@@ -6,56 +30,56 @@
struct
_pthread_cleanup
{
void
(
*
cleanup_func
)(
void
*
parameter
);
void
*
parameter
;
void
(
*
cleanup_func
)(
void
*
parameter
);
void
*
parameter
;
struct
_pthread_cleanup
*
next
;
struct
_pthread_cleanup
*
next
;
};
typedef
struct
_pthread_cleanup
_pthread_cleanup_t
;
struct
_pthread_key_data
{
int
is_used
;
void
(
*
destructor
)(
void
*
parameter
);
int
is_used
;
void
(
*
destructor
)(
void
*
parameter
);
};
typedef
struct
_pthread_key_data
_pthread_key_data_t
;
#define PTHREAD_MAGIC
0x70746873
#define PTHREAD_MAGIC
0x70746873
struct
_pthread_data
{
rt_uint32_t
magic
;
pthread_attr_t
attr
;
rt_thread_t
tid
;
rt_uint32_t
magic
;
pthread_attr_t
attr
;
rt_thread_t
tid
;
void
*
(
*
thread_entry
)(
void
*
parameter
);
void
*
thread_parameter
;
void
*
(
*
thread_entry
)(
void
*
parameter
);
void
*
thread_parameter
;
/* return value */
void
*
return_value
;
/* return value */
void
*
return_value
;
/* semaphore for joinable thread */
rt_sem_t
joinable_sem
;
/* semaphore for joinable thread */
rt_sem_t
joinable_sem
;
/* cancel state and type */
rt_uint8_t
cancelstate
;
volatile
rt_uint8_t
canceltype
;
volatile
rt_uint8_t
canceled
;
/* cancel state and type */
rt_uint8_t
cancelstate
;
volatile
rt_uint8_t
canceltype
;
volatile
rt_uint8_t
canceled
;
_pthread_cleanup_t
*
cleanup
;
void
**
tls
;
/* thread-local storage area */
_pthread_cleanup_t
*
cleanup
;
void
**
tls
;
/* thread-local storage area */
};
typedef
struct
_pthread_data
_pthread_data_t
;
rt_inline
_pthread_data_t
*
_pthread_get_data
(
pthread_t
thread
)
rt_inline
_pthread_data_t
*
_pthread_get_data
(
pthread_t
thread
)
{
_pthread_data_t
*
ptd
;
RT_ASSERT
(
thread
!=
RT_NULL
);
_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
);
ptd
=
(
_pthread_data_t
*
)
thread
->
user_data
;
RT_ASSERT
(
ptd
!=
RT_NULL
);
RT_ASSERT
(
ptd
->
magic
==
PTHREAD_MAGIC
);
return
ptd
;
return
ptd
;
}
int
clock_time_to_tick
(
const
struct
timespec
*
time
);
...
...
components/pthreads/pthread_mutex.c
浏览文件 @
8ab2b287
/*
* File : pthread_mutex.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <rtthread.h>
#include "pthread.h"
...
...
@@ -8,51 +32,54 @@ const pthread_mutexattr_t pthread_default_mutexattr = PTHREAD_PROCESS_PRIVATE;
int
pthread_mutexattr_init
(
pthread_mutexattr_t
*
attr
)
{
if
(
attr
)
{
*
attr
=
pthread_default_mutexattr
;
return
0
;
}
if
(
attr
)
{
*
attr
=
pthread_default_mutexattr
;
return
EINVAL
;
return
0
;
}
return
EINVAL
;
}
RTM_EXPORT
(
pthread_mutexattr_init
);
int
pthread_mutexattr_destroy
(
pthread_mutexattr_t
*
attr
)
{
if
(
attr
)
{
*
attr
=
-
1
;
return
0
;
}
if
(
attr
)
{
*
attr
=
-
1
;
return
EINVAL
;
return
0
;
}
return
EINVAL
;
}
RTM_EXPORT
(
pthread_mutexattr_destroy
);
int
pthread_mutexattr_gettype
(
const
pthread_mutexattr_t
*
attr
,
int
*
type
)
{
if
(
attr
&&
type
)
{
if
(
attr
&&
type
)
{
int
atype
=
(
*
attr
&
MUTEXATTR_TYPE_MASK
);
if
(
atype
>=
PTHREAD_MUTEX_NORMAL
&&
atype
<=
PTHREAD_MUTEX_ERRORCHECK
)
{
*
type
=
atype
;
return
0
;
}
}
if
(
atype
>=
PTHREAD_MUTEX_NORMAL
&&
atype
<=
PTHREAD_MUTEX_ERRORCHECK
)
{
*
type
=
atype
;
return
EINVAL
;
return
0
;
}
}
return
EINVAL
;
}
RTM_EXPORT
(
pthread_mutexattr_gettype
);
int
pthread_mutexattr_settype
(
pthread_mutexattr_t
*
attr
,
int
type
)
{
if
(
attr
&&
type
>=
PTHREAD_MUTEX_NORMAL
&&
type
<=
PTHREAD_MUTEX_ERRORCHECK
)
{
if
(
attr
&&
type
>=
PTHREAD_MUTEX_NORMAL
&&
type
<=
PTHREAD_MUTEX_ERRORCHECK
)
{
*
attr
=
(
*
attr
&
~
MUTEXATTR_TYPE_MASK
)
|
type
;
return
0
;
}
...
...
@@ -60,12 +87,13 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
}
RTM_EXPORT
(
pthread_mutexattr_settype
);
int
pthread_mutexattr_setpshared
(
pthread_mutexattr_t
*
attr
,
int
pshared
)
int
pthread_mutexattr_setpshared
(
pthread_mutexattr_t
*
attr
,
int
pshared
)
{
if
(
!
attr
)
return
EINVAL
;
if
(
!
attr
)
return
EINVAL
;
switch
(
pshared
)
{
{
case
PTHREAD_PROCESS_PRIVATE
:
*
attr
&=
~
MUTEXATTR_SHARED_MASK
;
return
0
;
...
...
@@ -81,7 +109,8 @@ RTM_EXPORT(pthread_mutexattr_setpshared);
int
pthread_mutexattr_getpshared
(
pthread_mutexattr_t
*
attr
,
int
*
pshared
)
{
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
*
pshared
=
(
*
attr
&
MUTEXATTR_SHARED_MASK
)
?
PTHREAD_PROCESS_SHARED
:
PTHREAD_PROCESS_PRIVATE
;
...
...
@@ -91,116 +120,132 @@ RTM_EXPORT(pthread_mutexattr_getpshared);
int
pthread_mutex_init
(
pthread_mutex_t
*
mutex
,
const
pthread_mutexattr_t
*
attr
)
{
rt_err_t
result
;
char
name
[
RT_NAME_MAX
];
static
rt_uint16_t
pthread_mutex_number
=
0
;
rt_err_t
result
;
char
name
[
RT_NAME_MAX
];
static
rt_uint16_t
pthread_mutex_number
=
0
;
if
(
!
mutex
)
return
EINVAL
;
if
(
!
mutex
)
return
EINVAL
;
/* build mutex name */
rt_snprintf
(
name
,
sizeof
(
name
),
"pmtx%02d"
,
pthread_mutex_number
++
);
if
(
attr
==
RT_NULL
)
mutex
->
attr
=
pthread_default_mutexattr
;
else
mutex
->
attr
=
*
attr
;
/* build mutex name */
rt_snprintf
(
name
,
sizeof
(
name
),
"pmtx%02d"
,
pthread_mutex_number
++
);
if
(
attr
==
RT_NULL
)
mutex
->
attr
=
pthread_default_mutexattr
;
else
mutex
->
attr
=
*
attr
;
/* init mutex lock */
result
=
rt_mutex_init
(
&
(
mutex
->
lock
),
name
,
RT_IPC_FLAG_FIFO
);
if
(
result
!=
RT_EOK
)
return
EINVAL
;
/* init mutex lock */
result
=
rt_mutex_init
(
&
(
mutex
->
lock
),
name
,
RT_IPC_FLAG_FIFO
);
if
(
result
!=
RT_EOK
)
return
EINVAL
;
/* detach the object from system object container */
rt_object_detach
(
&
(
mutex
->
lock
.
parent
.
parent
));
/* detach the object from system object container */
rt_object_detach
(
&
(
mutex
->
lock
.
parent
.
parent
));
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_mutex_init
);
int
pthread_mutex_destroy
(
pthread_mutex_t
*
mutex
)
{
if
(
!
mutex
||
mutex
->
attr
==
-
1
)
return
EINVAL
;
if
(
!
mutex
||
mutex
->
attr
==
-
1
)
return
EINVAL
;
/* it's busy */
if
(
mutex
->
lock
.
owner
!=
RT_NULL
)
return
EBUSY
;
/* it's busy */
if
(
mutex
->
lock
.
owner
!=
RT_NULL
)
return
EBUSY
;
rt_memset
(
mutex
,
0
,
sizeof
(
pthread_mutex_t
));
mutex
->
attr
=
-
1
;
rt_memset
(
mutex
,
0
,
sizeof
(
pthread_mutex_t
));
mutex
->
attr
=
-
1
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_mutex_destroy
);
int
pthread_mutex_lock
(
pthread_mutex_t
*
mutex
)
{
int
mtype
;
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
mtype
=
mutex
->
attr
&
MUTEXATTR_TYPE_MASK
;
rt_enter_critical
();
if
(
mutex
->
lock
.
owner
==
rt_thread_self
()
&&
mtype
!=
PTHREAD_MUTEX_RECURSIVE
)
{
rt_exit_critical
();
return
EDEADLK
;
}
rt_exit_critical
();
result
=
rt_mutex_take
(
&
(
mutex
->
lock
),
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
0
;
return
EINVAL
;
int
mtype
;
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
mtype
=
mutex
->
attr
&
MUTEXATTR_TYPE_MASK
;
rt_enter_critical
();
if
(
mutex
->
lock
.
owner
==
rt_thread_self
()
&&
mtype
!=
PTHREAD_MUTEX_RECURSIVE
)
{
rt_exit_critical
();
return
EDEADLK
;
}
rt_exit_critical
();
result
=
rt_mutex_take
(
&
(
mutex
->
lock
),
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
return
0
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_mutex_lock
);
int
pthread_mutex_unlock
(
pthread_mutex_t
*
mutex
)
{
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
if
(
mutex
->
lock
.
owner
!=
rt_thread_self
())
{
int
mtype
;
mtype
=
mutex
->
attr
&
MUTEXATTR_TYPE_MASK
;
/* error check, return EPERM */
if
(
mtype
==
PTHREAD_MUTEX_ERRORCHECK
)
return
EPERM
;
/* no thread waiting on this mutex */
if
(
mutex
->
lock
.
owner
==
RT_NULL
)
return
0
;
}
result
=
rt_mutex_release
(
&
(
mutex
->
lock
));
if
(
result
==
RT_EOK
)
return
0
;
return
EINVAL
;
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
if
(
mutex
->
lock
.
owner
!=
rt_thread_self
())
{
int
mtype
;
mtype
=
mutex
->
attr
&
MUTEXATTR_TYPE_MASK
;
/* error check, return EPERM */
if
(
mtype
==
PTHREAD_MUTEX_ERRORCHECK
)
return
EPERM
;
/* no thread waiting on this mutex */
if
(
mutex
->
lock
.
owner
==
RT_NULL
)
return
0
;
}
result
=
rt_mutex_release
(
&
(
mutex
->
lock
));
if
(
result
==
RT_EOK
)
return
0
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_mutex_unlock
);
int
pthread_mutex_trylock
(
pthread_mutex_t
*
mutex
)
{
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
rt_err_t
result
;
if
(
!
mutex
)
return
EINVAL
;
if
(
mutex
->
attr
==
-
1
)
{
/* init mutex */
pthread_mutex_init
(
mutex
,
RT_NULL
);
}
result
=
rt_mutex_take
(
&
(
mutex
->
lock
),
0
);
if
(
result
==
RT_EOK
)
return
0
;
result
=
rt_mutex_take
(
&
(
mutex
->
lock
),
0
);
if
(
result
==
RT_EOK
)
return
0
;
return
EBUSY
;
return
EBUSY
;
}
RTM_EXPORT
(
pthread_mutex_trylock
);
components/pthreads/pthread_rwlock.c
浏览文件 @
8ab2b287
/*
* File : pthread_rwlock.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <pthread.h>
int
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
attr
)
int
pthread_rwlockattr_init
(
pthread_rwlockattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
if
(
!
attr
)
return
EINVAL
;
*
attr
=
PTHREAD_PROCESS_PRIVATE
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_rwlockattr_init
);
int
pthread_rwlockattr_destroy
(
pthread_rwlockattr_t
*
attr
)
int
pthread_rwlockattr_destroy
(
pthread_rwlockattr_t
*
attr
)
{
if
(
!
attr
)
return
EINVAL
;
if
(
!
attr
)
return
EINVAL
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_rwlockattr_destroy
);
int
pthread_rwlockattr_getpshared
(
const
pthread_rwlockattr_t
*
attr
,
int
*
pshared
)
int
pthread_rwlockattr_getpshared
(
const
pthread_rwlockattr_t
*
attr
,
int
*
pshared
)
{
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
if
(
!
attr
||
!
pshared
)
return
EINVAL
;
*
pshared
=
PTHREAD_PROCESS_PRIVATE
;
*
pshared
=
PTHREAD_PROCESS_PRIVATE
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_rwlockattr_getpshared
);
int
pthread_rwlockattr_setpshared
(
pthread_rwlockattr_t
*
attr
,
int
pshared
)
int
pthread_rwlockattr_setpshared
(
pthread_rwlockattr_t
*
attr
,
int
pshared
)
{
if
(
!
attr
||
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
return
EINVAL
;
if
(
!
attr
||
pshared
!=
PTHREAD_PROCESS_PRIVATE
)
return
EINVAL
;
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_rwlockattr_setpshared
);
int
pthread_rwlock_init
(
pthread_rwlock_t
*
rwlock
,
const
pthread_rwlockattr_t
*
attr
)
int
pthread_rwlock_init
(
pthread_rwlock_t
*
rwlock
,
const
pthread_rwlockattr_t
*
attr
)
{
if
(
!
rwlock
)
return
EINVAL
;
rwlock
->
attr
=
PTHREAD_PROCESS_PRIVATE
;
pthread_mutex_init
(
&
(
rwlock
->
rw_mutex
),
NULL
);
pthread_cond_init
(
&
(
rwlock
->
rw_condreaders
),
NULL
);
pthread_cond_init
(
&
(
rwlock
->
rw_condwriters
),
NULL
);
rwlock
->
rw_nwaitwriters
=
0
;
rwlock
->
rw_nwaitreaders
=
0
;
rwlock
->
rw_refcount
=
0
;
return
0
;
if
(
!
rwlock
)
return
EINVAL
;
rwlock
->
attr
=
PTHREAD_PROCESS_PRIVATE
;
pthread_mutex_init
(
&
(
rwlock
->
rw_mutex
),
NULL
);
pthread_cond_init
(
&
(
rwlock
->
rw_condreaders
),
NULL
);
pthread_cond_init
(
&
(
rwlock
->
rw_condwriters
),
NULL
);
rwlock
->
rw_nwaitwriters
=
0
;
rwlock
->
rw_nwaitreaders
=
0
;
rwlock
->
rw_refcount
=
0
;
return
0
;
}
RTM_EXPORT
(
pthread_rwlock_init
);
int
pthread_rwlock_destroy
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
return
0
;
/* rwlock is not initialized */
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
!=
0
||
rwlock
->
rw_nwaitreaders
!=
0
||
rwlock
->
rw_nwaitwriters
!=
0
)
{
result
=
EBUSY
;
return
(
EBUSY
);
}
else
{
/* check whether busy */
result
=
rt_sem_trytake
(
&
(
rwlock
->
rw_condreaders
.
sem
));
if
(
result
==
RT_EOK
)
{
result
=
rt_sem_trytake
(
&
(
rwlock
->
rw_condwriters
.
sem
));
if
(
result
==
RT_EOK
)
{
rt_sem_release
(
&
(
rwlock
->
rw_condreaders
.
sem
));
rt_sem_release
(
&
(
rwlock
->
rw_condwriters
.
sem
));
pthread_cond_destroy
(
&
rwlock
->
rw_condreaders
);
pthread_cond_destroy
(
&
rwlock
->
rw_condwriters
);
}
else
{
rt_sem_release
(
&
(
rwlock
->
rw_condreaders
.
sem
));
result
=
EBUSY
;
}
}
else
result
=
EBUSY
;
}
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
if
(
result
==
0
)
pthread_mutex_destroy
(
&
rwlock
->
rw_mutex
);
return
result
;
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
return
0
;
/* rwlock is not initialized */
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
!=
0
||
rwlock
->
rw_nwaitreaders
!=
0
||
rwlock
->
rw_nwaitwriters
!=
0
)
{
result
=
EBUSY
;
return
(
EBUSY
);
}
else
{
/* check whether busy */
result
=
rt_sem_trytake
(
&
(
rwlock
->
rw_condreaders
.
sem
));
if
(
result
==
RT_EOK
)
{
result
=
rt_sem_trytake
(
&
(
rwlock
->
rw_condwriters
.
sem
));
if
(
result
==
RT_EOK
)
{
rt_sem_release
(
&
(
rwlock
->
rw_condreaders
.
sem
));
rt_sem_release
(
&
(
rwlock
->
rw_condwriters
.
sem
));
pthread_cond_destroy
(
&
rwlock
->
rw_condreaders
);
pthread_cond_destroy
(
&
rwlock
->
rw_condwriters
);
}
else
{
rt_sem_release
(
&
(
rwlock
->
rw_condreaders
.
sem
));
result
=
EBUSY
;
}
}
else
result
=
EBUSY
;
}
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
if
(
result
==
0
)
pthread_mutex_destroy
(
&
rwlock
->
rw_mutex
);
return
result
;
}
RTM_EXPORT
(
pthread_rwlock_destroy
);
int
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
rwlock
)
int
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
/* give preference to waiting writers */
while
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
{
rwlock
->
rw_nwaitreaders
++
;
/* rw_mutex will be released when waiting for rw_condreaders */
result
=
pthread_cond_wait
(
&
rwlock
->
rw_condreaders
,
&
rwlock
->
rw_mutex
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitreaders
--
;
if
(
result
!=
0
)
/* wait error */
break
;
}
/* another reader has a read lock */
if
(
result
==
0
)
rwlock
->
rw_refcount
++
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
/* give preference to waiting writers */
while
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
{
rwlock
->
rw_nwaitreaders
++
;
/* rw_mutex will be released when waiting for rw_condreaders */
result
=
pthread_cond_wait
(
&
rwlock
->
rw_condreaders
,
&
rwlock
->
rw_mutex
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitreaders
--
;
if
(
result
!=
0
)
/* wait error */
break
;
}
/* another reader has a read lock */
if
(
result
==
0
)
rwlock
->
rw_refcount
++
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_rdlock
);
int
pthread_rwlock_tryrdlock
(
pthread_rwlock_t
*
rwlock
)
int
pthread_rwlock_tryrdlock
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
result
=
EBUSY
;
/* held by a writer or waiting writers */
else
rwlock
->
rw_refcount
++
;
/* increment count of reader locks */
if
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
result
=
EBUSY
;
/* held by a writer or waiting writers */
else
rwlock
->
rw_refcount
++
;
/* increment count of reader locks */
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_tryrdlock
);
int
pthread_rwlock_timedrdlock
(
pthread_rwlock_t
*
rwlock
,
const
struct
timespec
*
abstime
)
int
pthread_rwlock_timedrdlock
(
pthread_rwlock_t
*
rwlock
,
const
struct
timespec
*
abstime
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
/* give preference to waiting writers */
while
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
{
rwlock
->
rw_nwaitreaders
++
;
/* rw_mutex will be released when waiting for rw_condreaders */
result
=
pthread_cond_timedwait
(
&
rwlock
->
rw_condreaders
,
&
rwlock
->
rw_mutex
,
abstime
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitreaders
--
;
if
(
result
!=
0
)
break
;
}
/* another reader has a read lock */
if
(
result
==
0
)
rwlock
->
rw_refcount
++
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
/* give preference to waiting writers */
while
(
rwlock
->
rw_refcount
<
0
||
rwlock
->
rw_nwaitwriters
>
0
)
{
rwlock
->
rw_nwaitreaders
++
;
/* rw_mutex will be released when waiting for rw_condreaders */
result
=
pthread_cond_timedwait
(
&
rwlock
->
rw_condreaders
,
&
rwlock
->
rw_mutex
,
abstime
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitreaders
--
;
if
(
result
!=
0
)
break
;
}
/* another reader has a read lock */
if
(
result
==
0
)
rwlock
->
rw_refcount
++
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_timedrdlock
);
int
pthread_rwlock_timedwrlock
(
pthread_rwlock_t
*
rwlock
,
const
struct
timespec
*
abstime
)
int
pthread_rwlock_timedwrlock
(
pthread_rwlock_t
*
rwlock
,
const
struct
timespec
*
abstime
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
while
(
rwlock
->
rw_refcount
!=
0
)
{
rwlock
->
rw_nwaitwriters
++
;
/* rw_mutex will be released when waiting for rw_condwriters */
result
=
pthread_cond_timedwait
(
&
rwlock
->
rw_condwriters
,
&
rwlock
->
rw_mutex
,
abstime
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitwriters
--
;
if
(
result
!=
0
)
break
;
}
if
(
result
==
0
)
rwlock
->
rw_refcount
=
-
1
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
while
(
rwlock
->
rw_refcount
!=
0
)
{
rwlock
->
rw_nwaitwriters
++
;
/* rw_mutex will be released when waiting for rw_condwriters */
result
=
pthread_cond_timedwait
(
&
rwlock
->
rw_condwriters
,
&
rwlock
->
rw_mutex
,
abstime
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitwriters
--
;
if
(
result
!=
0
)
break
;
}
if
(
result
==
0
)
rwlock
->
rw_refcount
=
-
1
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_timedwrlock
);
int
pthread_rwlock_trywrlock
(
pthread_rwlock_t
*
rwlock
)
int
pthread_rwlock_trywrlock
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
!=
0
)
result
=
EBUSY
;
/* held by either writer or reader(s) */
else
rwlock
->
rw_refcount
=
-
1
;
/* available, indicate a writer has it */
if
(
rwlock
->
rw_refcount
!=
0
)
result
=
EBUSY
;
/* held by either writer or reader(s) */
else
rwlock
->
rw_refcount
=
-
1
;
/* available, indicate a writer has it */
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_trywrlock
);
int
pthread_rwlock_unlock
(
pthread_rwlock_t
*
rwlock
)
int
pthread_rwlock_unlock
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
>
0
)
rwlock
->
rw_refcount
--
;
/* releasing a reader */
else
if
(
rwlock
->
rw_refcount
==
-
1
)
rwlock
->
rw_refcount
=
0
;
/* releasing a writer */
/* give preference to waiting writers over waiting readers */
if
(
rwlock
->
rw_nwaitwriters
>
0
)
{
if
(
rwlock
->
rw_refcount
==
0
)
result
=
pthread_cond_signal
(
&
rwlock
->
rw_condwriters
);
}
else
if
(
rwlock
->
rw_nwaitreaders
>
0
)
{
result
=
pthread_cond_broadcast
(
&
rwlock
->
rw_condreaders
);
}
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
if
(
rwlock
->
rw_refcount
>
0
)
rwlock
->
rw_refcount
--
;
/* releasing a reader */
else
if
(
rwlock
->
rw_refcount
==
-
1
)
rwlock
->
rw_refcount
=
0
;
/* releasing a writer */
/* give preference to waiting writers over waiting readers */
if
(
rwlock
->
rw_nwaitwriters
>
0
)
{
if
(
rwlock
->
rw_refcount
==
0
)
result
=
pthread_cond_signal
(
&
rwlock
->
rw_condwriters
);
}
else
if
(
rwlock
->
rw_nwaitreaders
>
0
)
{
result
=
pthread_cond_broadcast
(
&
rwlock
->
rw_condreaders
);
}
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_unlock
);
int
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
rwlock
)
int
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
rwlock
)
{
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
(
(
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
while
(
rwlock
->
rw_refcount
!=
0
)
{
rwlock
->
rw_nwaitwriters
++
;
/* rw_mutex will be released when waiting for rw_condwriters */
result
=
pthread_cond_wait
(
&
rwlock
->
rw_condwriters
,
&
rwlock
->
rw_mutex
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitwriters
--
;
if
(
result
!=
0
)
break
;
}
if
(
result
==
0
)
rwlock
->
rw_refcount
=
-
1
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
int
result
;
if
(
!
rwlock
)
return
EINVAL
;
if
(
rwlock
->
attr
==
-
1
)
pthread_rwlock_init
(
rwlock
,
NULL
);
if
((
result
=
pthread_mutex_lock
(
&
rwlock
->
rw_mutex
))
!=
0
)
return
(
result
);
while
(
rwlock
->
rw_refcount
!=
0
)
{
rwlock
->
rw_nwaitwriters
++
;
/* rw_mutex will be released when waiting for rw_condwriters */
result
=
pthread_cond_wait
(
&
rwlock
->
rw_condwriters
,
&
rwlock
->
rw_mutex
);
/* rw_mutex should have been taken again when returned from waiting */
rwlock
->
rw_nwaitwriters
--
;
if
(
result
!=
0
)
break
;
}
if
(
result
==
0
)
rwlock
->
rw_refcount
=
-
1
;
pthread_mutex_unlock
(
&
rwlock
->
rw_mutex
);
return
(
result
);
}
RTM_EXPORT
(
pthread_rwlock_wrlock
);
components/pthreads/pthread_spin.c
浏览文件 @
8ab2b287
/*
* File : pthread_spin.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <pthread.h>
int
pthread_spin_init
(
pthread_spinlock_t
*
lock
,
int
pshared
)
{
if
(
!
lock
)
return
EINVAL
;
if
(
!
lock
)
return
EINVAL
;
lock
->
lock
=
0
;
lock
->
lock
=
0
;
return
0
;
return
0
;
}
int
pthread_spin_destroy
(
pthread_spinlock_t
*
lock
)
{
if
(
!
lock
)
return
EINVAL
;
if
(
!
lock
)
return
EINVAL
;
return
0
;
return
0
;
}
int
pthread_spin_lock
(
pthread_spinlock_t
*
lock
)
{
if
(
!
lock
)
return
EINVAL
;
if
(
!
lock
)
return
EINVAL
;
while
(
!
(
lock
->
lock
))
{
lock
->
lock
=
1
;
}
while
(
!
(
lock
->
lock
))
{
lock
->
lock
=
1
;
}
return
0
;
return
0
;
}
int
pthread_spin_trylock
(
pthread_spinlock_t
*
lock
)
{
if
(
!
lock
)
return
EINVAL
;
if
(
!
lock
)
return
EINVAL
;
if
(
!
(
lock
->
lock
))
{
lock
->
lock
=
1
;
if
(
!
(
lock
->
lock
))
{
lock
->
lock
=
1
;
return
0
;
}
return
0
;
}
return
EBUSY
;
return
EBUSY
;
}
int
pthread_spin_unlock
(
pthread_spinlock_t
*
lock
)
{
if
(
!
lock
)
return
EINVAL
;
if
(
!
(
lock
->
lock
))
return
EPERM
;
if
(
!
lock
)
return
EINVAL
;
if
(
!
(
lock
->
lock
))
return
EPERM
;
lock
->
lock
=
0
;
lock
->
lock
=
0
;
return
0
;
return
0
;
}
components/pthreads/pthread_tls.c
浏览文件 @
8ab2b287
/*
* File : pthread_tls.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <pthread.h>
#include "pthread_internal.h"
...
...
@@ -5,82 +29,87 @@ _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX];
void
pthread_key_system_init
()
{
rt_memset
(
&
_thread_keys
[
0
],
0
,
sizeof
(
_thread_keys
));
rt_memset
(
&
_thread_keys
[
0
],
0
,
sizeof
(
_thread_keys
));
}
void
*
pthread_getspecific
(
pthread_key_t
key
)
{
struct
_pthread_data
*
ptd
;
struct
_pthread_data
*
ptd
;
ptd
=
_pthread_get_data
(
rt_thread_self
());
RT_ASSERT
(
ptd
!=
NULL
);
ptd
=
_pthread_get_data
(
rt_thread_self
());
RT_ASSERT
(
ptd
!=
NULL
);
if
(
ptd
->
tls
==
NULL
)
return
NULL
;
if
(
ptd
->
tls
==
NULL
)
return
NULL
;
if
((
key
<
PTHREAD_KEY_MAX
)
&&
(
_thread_keys
[
key
].
is_used
))
return
ptd
->
tls
[
key
];
if
((
key
<
PTHREAD_KEY_MAX
)
&&
(
_thread_keys
[
key
].
is_used
))
return
ptd
->
tls
[
key
];
return
NULL
;
return
NULL
;
}
RTM_EXPORT
(
pthread_getspecific
);
int
pthread_setspecific
(
pthread_key_t
key
,
const
void
*
value
)
{
struct
_pthread_data
*
ptd
;
struct
_pthread_data
*
ptd
;
ptd
=
_pthread_get_data
(
rt_thread_self
());
RT_ASSERT
(
ptd
!=
NULL
);
ptd
=
_pthread_get_data
(
rt_thread_self
());
RT_ASSERT
(
ptd
!=
NULL
);
/* check tls area */
if
(
ptd
->
tls
==
NULL
)
{
ptd
->
tls
=
(
void
**
)
rt_malloc
(
sizeof
(
void
*
)
*
PTHREAD_KEY_MAX
);
}
/* check tls area */
if
(
ptd
->
tls
==
NULL
)
{
ptd
->
tls
=
(
void
**
)
rt_malloc
(
sizeof
(
void
*
)
*
PTHREAD_KEY_MAX
);
}
if
((
key
<
PTHREAD_KEY_MAX
)
&&
_thread_keys
[
key
].
is_used
)
{
ptd
->
tls
[
key
]
=
(
void
*
)
value
;
if
((
key
<
PTHREAD_KEY_MAX
)
&&
_thread_keys
[
key
].
is_used
)
{
ptd
->
tls
[
key
]
=
(
void
*
)
value
;
return
0
;
}
return
0
;
}
return
EINVAL
;
return
EINVAL
;
}
RTM_EXPORT
(
pthread_setspecific
);
int
pthread_key_create
(
pthread_key_t
*
key
,
void
(
*
destructor
)(
void
*
))
{
rt_uint32_t
index
;
rt_uint32_t
index
;
rt_enter_critical
();
for
(
index
=
0
;
index
<
PTHREAD_KEY_MAX
;
index
++
)
{
if
(
_thread_keys
[
index
].
is_used
==
0
)
{
_thread_keys
[
index
].
is_used
=
1
;
_thread_keys
[
index
].
destructor
=
destructor
;
*
key
=
index
;
rt_enter_critical
();
for
(
index
=
0
;
index
<
PTHREAD_KEY_MAX
;
index
++
)
{
if
(
_thread_keys
[
index
].
is_used
==
0
)
{
_thread_keys
[
index
].
is_used
=
1
;
_thread_keys
[
index
].
destructor
=
destructor
;
rt_exit_critical
();
*
key
=
index
;
return
0
;
}
}
rt_exit_critical
();
return
0
;
}
}
rt_exit_critical
();
rt_exit_critical
();
return
EAGAIN
;
return
EAGAIN
;
}
RTM_EXPORT
(
pthread_key_create
);
int
pthread_key_delete
(
pthread_key_t
key
)
{
if
(
key
>=
PTHREAD_KEY_MAX
)
return
EINVAL
;
if
(
key
>=
PTHREAD_KEY_MAX
)
return
EINVAL
;
rt_enter_critical
();
_thread_keys
[
key
].
is_used
=
0
;
_thread_keys
[
key
].
destructor
=
0
;
rt_exit_critical
();
rt_enter_critical
();
_thread_keys
[
key
].
is_used
=
0
;
_thread_keys
[
key
].
destructor
=
0
;
rt_exit_critical
();
return
0
;
return
0
;
}
RTM_EXPORT
(
pthread_key_delete
);
components/pthreads/sched.c
浏览文件 @
8ab2b287
/*
* File : sched.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
*/
#include <sched.h>
int
sched_yield
(
void
)
{
rt_thread_yield
();
return
0
;
rt_thread_yield
();
return
0
;
}
RTM_EXPORT
(
sched_yield
);
int
sched_get_priority_min
(
int
policy
)
{
if
(
policy
!=
SCHED_FIFO
&&
policy
!=
SCHED_RR
)
return
EINVAL
;
if
(
policy
!=
SCHED_FIFO
&&
policy
!=
SCHED_RR
)
return
EINVAL
;
return
0
;
return
0
;
}
RTM_EXPORT
(
sched_get_priority_min
);
int
sched_get_priority_max
(
int
policy
)
{
if
(
policy
!=
SCHED_FIFO
&&
policy
!=
SCHED_RR
)
return
EINVAL
;
if
(
policy
!=
SCHED_FIFO
&&
policy
!=
SCHED_RR
)
return
EINVAL
;
return
RT_THREAD_PRIORITY_MAX
-
1
;
return
RT_THREAD_PRIORITY_MAX
-
1
;
}
RTM_EXPORT
(
sched_get_priority_max
);
int
sched_setscheduler
(
pid_t
pid
,
int
policy
)
{
return
ENOTSUP
;
return
ENOTSUP
;
}
RTM_EXPORT
(
sched_setscheduler
);
components/pthreads/sched.h
浏览文件 @
8ab2b287
/*
* File : sched.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __SCHED_H__
#define __SCHED_H__
...
...
@@ -7,16 +30,16 @@
/* Thread scheduling policies */
enum
{
SCHED_OTHER
=
0
,
SCHED_FIFO
,
SCHED_RR
,
SCHED_MIN
=
SCHED_OTHER
,
SCHED_MAX
=
SCHED_RR
SCHED_OTHER
=
0
,
SCHED_FIFO
,
SCHED_RR
,
SCHED_MIN
=
SCHED_OTHER
,
SCHED_MAX
=
SCHED_RR
};
struct
sched_param
{
int
sched_priority
;
int
sched_priority
;
};
#ifdef __cplusplus
...
...
components/pthreads/semaphore.c
浏览文件 @
8ab2b287
此差异已折叠。
点击以展开。
components/pthreads/semaphore.h
浏览文件 @
8ab2b287
/*
* File : semaphore.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#ifndef __POSIX_SEMAPHORE_H__
#define __POSIX_SEMAPHORE_H__
...
...
@@ -6,16 +30,16 @@
struct
posix_sem
{
/* reference count and unlinked */
rt_uint16_t
refcount
;
rt_uint8_t
unlinked
;
rt_uint8_t
unamed
;
/* reference count and unlinked */
rt_uint16_t
refcount
;
rt_uint8_t
unlinked
;
rt_uint8_t
unamed
;
/* RT-Thread semaphore */
rt_sem_t
sem
;
/* RT-Thread semaphore */
rt_sem_t
sem
;
/* next posix semaphore */
struct
posix_sem
*
next
;
/* next posix semaphore */
struct
posix_sem
*
next
;
};
typedef
struct
posix_sem
sem_t
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录