Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
38b9ed31
R
rt-thread
项目概览
BaiXuePrincess
/
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看板
提交
38b9ed31
编写于
3月 01, 2018
作者:
B
BernardXiong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Kernel] add sigwait implementation
上级
ef668bc3
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
228 addition
and
139 deletion
+228
-139
components/libc/signal/posix_signal.c
components/libc/signal/posix_signal.c
+51
-36
components/libc/signal/posix_signal.h
components/libc/signal/posix_signal.h
+1
-50
include/libc/libc_signal.h
include/libc/libc_signal.h
+20
-18
include/rtdef.h
include/rtdef.h
+3
-1
include/rtthread.h
include/rtthread.h
+1
-0
src/scheduler.c
src/scheduler.c
+2
-2
src/signal.c
src/signal.c
+147
-29
src/thread.c
src/thread.c
+2
-2
src/timer.c
src/timer.c
+1
-1
未找到文件。
components/libc/signal/posix_signal.c
浏览文件 @
38b9ed31
...
...
@@ -31,37 +31,37 @@
void
(
*
signal
(
int
sig
,
void
(
*
func
)(
int
)))
(
int
)
{
return
rt_signal_install
(
sig
,
func
);
return
rt_signal_install
(
sig
,
func
);
}
int
sigprocmask
(
int
how
,
const
sigset_t
*
set
,
sigset_t
*
oset
)
{
rt_base_t
level
;
rt_base_t
level
;
rt_thread_t
tid
;
tid
=
rt_thread_self
();
level
=
rt_hw_interrupt_disable
();
if
(
oset
)
*
oset
=
tid
->
sig_mask
;
if
(
set
)
{
switch
(
how
)
{
case
SIG_BLOCK
:
tid
->
sig_mask
|=
*
set
;
break
;
case
SIG_UNBLOCK
:
tid
->
sig_mask
&=
~*
set
;
break
;
case
SIG_SETMASK
:
tid
->
sig_mask
=
*
set
;
break
;
default:
break
;
}
}
rt_hw_interrupt_enable
(
level
);
level
=
rt_hw_interrupt_disable
();
if
(
oset
)
*
oset
=
tid
->
sig_mask
;
if
(
set
)
{
switch
(
how
)
{
case
SIG_BLOCK
:
tid
->
sig_mask
|=
*
set
;
break
;
case
SIG_UNBLOCK
:
tid
->
sig_mask
&=
~*
set
;
break
;
case
SIG_SETMASK
:
tid
->
sig_mask
=
*
set
;
break
;
default:
break
;
}
}
rt_hw_interrupt_enable
(
level
);
return
0
;
}
...
...
@@ -70,18 +70,18 @@ int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
{
rt_sighandler_t
old
=
RT_NULL
;
if
(
!
sig_valid
(
signum
))
return
-
RT_ERROR
;
if
(
!
sig_valid
(
signum
))
return
-
RT_ERROR
;
if
(
act
)
old
=
rt_signal_install
(
signum
,
act
->
sa_handler
);
else
{
old
=
rt_signal_install
(
signum
,
RT_NULL
);
rt_signal_install
(
signum
,
old
);
}
if
(
act
)
old
=
rt_signal_install
(
signum
,
act
->
sa_handler
);
else
{
old
=
rt_signal_install
(
signum
,
RT_NULL
);
rt_signal_install
(
signum
,
old
);
}
if
(
oldact
)
oldact
->
sa_handler
=
old
;
if
(
oldact
)
oldact
->
sa_handler
=
old
;
return
0
;
}
...
...
@@ -89,7 +89,22 @@ int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
int
sigtimedwait
(
const
sigset_t
*
set
,
siginfo_t
*
info
,
const
struct
timespec
*
timeout
)
{
return
0
;
int
ret
=
0
;
int
tick
=
RT_WAITING_FOREVER
;
#ifdef RT_USING_PTHREADS
if
(
timeout
)
{
extern
int
clock_time_to_tick
(
const
struct
timespec
*
time
);
tick
=
clock_time_to_tick
(
timeout
);
}
#endif
ret
=
rt_signal_wait
(
set
,
info
,
tick
);
if
(
ret
==
0
)
return
0
;
errno
=
ret
;
return
-
1
;
}
int
sigwait
(
const
sigset_t
*
set
,
int
*
sig
)
...
...
@@ -104,12 +119,12 @@ int sigwait(const sigset_t *set, int *sig)
int
sigwaitinfo
(
const
sigset_t
*
set
,
siginfo_t
*
info
)
{
return
sigtimedwait
(
set
,
info
,
NULL
);
return
sigtimedwait
(
set
,
info
,
NULL
);
}
int
raise
(
int
sig
)
{
rt_thread_kill
(
rt_thread_self
(),
sig
);
rt_thread_kill
(
rt_thread_self
(),
sig
);
return
0
;
}
components/libc/signal/posix_signal.h
浏览文件 @
38b9ed31
...
...
@@ -30,6 +30,7 @@ extern "C" {
#endif
#include <rtthread.h>
#include <sys/signal.h>
enum
rt_signal_value
{
SIG1
=
SIGHUP
,
...
...
@@ -68,56 +69,6 @@ enum rt_signal_value{
SIGMAX
=
NSIG
,
};
/*
The structure definitions on newlib:
typedef void (*_sig_func_ptr)(int);
struct sigaction
{
_sig_func_ptr sa_handler;
sigset_t sa_mask;
int sa_flags;
};
typedef int sig_atomic_t;
typedef _sig_func_ptr sig_t;
typedef _sig_func_ptr sighandler_t;
When enable POSIX_REALTIME_SIGNALS/POSIX_THREADS:
union sigval {
int sival_int;
void *sival_ptr;
};
struct sigevent {
int sigev_notify;
int sigev_signo;
union sigval sigev_value;
void (*sigev_notify_function)( union sigval );
pthread_attr_t *sigev_notify_attributes;
};
typedef struct {
int si_signo;
int si_code;
union sigval si_value;
} siginfo_t;
*/
rt_sighandler_t
rt_signal_install
(
int
signo
,
rt_sighandler_t
handler
);
void
rt_signal_mask
(
int
signo
);
void
rt_signal_unmask
(
int
signo
);
int
rt_thread_kill
(
rt_thread_t
tid
,
int
sig
);
int
rt_system_signal_init
(
void
);
#ifdef __cplusplus
}
#endif
...
...
include/libc/libc_signal.h
浏览文件 @
38b9ed31
...
...
@@ -30,6 +30,7 @@
extern
"C"
{
#endif
#ifndef HAVE_SYS_SIGNALS
/* 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. */
...
...
@@ -59,14 +60,15 @@ struct siginfo
union
sigval
si_value
;
};
typedef
struct
siginfo
siginfo_t
;
#endif
#define SI_USER
0x01
/* Signal sent by kill(). */
#define SI_QUEUE
0x02
/* Signal sent by sigqueue(). */
#define SI_TIMER
0x03
/* Signal generated by expiration of a
#define SI_USER
0x01
/* Signal sent by kill(). */
#define SI_QUEUE
0x02
/* Signal sent by sigqueue(). */
#define SI_TIMER
0x03
/* Signal generated by expiration of a
timer set by timer_settime(). */
#define SI_ASYNCIO
0x04
/* Signal generated by completion of an
asynchronous I/O request. */
#define SI_MESGQ
0x05
/* Signal generated by arrival of a
#define SI_ASYNCIO
0x04
/* Signal generated by completion of an
asynchronous I/O request. */
#define SI_MESGQ
0x05
/* Signal generated by arrival of a
message on an empty message queue. */
#ifdef RT_USING_NEWLIB
...
...
@@ -107,17 +109,17 @@ typedef unsigned long sigset_t;
#define SIGRTMAX 31
#define NSIG 32
#define SIG_SETMASK 0
/* set mask with sigprocmask() */
#define SIG_BLOCK
1
/* set of signals to block */
#define SIG_UNBLOCK 2
/* set of signals to, well, unblock */
#define SIG_SETMASK 0
/* set mask with sigprocmask() */
#define SIG_BLOCK
1
/* set of signals to block */
#define SIG_UNBLOCK 2
/* set of signals to, well, unblock */
typedef
void
(
*
_sig_func_ptr
)(
int
);
struct
sigaction
{
_sig_func_ptr
sa_handler
;
sigset_t
sa_mask
;
int
sa_flags
;
_sig_func_ptr
sa_handler
;
sigset_t
sa_mask
;
int
sa_flags
;
};
#define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0)
...
...
@@ -163,17 +165,17 @@ typedef unsigned long sigset_t;
#define SIGRTMAX 31
#define NSIG 32
#define SIG_SETMASK 0
/* set mask with sigprocmask() */
#define SIG_BLOCK
1
/* set of signals to block */
#define SIG_UNBLOCK 2
/* set of signals to, well, unblock */
#define SIG_SETMASK 0
/* set mask with sigprocmask() */
#define SIG_BLOCK
1
/* set of signals to block */
#define SIG_UNBLOCK 2
/* set of signals to, well, unblock */
typedef
void
(
*
_sig_func_ptr
)(
int
);
struct
sigaction
{
_sig_func_ptr
sa_handler
;
sigset_t
sa_mask
;
int
sa_flags
;
_sig_func_ptr
sa_handler
;
sigset_t
sa_mask
;
int
sa_flags
;
};
#define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0)
...
...
include/rtdef.h
浏览文件 @
38b9ed31
...
...
@@ -451,8 +451,10 @@ typedef struct rt_timer *rt_timer_t;
* @addtogroup Signal
*/
#ifdef RT_USING_SIGNALS
#include <libc/libc_signal.h>
typedef
unsigned
long
rt_sigset_t
;
typedef
void
(
*
rt_sighandler_t
)(
int
signo
);
typedef
siginfo_t
rt_siginfo_t
;
#define RT_SIG_MAX 32
#endif
...
...
@@ -481,7 +483,7 @@ typedef void (*rt_sighandler_t)(int signo);
#define RT_THREAD_STAT_SIGNAL 0x10
#define RT_THREAD_STAT_SIGNAL_READY (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY)
#define RT_THREAD_STAT_SIGNAL_
SUSPEND
0x20
#define RT_THREAD_STAT_SIGNAL_
WAIT
0x20
#define RT_THREAD_STAT_SIGNAL_MASK 0xf0
/**
...
...
include/rtthread.h
浏览文件 @
38b9ed31
...
...
@@ -204,6 +204,7 @@ void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
void
rt_signal_mask
(
int
signo
);
void
rt_signal_unmask
(
int
signo
);
rt_sighandler_t
rt_signal_install
(
int
signo
,
rt_sighandler_t
handler
);
int
rt_signal_wait
(
const
rt_sigset_t
*
set
,
rt_siginfo_t
*
si
,
rt_int32_t
timeout
);
int
rt_system_signal_init
(
void
);
#endif
...
...
src/scheduler.c
浏览文件 @
38b9ed31
...
...
@@ -263,7 +263,7 @@ void rt_schedule(void)
rt_hw_interrupt_enable
(
level
);
}
}
else
else
{
/* enable interrupt */
rt_hw_interrupt_enable
(
level
);
...
...
@@ -293,7 +293,7 @@ void rt_schedule_insert_thread(struct rt_thread *thread)
temp
=
rt_hw_interrupt_disable
();
/* change stat */
thread
->
stat
=
RT_THREAD_READY
;
thread
->
stat
=
RT_THREAD_READY
|
(
thread
->
stat
&
~
RT_THREAD_STAT_MASK
)
;
/* insert thread to ready list */
rt_list_insert_before
(
&
(
rt_thread_priority_table
[
thread
->
current_priority
]),
...
...
src/signal.c
浏览文件 @
38b9ed31
...
...
@@ -80,6 +80,16 @@ static void _signal_entry(void *parameter)
rt_hw_context_switch_to
((
rt_uint32_t
)
&
(
tid
->
sp
));
}
/*
* To deliver a signal to thread, there are cases:
* 1. When thread is suspended, function resumes thread and
* set signal stat;
* 2. When thread is ready:
* - If function delivers a signal to self thread, just handle
* it.
* - If function delivers a signal to another ready thread, OS
* should build a slice context to handle it.
*/
static
void
_signal_deliver
(
rt_thread_t
tid
)
{
rt_ubase_t
level
;
...
...
@@ -88,7 +98,7 @@ static void _signal_deliver(rt_thread_t tid)
if
(
!
(
tid
->
sig_pending
&
tid
->
sig_mask
))
return
;
level
=
rt_hw_interrupt_disable
();
if
(
tid
->
stat
==
RT_THREAD_SUSPEND
)
if
(
(
tid
->
stat
&
RT_THREAD_STAT_MASK
)
==
RT_THREAD_SUSPEND
)
{
/* resume thread to handle signal */
rt_thread_resume
(
tid
);
...
...
@@ -106,14 +116,17 @@ static void _signal_deliver(rt_thread_t tid)
{
/* add signal state */
tid
->
stat
|=
RT_THREAD_STAT_SIGNAL
;
rt_hw_interrupt_enable
(
level
);
/* do signal action in self thread context */
rt_thread_handle_sig
(
RT_TRUE
);
}
else
if
(
!
(
tid
->
stat
&
RT_THREAD_STAT_SIGNAL
))
else
if
(
!
(
(
tid
->
stat
&
RT_THREAD_STAT_MASK
)
&
RT_THREAD_STAT_SIGNAL
))
{
/* add signal state */
tid
->
stat
|=
RT_THREAD_STAT_SIGNAL
;
/* point to the signal handle entry */
tid
->
sig_ret
=
tid
->
sp
;
tid
->
sp
=
rt_hw_stack_init
((
void
*
)
_signal_entry
,
RT_NULL
,
...
...
@@ -191,6 +204,105 @@ void rt_signal_unmask(int signo)
}
}
int
rt_signal_wait
(
const
rt_sigset_t
*
set
,
rt_siginfo_t
*
si
,
rt_int32_t
timeout
)
{
int
ret
=
RT_EOK
;
rt_base_t
level
;
rt_thread_t
tid
=
rt_thread_self
();
struct
siginfo_node
*
si_node
=
RT_NULL
,
*
si_prev
=
RT_NULL
;
/* current context checking */
RT_DEBUG_IN_THREAD_CONTEXT
;
/* parameters check */
if
(
set
==
NULL
||
*
set
==
0
||
si
==
NULL
)
{
ret
=
-
RT_EINVAL
;
goto
__done_return
;
}
/* clear siginfo to avoid unknown value */
memset
(
si
,
0x0
,
sizeof
(
rt_siginfo_t
));
level
=
rt_hw_interrupt_disable
();
/* already pending */
if
(
tid
->
sig_pending
&
*
set
)
goto
__done
;
if
(
timeout
==
0
)
{
ret
=
-
RT_ETIMEOUT
;
goto
__done_int
;
}
/* suspend self thread */
rt_thread_suspend
(
tid
);
/* set thread stat as waiting for signal */
tid
->
stat
|=
RT_THREAD_STAT_SIGNAL_WAIT
;
/* start timeout timer */
if
(
timeout
!=
RT_WAITING_FOREVER
)
{
/* reset the timeout of thread timer and start it */
rt_timer_control
(
&
(
tid
->
thread_timer
),
RT_TIMER_CTRL_SET_TIME
,
&
timeout
);
rt_timer_start
(
&
(
tid
->
thread_timer
));
}
rt_hw_interrupt_enable
(
level
);
/* do thread scheduling */
rt_schedule
();
level
=
rt_hw_interrupt_disable
();
/* remove signal waiting flag */
tid
->
stat
&=
~
RT_THREAD_STAT_SIGNAL_WAIT
;
/* check errno of thread */
if
(
tid
->
error
==
-
RT_ETIMEOUT
)
{
tid
->
error
=
RT_EOK
;
rt_hw_interrupt_enable
(
level
);
/* timer timeout */
ret
=
-
RT_ETIMEOUT
;
goto
__done_return
;
}
__done:
/* to get the first matched pending signals */
si_node
=
(
struct
siginfo_node
*
)
tid
->
si_list
;
while
(
si_node
)
{
int
signo
;
signo
=
si_node
->
si
.
si_signo
;
if
(
sig_mask
(
signo
)
&
*
set
)
{
*
si
=
si_node
->
si
;
dbg_log
(
DBG_LOG
,
"sigwait: %d sig raised!
\n
"
,
signo
);
if
(
si_prev
)
si_prev
->
list
.
next
=
si_node
->
list
.
next
;
else
tid
->
si_list
=
si_node
->
list
.
next
;
/* clear pending */
tid
->
sig_pending
&=
~
sig_mask
(
signo
);
rt_mp_free
(
si_node
);
break
;
}
si_prev
=
si_node
;
si_node
=
(
void
*
)
rt_slist_entry
(
si_node
->
list
.
next
,
struct
siginfo_node
,
list
);
}
__done_int:
rt_hw_interrupt_enable
(
level
);
__done_return:
return
ret
;
}
void
rt_thread_handle_sig
(
rt_bool_t
clean_state
)
{
rt_base_t
level
;
...
...
@@ -199,38 +311,45 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
struct
siginfo_node
*
si_node
;
level
=
rt_hw_interrupt_disable
();
while
(
tid
->
sig_pending
&
tid
->
sig_mask
)
if
(
tid
->
sig_pending
&
tid
->
sig_mask
)
{
int
signo
,
error
;
rt_sighandler_t
handler
;
/* if thread is not waiting for signal */
if
(
!
(
tid
->
stat
&
RT_THREAD_STAT_SIGNAL_WAIT
))
{
while
(
tid
->
sig_pending
&
tid
->
sig_mask
)
{
int
signo
,
error
;
rt_sighandler_t
handler
;
si_node
=
(
struct
siginfo_node
*
)
tid
->
si_list
;
if
(
!
si_node
)
break
;
si_node
=
(
struct
siginfo_node
*
)
tid
->
si_list
;
if
(
!
si_node
)
break
;
/* remove this sig info node from list */
if
(
si_node
->
list
.
next
==
RT_NULL
)
tid
->
si_list
=
RT_NULL
;
else
tid
->
si_list
=
(
void
*
)
rt_slist_entry
(
si_node
->
list
.
next
,
struct
siginfo_node
,
list
);
/* remove this sig info node from list */
if
(
si_node
->
list
.
next
==
RT_NULL
)
tid
->
si_list
=
RT_NULL
;
else
tid
->
si_list
=
(
void
*
)
rt_slist_entry
(
si_node
->
list
.
next
,
struct
siginfo_node
,
list
);
signo
=
si_node
->
si
.
si_signo
;
handler
=
tid
->
sig_vectors
[
signo
];
rt_hw_interrupt_enable
(
level
);
signo
=
si_node
->
si
.
si_signo
;
handler
=
tid
->
sig_vectors
[
signo
];
rt_hw_interrupt_enable
(
level
);
dbg_log
(
DBG_LOG
,
"handle signal: %d, handler 0x%08x
\n
"
,
signo
,
handler
);
if
(
handler
)
handler
(
signo
);
dbg_log
(
DBG_LOG
,
"handle signal: %d, handler 0x%08x
\n
"
,
signo
,
handler
);
if
(
handler
)
handler
(
signo
);
level
=
rt_hw_interrupt_disable
();
tid
->
sig_pending
&=
~
sig_mask
(
signo
);
error
=
si_node
->
si
.
si_errno
;
level
=
rt_hw_interrupt_disable
();
tid
->
sig_pending
&=
~
sig_mask
(
signo
);
error
=
si_node
->
si
.
si_errno
;
rt_mp_free
(
si_node
);
/* release this siginfo node */
/* set errno in thread tcb */
tid
->
error
=
error
;
}
rt_mp_free
(
si_node
);
/* release this siginfo node */
/* set errno in thread tcb */
tid
->
error
=
error
;
}
/* whether clean signal status */
if
(
clean_state
==
RT_TRUE
)
tid
->
stat
&=
~
RT_THREAD_STAT_SIGNAL
;
/* whether clean signal status */
if
(
clean_state
==
RT_TRUE
)
tid
->
stat
&=
~
RT_THREAD_STAT_SIGNAL
;
}
}
rt_hw_interrupt_enable
(
level
);
}
...
...
@@ -315,7 +434,7 @@ int rt_thread_kill(rt_thread_t tid, int sig)
node
=
(
struct
rt_slist_node
*
)
tid
->
si_list
;
rt_hw_interrupt_enable
(
level
);
/* update sig info
r
*/
/* update sig info */
rt_enter_critical
();
for
(;
(
node
)
!=
RT_NULL
;
node
=
node
->
next
)
{
...
...
@@ -358,7 +477,7 @@ int rt_thread_kill(rt_thread_t tid, int sig)
}
else
{
dbg_log
(
DBG_ERROR
,
"The allocation of signal info
r
node failed.
\n
"
);
dbg_log
(
DBG_ERROR
,
"The allocation of signal info node failed.
\n
"
);
}
/* deliver signal to this thread */
...
...
@@ -380,4 +499,3 @@ int rt_system_signal_init(void)
}
#endif
src/thread.c
浏览文件 @
38b9ed31
...
...
@@ -638,7 +638,7 @@ rt_err_t rt_thread_suspend(rt_thread_t thread)
if
((
thread
->
stat
&
RT_THREAD_STAT_MASK
)
!=
RT_THREAD_READY
)
{
RT_DEBUG_LOG
(
RT_DEBUG_THREAD
,
(
"thread suspend: thread disorder,
%d
\n
"
,
RT_DEBUG_LOG
(
RT_DEBUG_THREAD
,
(
"thread suspend: thread disorder,
0x%2x
\n
"
,
thread
->
stat
));
return
-
RT_ERROR
;
...
...
@@ -648,7 +648,7 @@ rt_err_t rt_thread_suspend(rt_thread_t thread)
temp
=
rt_hw_interrupt_disable
();
/* change thread stat */
thread
->
stat
=
RT_THREAD_SUSPEND
;
thread
->
stat
=
RT_THREAD_SUSPEND
|
(
thread
->
stat
&
~
RT_THREAD_STAT_MASK
)
;
rt_schedule_remove_thread
(
thread
);
/* stop thread timer anyway */
...
...
src/timer.c
浏览文件 @
38b9ed31
...
...
@@ -396,7 +396,7 @@ rt_err_t rt_timer_start(rt_timer_t timer)
if
(
timer
->
parent
.
flag
&
RT_TIMER_FLAG_SOFT_TIMER
)
{
/* check whether timer thread is ready */
if
(
timer_thread
.
stat
!=
RT_THREAD_READY
)
if
(
(
timer_thread
.
stat
&
RT_THREAD_STAT_MASK
)
!=
RT_THREAD_READY
)
{
/* resume timer thread to check soft timer */
rt_thread_resume
(
&
timer_thread
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录