19#ifdef RT_USING_SIGNALS
21#ifndef RT_SIG_INFO_MAX
23 #define RT_SIG_INFO_MAX 64
25 #define RT_SIG_INFO_MAX 32
30#define DBG_LVL DBG_WARNING
33#ifdef RT_USING_MUSLLIBC
34 #define sig_mask(sig_no) (1u << (sig_no - 1))
36 #define sig_mask(sig_no) (1u << sig_no)
38#define sig_valid(sig_no) (sig_no >= 0 && sig_no < RT_SIG_MAX)
45 struct rt_slist_node list;
50void rt_thread_handle_sig(
rt_bool_t clean_state);
52static void _signal_default_handler(
int signo)
55 LOG_I(
"handled signo[%d] with default action.", signo);
59static void _signal_entry(
void *parameter)
71 tid->
sp = tid->sig_ret;
75 LOG_D(
"switch back to: 0x%08x\n", tid->
sp);
102 if (!(tid->sig_pending & tid->sig_mask))
112 rt_thread_wakeup(tid);
149 if ((cpu_id != RT_CPU_DETACHED) && (cpu_id !=
rt_cpu_get_id()))
153 cpu_mask = RT_CPU_MASK ^ (1 << cpu_id);
154 rt_hw_ipi_send(RT_SCHEDULE_IPI, cpu_mask);
160 tid->sig_ret = tid->
sp;
162 (
void *)((
char *)tid->sig_ret - 32),
RT_NULL);
166 LOG_D(
"signal stack pointer @ 0x%08x", tid->
sp);
179void *rt_signal_check(
void* context)
198 if (current_thread->cpus_lock_nest == 1)
208 (
void*)((
char*)context - 32),
RT_NULL);
233rt_sighandler_t rt_signal_install(
int signo, rt_sighandler_t handler)
239 if (!sig_valid(signo))
return SIG_ERR;
242 if (tid->sig_vectors ==
RT_NULL)
246 rt_thread_alloc_sig(tid);
251 if (tid->sig_vectors)
253 old = tid->sig_vectors[signo];
255 if (handler == SIG_IGN) tid->sig_vectors[signo] =
RT_NULL;
256 else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler;
257 else tid->sig_vectors[signo] = handler;
275void rt_signal_mask(
int signo)
282 tid->sig_mask &= ~sig_mask(signo);
298void rt_signal_unmask(
int signo)
305 tid->sig_mask |= sig_mask(signo);
308 if (tid->sig_mask & tid->sig_pending)
311 _signal_deliver(tid);
333int rt_signal_wait(
const rt_sigset_t *set, rt_siginfo_t *si,
rt_int32_t timeout)
344 if (set == NULL || *set == 0 || si == NULL )
351 memset(si, 0x0,
sizeof(rt_siginfo_t));
356 if (tid->sig_pending & *set)
goto __done;
389 if (tid->
error == -RT_ETIMEOUT)
401 si_node = (
struct siginfo_node *)tid->si_list;
406 signo = si_node->si.si_signo;
407 if (sig_mask(signo) & *set)
411 LOG_D(
"sigwait: %d sig raised!", signo);
412 if (si_prev) si_prev->list.next = si_node->list.next;
415 struct siginfo_node *node_next;
417 if (si_node->list.next)
419 node_next = (
void *)
rt_slist_entry(si_node->list.next,
struct siginfo_node, list);
420 tid->si_list = node_next;
429 tid->sig_pending &= ~sig_mask(signo);
435 if (si_node->list.next)
437 si_node = (
void *)
rt_slist_entry(si_node->list.next,
struct siginfo_node, list);
452void rt_thread_handle_sig(
rt_bool_t clean_state)
457 struct siginfo_node *si_node;
460 if (tid->sig_pending & tid->sig_mask)
465 while (tid->sig_pending & tid->sig_mask)
468 rt_sighandler_t handler;
470 si_node = (
struct siginfo_node *)tid->si_list;
474 if (si_node->list.next ==
RT_NULL)
477 tid->si_list = (
void *)
rt_slist_entry(si_node->list.next,
struct siginfo_node, list);
479 signo = si_node->si.si_signo;
480 handler = tid->sig_vectors[signo];
481 tid->sig_pending &= ~sig_mask(signo);
484 LOG_D(
"handle signal: %d, handler 0x%08x", signo, handler);
485 if (handler) handler(signo);
514 rt_sighandler_t *vectors;
516 vectors = (rt_sighandler_t *)
RT_KERNEL_MALLOC(
sizeof(rt_sighandler_t) * RT_SIG_MAX);
519 for (index = 0; index < RT_SIG_MAX; index ++)
521 vectors[index] = _signal_default_handler;
526 if (tid->sig_vectors ==
RT_NULL)
528 tid->sig_vectors = vectors;
546 struct siginfo_node *si_node;
547 rt_sighandler_t *sig_vectors;
550 si_node = (
struct siginfo_node *)tid->si_list;
553 sig_vectors = tid->sig_vectors;
562 LOG_D(
"free signal info list");
563 node = &(si_node->list);
568 si_node =
rt_slist_entry(node_to_free,
struct siginfo_node, list);
593 struct siginfo_node *si_node;
596 if (!sig_valid(sig))
return -RT_EINVAL;
598 LOG_I(
"send signal: %d", sig);
600 si.si_code = SI_USER;
601 si.si_value.sival_ptr =
RT_NULL;
604 if (tid->sig_pending & sig_mask(sig))
608 struct siginfo_node *entry;
610 si_node = (
struct siginfo_node *)tid->si_list;
620 if (entry->si.si_signo == sig)
622 memcpy(&(entry->si), &si,
sizeof(siginfo_t));
630 si_node = (
struct siginfo_node *)
rt_mp_alloc(_siginfo_pool, 0);
634 memcpy(&(si_node->si), &si,
sizeof(siginfo_t));
640 struct siginfo_node *si_list;
642 si_list = (
struct siginfo_node *)tid->si_list;
647 tid->si_list = si_node;
651 tid->sig_pending |= sig_mask(sig);
657 LOG_E(
"The allocation of signal info node failed.");
662 _signal_deliver(tid);
667int rt_system_signal_init(
void)
669 _siginfo_pool =
rt_mp_create(
"signal", RT_SIG_INFO_MAX,
sizeof(
struct siginfo_node));
672 LOG_E(
"create memory pool for signal info failed.");
struct rt_cpu * rt_cpu_index(int index)
This fucntion will return the cpu object corresponding to index.
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
This function will get or set some options of the timer
rt_err_t rt_timer_start(rt_timer_t timer)
This function will start the timer
#define RT_TIMER_CTRL_SET_TIME
int stat(const char *file, struct stat *buf)
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
This function will disable the local interrupt and then lock the spinlock, will lock the thread sched...
#define RT_WAITING_FOREVER
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
This function will unlock the spinlock and then restore current cpu interrupt status,...
rt_weak rt_uint8_t rt_interrupt_get_nest(void)
This function will return the nest of interrupt.
rt_inline void rt_slist_init(rt_slist_t *l)
initialize a single list
#define rt_slist_entry(node, type, member)
get the struct for this single list node
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
#define RT_DEBUG_IN_THREAD_CONTEXT
void * rt_mp_alloc(rt_mp_t mp, rt_int32_t time)
This function will allocate a block from memory pool.
void rt_mp_free(void *block)
This function will release a memory block.
rt_mp_t rt_mp_create(const char *name, rt_size_t block_count, rt_size_t block_size)
This function will create a mempool object and allocate the memory pool from heap.
#define RT_THREAD_STAT_SIGNAL_MASK
#define RT_THREAD_STAT_SIGNAL_WAIT
rt_err_t rt_thread_suspend_with_flag(rt_thread_t thread, int suspend_flag)
This function will suspend the specified thread and change it to suspend state.
rt_thread_t rt_thread_self(void)
This function will return self thread object.
#define RT_THREAD_STAT_SIGNAL_PENDING
rt_err_t rt_thread_resume(rt_thread_t thread)
This function will resume a thread and put it to system ready queue.
struct rt_thread * rt_thread_t
#define RT_THREAD_SUSPEND_MASK
void rt_schedule(void)
This function will perform one scheduling. It will select one thread with the highest priority level ...
#define RT_THREAD_STAT_SIGNAL
#define RT_KERNEL_FREE(ptr)
#define RT_KERNEL_MALLOC(sz)
void rt_hw_context_switch_to(rt_ubase_t to)
rt_uint8_t * rt_hw_stack_init(void *entry, void *parameter, rt_uint8_t *stack_addr, void *exit)
#define RT_SCHED_CTX(thread)
rt_ubase_t rt_sched_lock_level_t
struct rt_thread * current_thread
struct rt_slist_node * next
RT_SCHED_THREAD_CTX struct rt_timer thread_timer