未验证 提交 854d0144 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #2665 from jesven/new_signal_fix

fix signal code
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# RT-Thread Kernel # RT-Thread Kernel
# #
CONFIG_RT_NAME_MAX=8 CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
CONFIG_RT_USING_SMP=y CONFIG_RT_USING_SMP=y
CONFIG_RT_CPUS_NR=2 CONFIG_RT_CPUS_NR=2
CONFIG_RT_ALIGN_SIZE=8 CONFIG_RT_ALIGN_SIZE=8
...@@ -19,7 +20,7 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y ...@@ -19,7 +20,7 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDEL_HOOK_LIST_SIZE=4 CONFIG_RT_IDEL_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=1024 CONFIG_IDLE_THREAD_STACK_SIZE=4096
# CONFIG_RT_USING_TIMER_SOFT is not set # CONFIG_RT_USING_TIMER_SOFT is not set
CONFIG_RT_DEBUG=y CONFIG_RT_DEBUG=y
CONFIG_RT_DEBUG_COLOR=y CONFIG_RT_DEBUG_COLOR=y
...@@ -43,7 +44,7 @@ CONFIG_RT_USING_MUTEX=y ...@@ -43,7 +44,7 @@ CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set CONFIG_RT_USING_SIGNALS=y
# #
# Memory Management # Memory Management
...@@ -139,6 +140,7 @@ CONFIG_RT_USING_DFS_DEVFS=y ...@@ -139,6 +140,7 @@ CONFIG_RT_USING_DFS_DEVFS=y
# #
CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512 CONFIG_RT_PIPE_BUFSZ=512
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_SERIAL_RB_BUFSZ=64
...@@ -202,6 +204,11 @@ CONFIG_RT_USING_POSIX=y ...@@ -202,6 +204,11 @@ CONFIG_RT_USING_POSIX=y
# #
# CONFIG_RT_USING_SAL is not set # CONFIG_RT_USING_SAL is not set
#
# Network interface device
#
# CONFIG_RT_USING_NETDEV is not set
# #
# light weight TCP/IP stack # light weight TCP/IP stack
# #
...@@ -225,7 +232,6 @@ CONFIG_RT_USING_POSIX=y ...@@ -225,7 +232,6 @@ CONFIG_RT_USING_POSIX=y
# #
# Utilities # Utilities
# #
# CONFIG_RT_USING_LOGTRACE is not set
# CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_UTEST is not set
...@@ -354,7 +360,6 @@ CONFIG_RT_USING_POSIX=y ...@@ -354,7 +360,6 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_MPU6XXX is not set # CONFIG_PKG_USING_MPU6XXX is not set
# CONFIG_PKG_USING_PCF8574 is not set # CONFIG_PKG_USING_PCF8574 is not set
# CONFIG_PKG_USING_SX12XX is not set # CONFIG_PKG_USING_SX12XX is not set
# CONFIG_PKG_USING_SIGNAL_LED is not set
CONFIG_PKG_USING_KENDRYTE_SDK=y CONFIG_PKG_USING_KENDRYTE_SDK=y
CONFIG_PKG_KENDRYTE_SDK_PATH="/packages/peripherals/kendryte-sdk" CONFIG_PKG_KENDRYTE_SDK_PATH="/packages/peripherals/kendryte-sdk"
CONFIG_PKG_USING_KENDRYTE_SDK_V052=y CONFIG_PKG_USING_KENDRYTE_SDK_V052=y
...@@ -385,6 +390,34 @@ CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2" ...@@ -385,6 +390,34 @@ CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2"
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# CONFIG_PKG_USING_HELLO is not set # CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set # CONFIG_PKG_USING_VI is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_MPLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RDBD_SRC is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
# CONFIG_PKG_USING_RTX is not set
# CONFIG_RT_USING_TESTCASE is not set
# CONFIG_PKG_USING_NGHTTP2 is not set
# CONFIG_PKG_USING_AVS is not set
# CONFIG_PKG_USING_STS is not set
# CONFIG_PKG_USING_DLMS is not set
CONFIG_BOARD_K210_EVB=y CONFIG_BOARD_K210_EVB=y
CONFIG_BSP_USING_UART_HS=y CONFIG_BSP_USING_UART_HS=y
# CONFIG_BSP_USING_UART1 is not set # CONFIG_BSP_USING_UART1 is not set
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
/* RT-Thread Kernel */ /* RT-Thread Kernel */
#define RT_NAME_MAX 8 #define RT_NAME_MAX 8
/* RT_USING_ARCH_DATA_TYPE is not set */
#define RT_USING_SMP #define RT_USING_SMP
#define RT_CPUS_NR 2 #define RT_CPUS_NR 2
#define RT_ALIGN_SIZE 8 #define RT_ALIGN_SIZE 8
...@@ -19,7 +20,7 @@ ...@@ -19,7 +20,7 @@
#define RT_USING_HOOK #define RT_USING_HOOK
#define RT_USING_IDLE_HOOK #define RT_USING_IDLE_HOOK
#define RT_IDEL_HOOK_LIST_SIZE 4 #define RT_IDEL_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 1024 #define IDLE_THREAD_STACK_SIZE 4096
/* RT_USING_TIMER_SOFT is not set */ /* RT_USING_TIMER_SOFT is not set */
#define RT_DEBUG #define RT_DEBUG
#define RT_DEBUG_COLOR #define RT_DEBUG_COLOR
...@@ -42,7 +43,7 @@ ...@@ -42,7 +43,7 @@
#define RT_USING_EVENT #define RT_USING_EVENT
#define RT_USING_MAILBOX #define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE #define RT_USING_MESSAGEQUEUE
/* RT_USING_SIGNALS is not set */ #define RT_USING_SIGNALS
/* Memory Management */ /* Memory Management */
...@@ -130,6 +131,7 @@ ...@@ -130,6 +131,7 @@
#define RT_USING_DEVICE_IPC #define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512 #define RT_PIPE_BUFSZ 512
/* RT_USING_SYSTEM_WORKQUEUE is not set */
#define RT_USING_SERIAL #define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA #define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64 #define RT_SERIAL_RB_BUFSZ 64
...@@ -187,6 +189,10 @@ ...@@ -187,6 +189,10 @@
/* RT_USING_SAL is not set */ /* RT_USING_SAL is not set */
/* Network interface device */
/* RT_USING_NETDEV is not set */
/* light weight TCP/IP stack */ /* light weight TCP/IP stack */
/* RT_USING_LWIP is not set */ /* RT_USING_LWIP is not set */
...@@ -205,7 +211,6 @@ ...@@ -205,7 +211,6 @@
/* Utilities */ /* Utilities */
/* RT_USING_LOGTRACE is not set */
/* RT_USING_RYM is not set */ /* RT_USING_RYM is not set */
/* RT_USING_ULOG is not set */ /* RT_USING_ULOG is not set */
/* RT_USING_UTEST is not set */ /* RT_USING_UTEST is not set */
...@@ -318,7 +323,6 @@ ...@@ -318,7 +323,6 @@
/* PKG_USING_MPU6XXX is not set */ /* PKG_USING_MPU6XXX is not set */
/* PKG_USING_PCF8574 is not set */ /* PKG_USING_PCF8574 is not set */
/* PKG_USING_SX12XX is not set */ /* PKG_USING_SX12XX is not set */
/* PKG_USING_SIGNAL_LED is not set */
#define PKG_USING_KENDRYTE_SDK #define PKG_USING_KENDRYTE_SDK
#define PKG_USING_KENDRYTE_SDK_V052 #define PKG_USING_KENDRYTE_SDK_V052
/* PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set */ /* PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set */
...@@ -345,6 +349,32 @@ ...@@ -345,6 +349,32 @@
/* PKG_USING_PERIPHERAL_SAMPLES is not set */ /* PKG_USING_PERIPHERAL_SAMPLES is not set */
/* PKG_USING_HELLO is not set */ /* PKG_USING_HELLO is not set */
/* PKG_USING_VI is not set */ /* PKG_USING_VI is not set */
/* Privated Packages of RealThread */
/* PKG_USING_CODEC is not set */
/* PKG_USING_PLAYER is not set */
/* PKG_USING_MPLAYER is not set */
/* PKG_USING_PERSIMMON_SRC is not set */
/* PKG_USING_JS_PERSIMMON is not set */
/* PKG_USING_JERRYSCRIPT_WIN32 is not set */
/* Network Utilities */
/* PKG_USING_WICED is not set */
/* PKG_USING_CLOUDSDK is not set */
/* PKG_USING_COREMARK is not set */
/* PKG_USING_POWER_MANAGER is not set */
/* PKG_USING_RT_OTA is not set */
/* PKG_USING_RDBD_SRC is not set */
/* PKG_USING_RTINSIGHT is not set */
/* PKG_USING_SMARTCONFIG is not set */
/* PKG_USING_RTX is not set */
/* RT_USING_TESTCASE is not set */
/* PKG_USING_NGHTTP2 is not set */
/* PKG_USING_AVS is not set */
/* PKG_USING_STS is not set */
/* PKG_USING_DLMS is not set */
#define BOARD_K210_EVB #define BOARD_K210_EVB
#define BSP_USING_UART_HS #define BSP_USING_UART_HS
/* BSP_USING_UART1 is not set */ /* BSP_USING_UART1 is not set */
......
...@@ -15,7 +15,7 @@ if os.getenv('RTT_CC'): ...@@ -15,7 +15,7 @@ if os.getenv('RTT_CC'):
if CROSS_TOOL == 'gcc': if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc' PLATFORM = 'gcc'
EXEC_PATH = r'/opt/riscv64-unknown-elf/bin' EXEC_PATH = r'/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin'
else: else:
print('Please make sure your toolchains is GNU GCC!') print('Please make sure your toolchains is GNU GCC!')
exit(0) exit(0)
......
...@@ -492,9 +492,10 @@ typedef siginfo_t rt_siginfo_t; ...@@ -492,9 +492,10 @@ typedef siginfo_t rt_siginfo_t;
#define RT_THREAD_CLOSE 0x04 /**< Closed status */ #define RT_THREAD_CLOSE 0x04 /**< Closed status */
#define RT_THREAD_STAT_MASK 0x0f #define RT_THREAD_STAT_MASK 0x0f
#define RT_THREAD_STAT_SIGNAL 0x10 #define RT_THREAD_STAT_SIGNAL 0x10 /**< task hold signals */
#define RT_THREAD_STAT_SIGNAL_READY (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY) #define RT_THREAD_STAT_SIGNAL_READY (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY)
#define RT_THREAD_STAT_SIGNAL_WAIT 0x20 #define RT_THREAD_STAT_SIGNAL_WAIT 0x20 /**< task is waiting for signals */
#define RT_THREAD_STAT_SIGNAL_PENDING 0x40 /**< signals is held and it has not been procressed */
#define RT_THREAD_STAT_SIGNAL_MASK 0xf0 #define RT_THREAD_STAT_SIGNAL_MASK 0xf0
/** /**
...@@ -596,7 +597,9 @@ struct rt_thread ...@@ -596,7 +597,9 @@ struct rt_thread
rt_sigset_t sig_pending; /**< the pending signals */ rt_sigset_t sig_pending; /**< the pending signals */
rt_sigset_t sig_mask; /**< the mask bits of signal */ rt_sigset_t sig_mask; /**< the mask bits of signal */
#ifndef RT_USING_SMP
void *sig_ret; /**< the return stack pointer from signal */ void *sig_ret; /**< the return stack pointer from signal */
#endif
rt_sighandler_t *sig_vectors; /**< vectors of signal handler */ rt_sighandler_t *sig_vectors; /**< vectors of signal handler */
void *si_list; /**< the signal infor list */ void *si_list; /**< the signal infor list */
#endif #endif
......
...@@ -46,16 +46,7 @@ rt_hw_context_switch_to: ...@@ -46,16 +46,7 @@ rt_hw_context_switch_to:
mov r0, r1 mov r0, r1
bl rt_cpus_lock_status_restore bl rt_cpus_lock_status_restore
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
b rt_hw_context_switch_exit
#ifdef RT_USING_LWP
ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr
add sp, #8
#endif
ldmfd sp!, {r4} @ pop new task spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc
.section .bss.share.isr .section .bss.share.isr
_guest_switch_lvl: _guest_switch_lvl:
...@@ -93,15 +84,7 @@ rt_hw_context_switch: ...@@ -93,15 +84,7 @@ rt_hw_context_switch:
mov r0, r2 mov r0, r2
bl rt_cpus_lock_status_restore bl rt_cpus_lock_status_restore
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
b rt_hw_context_switch_exit
#ifdef RT_USING_LWP
ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr
add sp, #8
#endif
ldmfd sp!, {r4} @ pop new task cpsr to spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
/* /*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
...@@ -123,51 +106,19 @@ rt_hw_context_switch: ...@@ -123,51 +106,19 @@ rt_hw_context_switch:
.globl rt_hw_context_switch_interrupt .globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt: rt_hw_context_switch_interrupt:
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
/* r0 :irq_mod context /* r0 :svc_mod context
* r1 :addr of from_thread's sp * r1 :addr of from_thread's sp
* r2 :addr of to_thread's sp * r2 :addr of to_thread's sp
* r3 :to_thread's tcb * r3 :to_thread's tcb
*/ */
@ r0 point to {r0-r3} in stack str r0, [r1]
push {r1 - r3}
mov r1, r0
add r0, r0, #4*4
ldmfd r0!, {r4-r12,lr}@ reload saved registers
mrs r3, spsr @ get cpsr of interrupt thread
sub r2, lr, #4 @ save old task's pc to r2
msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
stmfd sp!, {r2} @ push old task's pc
stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
ldmfd r1, {r4-r7} @ restore r0-r3 of the interrupt thread
stmfd sp!, {r4-r7} @ push old task's r0-r3
stmfd sp!, {r3} @ push old task's cpsr
#ifdef RT_USING_LWP
stmfd sp, {r13,r14}^ @push usr_sp usr_lr
sub sp, #8
#endif
msr cpsr_c, #I_Bit|F_Bit|Mode_IRQ
pop {r1 - r3}
mov sp, r0
msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
str sp, [r1]
ldr sp, [r2] ldr sp, [r2]
mov r0, r3 mov r0, r3
bl rt_cpus_lock_status_restore bl rt_cpus_lock_status_restore
#ifdef RT_USING_LWP b rt_hw_context_switch_exit
ldmfd sp, {r13,r14}^ @pop usr_sp usr_lr
add sp, #8
#endif
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
#else /*RT_USING_SMP*/ #else /*RT_USING_SMP*/
ldr r2, =rt_thread_switch_interrupt_flag ldr r2, =rt_thread_switch_interrupt_flag
...@@ -183,3 +134,25 @@ _reswitch: ...@@ -183,3 +134,25 @@ _reswitch:
str r1, [r2] str r1, [r2]
bx lr bx lr
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
.global rt_hw_context_switch_exit
rt_hw_context_switch_exit:
#ifdef RT_USING_SMP
#ifdef RT_USING_SIGNALS
mov r0, sp
cps #Mode_IRQ
bl rt_signal_check
cps #Mode_SVC
mov sp, r0
#endif
#endif
#ifdef RT_USING_LWP
ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */
add sp, #8
#endif
ldmfd sp!, {r1}
msr spsr_cxsf, r1 /* original mode */
ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
*/ */
#include "rtconfig.h" #include "rtconfig.h"
.equ Mode_USR, 0x10 .equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11 .equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12 .equ Mode_IRQ, 0x12
...@@ -158,20 +157,48 @@ vector_fiq: ...@@ -158,20 +157,48 @@ vector_fiq:
vector_irq: vector_irq:
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
clrex clrex
stmfd sp!, {r0, r1}
cps #Mode_SVC
mov r0, sp /* svc_sp */
mov r1, lr /* svc_lr */
cps #Mode_IRQ
sub lr, #4
stmfd r0!, {r1, lr} /* svc_lr, svc_pc */
stmfd r0!, {r2 - r12}
ldmfd sp!, {r1, r2} /* original r0, r1 */
stmfd r0!, {r1 - r2}
mrs r1, spsr /* original mode */
stmfd r0!, {r1}
#ifdef RT_USING_LWP
stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */
sub r0, #8
#endif #endif
stmfd sp!, {r0-r12,lr} /* now irq stack is clean */
/* r0 is task svc_sp */
/* backup r0 -> r8 */
mov r8, r0
bl rt_interrupt_enter bl rt_interrupt_enter
bl rt_hw_trap_irq bl rt_hw_trap_irq
bl rt_interrupt_leave bl rt_interrupt_leave
#ifdef RT_USING_SMP cps #Mode_SVC
mov r0, sp mov sp, r8
mov r0, r8
bl rt_scheduler_do_irq_switch bl rt_scheduler_do_irq_switch
ldmfd sp!, {r0-r12,lr} b rt_hw_context_switch_exit
subs pc, lr, #4
#else #else
stmfd sp!, {r0-r12,lr}
bl rt_interrupt_enter
bl rt_hw_trap_irq
bl rt_interrupt_leave
@ if rt_thread_switch_interrupt_flag set, jump to @ if rt_thread_switch_interrupt_flag set, jump to
@ rt_hw_context_switch_interrupt_do and don't return @ rt_hw_context_switch_interrupt_do and don't return
ldr r0, =rt_thread_switch_interrupt_flag ldr r0, =rt_thread_switch_interrupt_flag
......
...@@ -49,45 +49,9 @@ rt_hw_context_switch_to: ...@@ -49,45 +49,9 @@ rt_hw_context_switch_to:
mv a0, a1 mv a0, a1
jal rt_cpus_lock_status_restore jal rt_cpus_lock_status_restore
#endif #endif
/* load epc from stack */
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
LOAD x1, 1 * REGBYTES(sp)
/* load mstatus from stack */
LOAD a0, 2 * REGBYTES(sp) LOAD a0, 2 * REGBYTES(sp)
csrw mstatus, a0 csrw mstatus, a0
LOAD x4, 4 * REGBYTES(sp) j rt_hw_context_switch_exit
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
mret
/* /*
* #ifdef RT_USING_SMP * #ifdef RT_USING_SMP
...@@ -102,7 +66,6 @@ rt_hw_context_switch_to: ...@@ -102,7 +66,6 @@ rt_hw_context_switch_to:
*/ */
.globl rt_hw_context_switch .globl rt_hw_context_switch
rt_hw_context_switch: rt_hw_context_switch:
/* saved from thread context /* saved from thread context
* x1/ra -> sp(0) * x1/ra -> sp(0)
* x1/ra -> sp(1) * x1/ra -> sp(1)
...@@ -163,48 +126,7 @@ save_mpie: ...@@ -163,48 +126,7 @@ save_mpie:
jal rt_cpus_lock_status_restore jal rt_cpus_lock_status_restore
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
/* resw ra to mepc */ j rt_hw_context_switch_exit
LOAD a1, 0 * REGBYTES(sp)
csrw mepc, a1
LOAD x1, 1 * REGBYTES(sp)
/* force to machin mode(MPP=11) */
li a1, 0x00001800;
csrs mstatus, a1
LOAD a1, 2 * REGBYTES(sp)
csrs mstatus, a1
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
mret
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
/* /*
...@@ -220,26 +142,42 @@ rt_hw_context_switch_interrupt: ...@@ -220,26 +142,42 @@ rt_hw_context_switch_interrupt:
STORE a0, 0(a1) STORE a0, 0(a1)
csrr a1, mepc
STORE a1, 0 * REGBYTES(a0)
csrr a1, mstatus
STORE a1, 2 * REGBYTES(a0)
LOAD sp, 0(a2) LOAD sp, 0(a2)
move a0, a3 move a0, a3
call rt_cpus_lock_status_restore call rt_cpus_lock_status_restore
j rt_hw_context_switch_exit
#endif
.global rt_hw_context_switch_exit
rt_hw_context_switch_exit:
#ifdef RT_USING_SMP
#ifdef RT_USING_SIGNALS
mv a0, sp
csrr t0, mhartid
/* switch interrupt stack of current cpu */
la sp, __stack_start__
addi t1, t0, 1
li t2, __STACKSIZE__
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
call rt_signal_check
mv sp, a0
#endif
#endif
/* resw ra to mepc */ /* resw ra to mepc */
LOAD a1, 0 * REGBYTES(sp) LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a1 csrw mepc, a0
LOAD x1, 1 * REGBYTES(sp) LOAD x1, 1 * REGBYTES(sp)
/* force to machin mode(MPP=11) */ li t0, 0x00001800
li a1, 0x00001800; csrs mstatus, t0
csrs mstatus, a1 LOAD a0, 2 * REGBYTES(sp)
LOAD a1, 2 * REGBYTES(sp) csrs mstatus, a0
csrs mstatus, a1
LOAD x4, 4 * REGBYTES(sp) LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp) LOAD x5, 5 * REGBYTES(sp)
...@@ -272,5 +210,3 @@ rt_hw_context_switch_interrupt: ...@@ -272,5 +210,3 @@ rt_hw_context_switch_interrupt:
addi sp, sp, 32 * REGBYTES addi sp, sp, 32 * REGBYTES
mret mret
#endif
...@@ -20,8 +20,12 @@ trap_entry: ...@@ -20,8 +20,12 @@ trap_entry:
addi sp, sp, -32 * REGBYTES addi sp, sp, -32 * REGBYTES
STORE x1, 1 * REGBYTES(sp) STORE x1, 1 * REGBYTES(sp)
li t0, 0x80
STORE t0, 2 * REGBYTES(sp) csrr x1, mstatus
STORE x1, 2 * REGBYTES(sp)
csrr x1, mepc
STORE x1, 0 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp) STORE x4, 4 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp) STORE x5, 5 * REGBYTES(sp)
...@@ -75,9 +79,11 @@ trap_entry: ...@@ -75,9 +79,11 @@ trap_entry:
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
/* s0 --> sp */ /* s0 --> sp */
mv sp, s0
mv a0, s0 mv a0, s0
call rt_scheduler_do_irq_switch call rt_scheduler_do_irq_switch
mv sp, s0 j rt_hw_context_switch_exit
#else #else
/* switch to from_thread stack */ /* switch to from_thread stack */
...@@ -89,9 +95,6 @@ trap_entry: ...@@ -89,9 +95,6 @@ trap_entry:
beqz s2, spurious_interrupt beqz s2, spurious_interrupt
sw zero, 0(s0) sw zero, 0(s0)
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
la s0, rt_interrupt_from_thread la s0, rt_interrupt_from_thread
LOAD s1, 0(s0) LOAD s1, 0(s0)
STORE sp, 0(s1) STORE sp, 0(s1)
...@@ -100,47 +103,7 @@ trap_entry: ...@@ -100,47 +103,7 @@ trap_entry:
LOAD s1, 0(s0) LOAD s1, 0(s0)
LOAD sp, 0(s1) LOAD sp, 0(s1)
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
#endif #endif
spurious_interrupt: spurious_interrupt:
LOAD x1, 1 * REGBYTES(sp) j rt_hw_context_switch_exit
/* Remain in M-mode after mret */
li t0, 0x00001800
csrs mstatus, t0
LOAD t0, 2 * REGBYTES(sp)
csrs mstatus, t0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
mret
...@@ -128,17 +128,9 @@ static struct rt_thread* _get_highest_priority_thread(rt_ubase_t *highest_prio) ...@@ -128,17 +128,9 @@ static struct rt_thread* _get_highest_priority_thread(rt_ubase_t *highest_prio)
register struct rt_thread *highest_priority_thread; register struct rt_thread *highest_priority_thread;
register rt_ubase_t highest_ready_priority, local_highest_ready_priority; register rt_ubase_t highest_ready_priority, local_highest_ready_priority;
struct rt_cpu* pcpu = rt_cpu_self(); struct rt_cpu* pcpu = rt_cpu_self();
#if RT_THREAD_PRIORITY_MAX > 32 #if RT_THREAD_PRIORITY_MAX > 32
register rt_ubase_t number; register rt_ubase_t number;
if (rt_thread_ready_priority_group == 0 && pcpu->priority_group == 0)
{
*highest_prio = pcpu->current_thread->current_priority;
/* only local IDLE is readly */
return pcpu->current_thread;
}
number = __rt_ffs(rt_thread_ready_priority_group) - 1; number = __rt_ffs(rt_thread_ready_priority_group) - 1;
highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1; highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
number = __rt_ffs(pcpu->priority_group) - 1; number = __rt_ffs(pcpu->priority_group) - 1;
...@@ -322,8 +314,23 @@ void rt_schedule(void) ...@@ -322,8 +314,23 @@ void rt_schedule(void)
if (pcpu->irq_nest) if (pcpu->irq_nest)
{ {
pcpu->irq_switch_flag = 1; pcpu->irq_switch_flag = 1;
rt_hw_interrupt_enable(level);
goto __exit;
} }
else if (current_thread->scheduler_lock_nest == 1) /* whether lock scheduler */
#ifdef RT_USING_SIGNALS
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
{
/* if current_thread signal is in pending */
if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
{
rt_thread_resume(current_thread);
}
}
#endif
if (current_thread->scheduler_lock_nest == 1) /* whether lock scheduler */
{ {
rt_ubase_t highest_ready_priority; rt_ubase_t highest_ready_priority;
...@@ -366,27 +373,32 @@ void rt_schedule(void) ...@@ -366,27 +373,32 @@ void rt_schedule(void)
_rt_scheduler_stack_check(to_thread); _rt_scheduler_stack_check(to_thread);
#endif #endif
{ rt_hw_context_switch((rt_ubase_t)&current_thread->sp,
extern void rt_thread_handle_sig(rt_bool_t clean_state); (rt_ubase_t)&to_thread->sp, to_thread);
rt_hw_context_switch((rt_ubase_t)&current_thread->sp,
(rt_ubase_t)&to_thread->sp, to_thread);
/* enable interrupt */
rt_hw_interrupt_enable(level);
#ifdef RT_USING_SIGNALS
/* check signal status */
rt_thread_handle_sig(RT_TRUE);
#endif
goto __exit;
}
} }
} }
} }
#ifdef RT_USING_SIGNALS
if (current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
{
extern void rt_thread_handle_sig(rt_bool_t clean_state);
current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
rt_hw_interrupt_enable(level);
/* check signal status */
rt_thread_handle_sig(RT_TRUE);
}
else
{
rt_hw_interrupt_enable(level);
}
#else
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
#endif
__exit: __exit:
return ; return ;
...@@ -465,13 +477,25 @@ void rt_schedule(void) ...@@ -465,13 +477,25 @@ void rt_schedule(void)
rt_hw_context_switch((rt_ubase_t)&from_thread->sp, rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp); (rt_ubase_t)&to_thread->sp);
#ifdef RT_USING_SIGNALS
if (rt_current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
{
extern void rt_thread_handle_sig(rt_bool_t clean_state);
rt_current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
rt_hw_interrupt_enable(level);
/* check signal status */
rt_thread_handle_sig(RT_TRUE);
}
else
{
rt_hw_interrupt_enable(level);
}
#else
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
#ifdef RT_USING_SIGNALS
/* check signal status */
rt_thread_handle_sig(RT_TRUE);
#endif #endif
goto __exit; goto __exit;
} }
...@@ -519,6 +543,18 @@ void rt_scheduler_do_irq_switch(void *context) ...@@ -519,6 +543,18 @@ void rt_scheduler_do_irq_switch(void *context)
pcpu = rt_cpu_index(cpu_id); pcpu = rt_cpu_index(cpu_id);
current_thread = pcpu->current_thread; current_thread = pcpu->current_thread;
#ifdef RT_USING_SIGNALS
if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
{
/* if current_thread signal is in pending */
if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
{
rt_thread_resume(current_thread);
}
}
#endif
if (pcpu->irq_switch_flag == 0) if (pcpu->irq_switch_flag == 0)
{ {
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#endif #endif
#define DBG_TAG "SIGN" #define DBG_TAG "SIGN"
#define DBG_LVL DBG_INFO #define DBG_LVL DBG_WARNING
#include <rtdbg.h> #include <rtdbg.h>
#define sig_mask(sig_no) (1u << sig_no) #define sig_mask(sig_no) (1u << sig_no)
...@@ -52,17 +52,28 @@ static void _signal_entry(void *parameter) ...@@ -52,17 +52,28 @@ static void _signal_entry(void *parameter)
/* handle signal */ /* handle signal */
rt_thread_handle_sig(RT_FALSE); rt_thread_handle_sig(RT_FALSE);
/* never come back... */ #ifdef RT_USING_SMP
rt_hw_interrupt_disable(); {
struct rt_cpu* pcpu = rt_cpu_self();
pcpu->current_thread->cpus_lock_nest--;
if (pcpu->current_thread->cpus_lock_nest == 0)
{
pcpu->current_thread->scheduler_lock_nest--;
}
}
#else
/* return to thread */ /* return to thread */
tid->sp = tid->sig_ret; tid->sp = tid->sig_ret;
tid->sig_ret = RT_NULL; tid->sig_ret = RT_NULL;
#endif
LOG_D("switch back to: 0x%08x\n", tid->sp); LOG_D("switch back to: 0x%08x\n", tid->sp);
tid->stat &= ~RT_THREAD_STAT_SIGNAL; tid->stat &= ~RT_THREAD_STAT_SIGNAL;
#ifdef RT_USING_SMP #ifdef RT_USING_SMP
rt_hw_context_switch_to((rt_ubase_t)&(tid->sp), tid); rt_hw_context_switch_to((rt_base_t)&parameter, tid);
#else #else
rt_hw_context_switch_to((rt_ubase_t)&(tid->sp)); rt_hw_context_switch_to((rt_ubase_t)&(tid->sp));
#endif /*RT_USING_SMP*/ #endif /*RT_USING_SMP*/
...@@ -82,16 +93,21 @@ static void _signal_deliver(rt_thread_t tid) ...@@ -82,16 +93,21 @@ static void _signal_deliver(rt_thread_t tid)
{ {
rt_ubase_t level; rt_ubase_t level;
level = rt_hw_interrupt_disable();
/* thread is not interested in pended signals */ /* thread is not interested in pended signals */
if (!(tid->sig_pending & tid->sig_mask)) return; if (!(tid->sig_pending & tid->sig_mask))
{
rt_hw_interrupt_enable(level);
return;
}
level = rt_hw_interrupt_disable();
if ((tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND) if ((tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
{ {
/* resume thread to handle signal */ /* resume thread to handle signal */
rt_thread_resume(tid); rt_thread_resume(tid);
/* add signal state */ /* add signal state */
tid->stat |= RT_THREAD_STAT_SIGNAL; tid->stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
...@@ -108,17 +124,36 @@ static void _signal_deliver(rt_thread_t tid) ...@@ -108,17 +124,36 @@ static void _signal_deliver(rt_thread_t tid)
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
/* do signal action in self thread context */ /* do signal action in self thread context */
rt_thread_handle_sig(RT_TRUE); if (rt_interrupt_get_nest() == 0)
{
rt_thread_handle_sig(RT_TRUE);
}
} }
else if (!((tid->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL)) else if (!((tid->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL))
{ {
/* add signal state */ /* add signal state */
tid->stat |= RT_THREAD_STAT_SIGNAL; tid->stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);
#ifdef RT_USING_SMP
{
int cpu_id;
cpu_id = tid->oncpu;
if ((cpu_id != RT_CPU_DETACHED) && (cpu_id != rt_hw_cpu_id()))
{
rt_uint32_t cpu_mask;
cpu_mask = RT_CPU_MASK ^ (1 << cpu_id);
rt_hw_ipi_send(RT_SCHEDULE_IPI, cpu_mask);
}
}
#else
/* point to the signal handle entry */ /* point to the signal handle entry */
tid->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
tid->sig_ret = tid->sp; tid->sig_ret = tid->sp;
tid->sp = rt_hw_stack_init((void *)_signal_entry, RT_NULL, tid->sp = rt_hw_stack_init((void *)_signal_entry, RT_NULL,
(void *)((char *)tid->sig_ret - 32), RT_NULL); (void *)((char *)tid->sig_ret - 32), RT_NULL);
#endif
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
LOG_D("signal stack pointer @ 0x%08x", tid->sp); LOG_D("signal stack pointer @ 0x%08x", tid->sp);
...@@ -133,14 +168,53 @@ static void _signal_deliver(rt_thread_t tid) ...@@ -133,14 +168,53 @@ static void _signal_deliver(rt_thread_t tid)
} }
} }
#ifdef RT_USING_SMP
void *rt_signal_check(void* context)
{
rt_base_t level;
int cpu_id;
struct rt_cpu* pcpu;
struct rt_thread *current_thread;
level = rt_hw_interrupt_disable();
cpu_id = rt_hw_cpu_id();
pcpu = rt_cpu_index(cpu_id);
current_thread = pcpu->current_thread;
if (pcpu->irq_nest)
{
rt_hw_interrupt_enable(level);
return context;
}
if (current_thread->cpus_lock_nest == 1)
{
if (current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
{
void *sig_context;
current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
rt_hw_interrupt_enable(level);
sig_context = rt_hw_stack_init((void *)_signal_entry, context,
(void *)(context - 32), RT_NULL);
return sig_context;
}
}
rt_hw_interrupt_enable(level);
return context;
}
#endif
rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler) rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler)
{ {
rt_base_t level;
rt_sighandler_t old = RT_NULL; rt_sighandler_t old = RT_NULL;
rt_thread_t tid = rt_thread_self(); rt_thread_t tid = rt_thread_self();
if (!sig_valid(signo)) return SIG_ERR; if (!sig_valid(signo)) return SIG_ERR;
rt_enter_critical(); level = rt_hw_interrupt_disable();
if (tid->sig_vectors == RT_NULL) if (tid->sig_vectors == RT_NULL)
{ {
rt_thread_alloc_sig(tid); rt_thread_alloc_sig(tid);
...@@ -154,7 +228,7 @@ rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler) ...@@ -154,7 +228,7 @@ rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler)
else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler; else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler;
else tid->sig_vectors[signo] = handler; else tid->sig_vectors[signo] = handler;
} }
rt_exit_critical(); rt_hw_interrupt_enable(level);
return old; return old;
} }
...@@ -272,7 +346,20 @@ __done: ...@@ -272,7 +346,20 @@ __done:
LOG_D("sigwait: %d sig raised!", signo); LOG_D("sigwait: %d sig raised!", signo);
if (si_prev) si_prev->list.next = si_node->list.next; if (si_prev) si_prev->list.next = si_node->list.next;
else tid->si_list = si_node->list.next; else
{
struct siginfo_node *node_next;
if (si_node->list.next)
{
node_next = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
tid->si_list = node_next;
}
else
{
tid->si_list = RT_NULL;
}
}
/* clear pending */ /* clear pending */
tid->sig_pending &= ~sig_mask(signo); tid->sig_pending &= ~sig_mask(signo);
...@@ -281,7 +368,14 @@ __done: ...@@ -281,7 +368,14 @@ __done:
} }
si_prev = si_node; si_prev = si_node;
si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list); if (si_node->list.next)
{
si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
}
else
{
si_node = RT_NULL;
}
} }
__done_int: __done_int:
...@@ -320,13 +414,13 @@ void rt_thread_handle_sig(rt_bool_t clean_state) ...@@ -320,13 +414,13 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
signo = si_node->si.si_signo; signo = si_node->si.si_signo;
handler = tid->sig_vectors[signo]; handler = tid->sig_vectors[signo];
tid->sig_pending &= ~sig_mask(signo);
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
LOG_D("handle signal: %d, handler 0x%08x", signo, handler); LOG_D("handle signal: %d, handler 0x%08x", signo, handler);
if (handler) handler(signo); if (handler) handler(signo);
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
tid->sig_pending &= ~sig_mask(signo);
error = -RT_EINTR; error = -RT_EINTR;
rt_mp_free(si_node); /* release this siginfo node */ rt_mp_free(si_node); /* release this siginfo node */
...@@ -335,10 +429,16 @@ void rt_thread_handle_sig(rt_bool_t clean_state) ...@@ -335,10 +429,16 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
} }
/* whether clean signal status */ /* whether clean signal status */
if (clean_state == RT_TRUE) tid->stat &= ~RT_THREAD_STAT_SIGNAL; if (clean_state == RT_TRUE)
{
tid->stat &= ~RT_THREAD_STAT_SIGNAL;
}
else
{
return;
}
} }
} }
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
} }
...@@ -364,30 +464,30 @@ void rt_thread_alloc_sig(rt_thread_t tid) ...@@ -364,30 +464,30 @@ void rt_thread_alloc_sig(rt_thread_t tid)
void rt_thread_free_sig(rt_thread_t tid) void rt_thread_free_sig(rt_thread_t tid)
{ {
rt_base_t level; rt_base_t level;
struct siginfo_node *si_list; struct siginfo_node *si_node;
rt_sighandler_t *sig_vectors; rt_sighandler_t *sig_vectors;
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
si_list = (struct siginfo_node *)tid->si_list; si_node = (struct siginfo_node *)tid->si_list;
tid->si_list = RT_NULL; tid->si_list = RT_NULL;
sig_vectors = tid->sig_vectors; sig_vectors = tid->sig_vectors;
tid->sig_vectors = RT_NULL; tid->sig_vectors = RT_NULL;
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
if (si_list) if (si_node)
{ {
struct rt_slist_node *node; struct rt_slist_node *node;
struct siginfo_node *si_node; struct rt_slist_node *node_to_free;
LOG_D("free signal info list"); LOG_D("free signal info list");
node = &(si_list->list); node = &(si_node->list);
do do
{ {
si_node = rt_slist_entry(node, struct siginfo_node, list); node_to_free = node;
rt_mp_free(si_node);
node = node->next; node = node->next;
si_node = rt_slist_entry(node_to_free, struct siginfo_node, list);
rt_mp_free(si_node);
} while (node); } while (node);
} }
...@@ -418,30 +518,23 @@ int rt_thread_kill(rt_thread_t tid, int sig) ...@@ -418,30 +518,23 @@ int rt_thread_kill(rt_thread_t tid, int sig)
struct rt_slist_node *node; struct rt_slist_node *node;
struct siginfo_node *entry; struct siginfo_node *entry;
node = (struct rt_slist_node *)tid->si_list; si_node = (struct siginfo_node *)tid->si_list;
rt_hw_interrupt_enable(level); if (si_node)
node = (struct rt_slist_node *)&si_node->list;
else
node = RT_NULL;
/* update sig info */ /* update sig info */
rt_enter_critical();
for (; (node) != RT_NULL; node = node->next) for (; (node) != RT_NULL; node = node->next)
{ {
entry = rt_slist_entry(node, struct siginfo_node, list); entry = rt_slist_entry(node, struct siginfo_node, list);
if (entry->si.si_signo == sig) if (entry->si.si_signo == sig)
{ {
memcpy(&(entry->si), &si, sizeof(siginfo_t)); memcpy(&(entry->si), &si, sizeof(siginfo_t));
rt_exit_critical(); rt_hw_interrupt_enable(level);
return 0; return 0;
} }
} }
rt_exit_critical();
/* disable interrupt to protect tcb */
level = rt_hw_interrupt_disable();
}
else
{
/* a new signal */
tid->sig_pending |= sig_mask(sig);
} }
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
...@@ -452,14 +545,22 @@ int rt_thread_kill(rt_thread_t tid, int sig) ...@@ -452,14 +545,22 @@ int rt_thread_kill(rt_thread_t tid, int sig)
memcpy(&(si_node->si), &si, sizeof(siginfo_t)); memcpy(&(si_node->si), &si, sizeof(siginfo_t));
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
if (!tid->si_list) tid->si_list = si_node;
else if (tid->si_list)
{ {
struct siginfo_node *si_list; struct siginfo_node *si_list;
si_list = (struct siginfo_node *)tid->si_list; si_list = (struct siginfo_node *)tid->si_list;
rt_slist_append(&(si_list->list), &(si_node->list)); rt_slist_append(&(si_list->list), &(si_node->list));
} }
else
{
tid->si_list = si_node;
}
/* a new signal */
tid->sig_pending |= sig_mask(sig);
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
} }
else else
......
...@@ -191,7 +191,9 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread, ...@@ -191,7 +191,9 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread,
thread->sig_mask = 0x00; thread->sig_mask = 0x00;
thread->sig_pending = 0x00; thread->sig_pending = 0x00;
#ifndef RT_USING_SMP
thread->sig_ret = RT_NULL; thread->sig_ret = RT_NULL;
#endif
thread->sig_vectors = RT_NULL; thread->sig_vectors = RT_NULL;
thread->si_list = RT_NULL; thread->si_list = RT_NULL;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册