1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2017/10/5 Bernard the first version
9*10465441SEvalZero * 2018/09/17 Jesven fix: in _signal_deliver RT_THREAD_STAT_MASK to RT_THREAD_STAT_SIGNAL_MASK
10*10465441SEvalZero * 2018/11/22 Jesven in smp version rt_hw_context_switch_to add a param
11*10465441SEvalZero */
12*10465441SEvalZero
13*10465441SEvalZero #include <stdint.h>
14*10465441SEvalZero #include <string.h>
15*10465441SEvalZero
16*10465441SEvalZero #include <rthw.h>
17*10465441SEvalZero #include <rtthread.h>
18*10465441SEvalZero
19*10465441SEvalZero #ifdef RT_USING_SIGNALS
20*10465441SEvalZero
21*10465441SEvalZero #ifndef RT_SIG_INFO_MAX
22*10465441SEvalZero #define RT_SIG_INFO_MAX 32
23*10465441SEvalZero #endif
24*10465441SEvalZero
25*10465441SEvalZero // #define DBG_ENABLE
26*10465441SEvalZero #define DBG_SECTION_NAME "SIGN"
27*10465441SEvalZero #define DBG_COLOR
28*10465441SEvalZero #define DBG_LEVEL DBG_LOG
29*10465441SEvalZero #include <rtdbg.h>
30*10465441SEvalZero
31*10465441SEvalZero #define sig_mask(sig_no) (1u << sig_no)
32*10465441SEvalZero #define sig_valid(sig_no) (sig_no >= 0 && sig_no < RT_SIG_MAX)
33*10465441SEvalZero
34*10465441SEvalZero struct siginfo_node
35*10465441SEvalZero {
36*10465441SEvalZero siginfo_t si;
37*10465441SEvalZero struct rt_slist_node list;
38*10465441SEvalZero };
39*10465441SEvalZero
40*10465441SEvalZero static struct rt_mempool *_rt_siginfo_pool;
41*10465441SEvalZero static void _signal_deliver(rt_thread_t tid);
42*10465441SEvalZero void rt_thread_handle_sig(rt_bool_t clean_state);
43*10465441SEvalZero
_signal_default_handler(int signo)44*10465441SEvalZero static void _signal_default_handler(int signo)
45*10465441SEvalZero {
46*10465441SEvalZero LOG_I("handled signo[%d] with default action.", signo);
47*10465441SEvalZero return ;
48*10465441SEvalZero }
49*10465441SEvalZero
_signal_entry(void * parameter)50*10465441SEvalZero static void _signal_entry(void *parameter)
51*10465441SEvalZero {
52*10465441SEvalZero rt_thread_t tid = rt_thread_self();
53*10465441SEvalZero
54*10465441SEvalZero dbg_enter;
55*10465441SEvalZero
56*10465441SEvalZero /* handle signal */
57*10465441SEvalZero rt_thread_handle_sig(RT_FALSE);
58*10465441SEvalZero
59*10465441SEvalZero /* never come back... */
60*10465441SEvalZero rt_hw_interrupt_disable();
61*10465441SEvalZero /* return to thread */
62*10465441SEvalZero tid->sp = tid->sig_ret;
63*10465441SEvalZero tid->sig_ret = RT_NULL;
64*10465441SEvalZero
65*10465441SEvalZero LOG_D("switch back to: 0x%08x\n", tid->sp);
66*10465441SEvalZero tid->stat &= ~RT_THREAD_STAT_SIGNAL;
67*10465441SEvalZero
68*10465441SEvalZero #ifdef RT_USING_SMP
69*10465441SEvalZero rt_hw_context_switch_to((rt_ubase_t)&(tid->sp), tid);
70*10465441SEvalZero #else
71*10465441SEvalZero rt_hw_context_switch_to((rt_ubase_t)&(tid->sp));
72*10465441SEvalZero #endif /*RT_USING_SMP*/
73*10465441SEvalZero }
74*10465441SEvalZero
75*10465441SEvalZero /*
76*10465441SEvalZero * To deliver a signal to thread, there are cases:
77*10465441SEvalZero * 1. When thread is suspended, function resumes thread and
78*10465441SEvalZero * set signal stat;
79*10465441SEvalZero * 2. When thread is ready:
80*10465441SEvalZero * - If function delivers a signal to self thread, just handle
81*10465441SEvalZero * it.
82*10465441SEvalZero * - If function delivers a signal to another ready thread, OS
83*10465441SEvalZero * should build a slice context to handle it.
84*10465441SEvalZero */
_signal_deliver(rt_thread_t tid)85*10465441SEvalZero static void _signal_deliver(rt_thread_t tid)
86*10465441SEvalZero {
87*10465441SEvalZero rt_ubase_t level;
88*10465441SEvalZero
89*10465441SEvalZero /* thread is not interested in pended signals */
90*10465441SEvalZero if (!(tid->sig_pending & tid->sig_mask)) return;
91*10465441SEvalZero
92*10465441SEvalZero level = rt_hw_interrupt_disable();
93*10465441SEvalZero if ((tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
94*10465441SEvalZero {
95*10465441SEvalZero /* resume thread to handle signal */
96*10465441SEvalZero rt_thread_resume(tid);
97*10465441SEvalZero /* add signal state */
98*10465441SEvalZero tid->stat |= RT_THREAD_STAT_SIGNAL;
99*10465441SEvalZero
100*10465441SEvalZero rt_hw_interrupt_enable(level);
101*10465441SEvalZero
102*10465441SEvalZero /* re-schedule */
103*10465441SEvalZero rt_schedule();
104*10465441SEvalZero }
105*10465441SEvalZero else
106*10465441SEvalZero {
107*10465441SEvalZero if (tid == rt_thread_self())
108*10465441SEvalZero {
109*10465441SEvalZero /* add signal state */
110*10465441SEvalZero tid->stat |= RT_THREAD_STAT_SIGNAL;
111*10465441SEvalZero
112*10465441SEvalZero rt_hw_interrupt_enable(level);
113*10465441SEvalZero
114*10465441SEvalZero /* do signal action in self thread context */
115*10465441SEvalZero rt_thread_handle_sig(RT_TRUE);
116*10465441SEvalZero }
117*10465441SEvalZero else if (!((tid->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL))
118*10465441SEvalZero {
119*10465441SEvalZero /* add signal state */
120*10465441SEvalZero tid->stat |= RT_THREAD_STAT_SIGNAL;
121*10465441SEvalZero
122*10465441SEvalZero /* point to the signal handle entry */
123*10465441SEvalZero tid->sig_ret = tid->sp;
124*10465441SEvalZero tid->sp = rt_hw_stack_init((void *)_signal_entry, RT_NULL,
125*10465441SEvalZero (void *)((char *)tid->sig_ret - 32), RT_NULL);
126*10465441SEvalZero
127*10465441SEvalZero rt_hw_interrupt_enable(level);
128*10465441SEvalZero LOG_D("signal stack pointer @ 0x%08x", tid->sp);
129*10465441SEvalZero
130*10465441SEvalZero /* re-schedule */
131*10465441SEvalZero rt_schedule();
132*10465441SEvalZero }
133*10465441SEvalZero else
134*10465441SEvalZero {
135*10465441SEvalZero rt_hw_interrupt_enable(level);
136*10465441SEvalZero }
137*10465441SEvalZero }
138*10465441SEvalZero }
139*10465441SEvalZero
rt_signal_install(int signo,rt_sighandler_t handler)140*10465441SEvalZero rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler)
141*10465441SEvalZero {
142*10465441SEvalZero rt_sighandler_t old = RT_NULL;
143*10465441SEvalZero rt_thread_t tid = rt_thread_self();
144*10465441SEvalZero
145*10465441SEvalZero if (!sig_valid(signo)) return SIG_ERR;
146*10465441SEvalZero
147*10465441SEvalZero rt_enter_critical();
148*10465441SEvalZero if (tid->sig_vectors == RT_NULL)
149*10465441SEvalZero {
150*10465441SEvalZero rt_thread_alloc_sig(tid);
151*10465441SEvalZero }
152*10465441SEvalZero
153*10465441SEvalZero if (tid->sig_vectors)
154*10465441SEvalZero {
155*10465441SEvalZero old = tid->sig_vectors[signo];
156*10465441SEvalZero
157*10465441SEvalZero if (handler == SIG_IGN) tid->sig_vectors[signo] = RT_NULL;
158*10465441SEvalZero else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler;
159*10465441SEvalZero else tid->sig_vectors[signo] = handler;
160*10465441SEvalZero }
161*10465441SEvalZero rt_exit_critical();
162*10465441SEvalZero
163*10465441SEvalZero return old;
164*10465441SEvalZero }
165*10465441SEvalZero
rt_signal_mask(int signo)166*10465441SEvalZero void rt_signal_mask(int signo)
167*10465441SEvalZero {
168*10465441SEvalZero rt_base_t level;
169*10465441SEvalZero rt_thread_t tid = rt_thread_self();
170*10465441SEvalZero
171*10465441SEvalZero level = rt_hw_interrupt_disable();
172*10465441SEvalZero
173*10465441SEvalZero tid->sig_mask &= ~sig_mask(signo);
174*10465441SEvalZero
175*10465441SEvalZero rt_hw_interrupt_enable(level);
176*10465441SEvalZero }
177*10465441SEvalZero
rt_signal_unmask(int signo)178*10465441SEvalZero void rt_signal_unmask(int signo)
179*10465441SEvalZero {
180*10465441SEvalZero rt_base_t level;
181*10465441SEvalZero rt_thread_t tid = rt_thread_self();
182*10465441SEvalZero
183*10465441SEvalZero level = rt_hw_interrupt_disable();
184*10465441SEvalZero
185*10465441SEvalZero tid->sig_mask |= sig_mask(signo);
186*10465441SEvalZero
187*10465441SEvalZero /* let thread handle pended signals */
188*10465441SEvalZero if (tid->sig_mask & tid->sig_pending)
189*10465441SEvalZero {
190*10465441SEvalZero rt_hw_interrupt_enable(level);
191*10465441SEvalZero _signal_deliver(tid);
192*10465441SEvalZero }
193*10465441SEvalZero else
194*10465441SEvalZero {
195*10465441SEvalZero rt_hw_interrupt_enable(level);
196*10465441SEvalZero }
197*10465441SEvalZero }
198*10465441SEvalZero
rt_signal_wait(const rt_sigset_t * set,rt_siginfo_t * si,rt_int32_t timeout)199*10465441SEvalZero int rt_signal_wait(const rt_sigset_t *set, rt_siginfo_t *si, rt_int32_t timeout)
200*10465441SEvalZero {
201*10465441SEvalZero int ret = RT_EOK;
202*10465441SEvalZero rt_base_t level;
203*10465441SEvalZero rt_thread_t tid = rt_thread_self();
204*10465441SEvalZero struct siginfo_node *si_node = RT_NULL, *si_prev = RT_NULL;
205*10465441SEvalZero
206*10465441SEvalZero /* current context checking */
207*10465441SEvalZero RT_DEBUG_IN_THREAD_CONTEXT;
208*10465441SEvalZero
209*10465441SEvalZero /* parameters check */
210*10465441SEvalZero if (set == NULL || *set == 0 || si == NULL )
211*10465441SEvalZero {
212*10465441SEvalZero ret = -RT_EINVAL;
213*10465441SEvalZero goto __done_return;
214*10465441SEvalZero }
215*10465441SEvalZero
216*10465441SEvalZero /* clear siginfo to avoid unknown value */
217*10465441SEvalZero memset(si, 0x0, sizeof(rt_siginfo_t));
218*10465441SEvalZero
219*10465441SEvalZero level = rt_hw_interrupt_disable();
220*10465441SEvalZero
221*10465441SEvalZero /* already pending */
222*10465441SEvalZero if (tid->sig_pending & *set) goto __done;
223*10465441SEvalZero
224*10465441SEvalZero if (timeout == 0)
225*10465441SEvalZero {
226*10465441SEvalZero ret = -RT_ETIMEOUT;
227*10465441SEvalZero goto __done_int;
228*10465441SEvalZero }
229*10465441SEvalZero
230*10465441SEvalZero /* suspend self thread */
231*10465441SEvalZero rt_thread_suspend(tid);
232*10465441SEvalZero /* set thread stat as waiting for signal */
233*10465441SEvalZero tid->stat |= RT_THREAD_STAT_SIGNAL_WAIT;
234*10465441SEvalZero
235*10465441SEvalZero /* start timeout timer */
236*10465441SEvalZero if (timeout != RT_WAITING_FOREVER)
237*10465441SEvalZero {
238*10465441SEvalZero /* reset the timeout of thread timer and start it */
239*10465441SEvalZero rt_timer_control(&(tid->thread_timer),
240*10465441SEvalZero RT_TIMER_CTRL_SET_TIME,
241*10465441SEvalZero &timeout);
242*10465441SEvalZero rt_timer_start(&(tid->thread_timer));
243*10465441SEvalZero }
244*10465441SEvalZero rt_hw_interrupt_enable(level);
245*10465441SEvalZero
246*10465441SEvalZero /* do thread scheduling */
247*10465441SEvalZero rt_schedule();
248*10465441SEvalZero
249*10465441SEvalZero level = rt_hw_interrupt_disable();
250*10465441SEvalZero
251*10465441SEvalZero /* remove signal waiting flag */
252*10465441SEvalZero tid->stat &= ~RT_THREAD_STAT_SIGNAL_WAIT;
253*10465441SEvalZero
254*10465441SEvalZero /* check errno of thread */
255*10465441SEvalZero if (tid->error == -RT_ETIMEOUT)
256*10465441SEvalZero {
257*10465441SEvalZero tid->error = RT_EOK;
258*10465441SEvalZero rt_hw_interrupt_enable(level);
259*10465441SEvalZero
260*10465441SEvalZero /* timer timeout */
261*10465441SEvalZero ret = -RT_ETIMEOUT;
262*10465441SEvalZero goto __done_return;
263*10465441SEvalZero }
264*10465441SEvalZero
265*10465441SEvalZero __done:
266*10465441SEvalZero /* to get the first matched pending signals */
267*10465441SEvalZero si_node = (struct siginfo_node *)tid->si_list;
268*10465441SEvalZero while (si_node)
269*10465441SEvalZero {
270*10465441SEvalZero int signo;
271*10465441SEvalZero
272*10465441SEvalZero signo = si_node->si.si_signo;
273*10465441SEvalZero if (sig_mask(signo) & *set)
274*10465441SEvalZero {
275*10465441SEvalZero *si = si_node->si;
276*10465441SEvalZero
277*10465441SEvalZero LOG_D("sigwait: %d sig raised!", signo);
278*10465441SEvalZero if (si_prev) si_prev->list.next = si_node->list.next;
279*10465441SEvalZero else tid->si_list = si_node->list.next;
280*10465441SEvalZero
281*10465441SEvalZero /* clear pending */
282*10465441SEvalZero tid->sig_pending &= ~sig_mask(signo);
283*10465441SEvalZero rt_mp_free(si_node);
284*10465441SEvalZero break;
285*10465441SEvalZero }
286*10465441SEvalZero
287*10465441SEvalZero si_prev = si_node;
288*10465441SEvalZero si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
289*10465441SEvalZero }
290*10465441SEvalZero
291*10465441SEvalZero __done_int:
292*10465441SEvalZero rt_hw_interrupt_enable(level);
293*10465441SEvalZero
294*10465441SEvalZero __done_return:
295*10465441SEvalZero return ret;
296*10465441SEvalZero }
297*10465441SEvalZero
rt_thread_handle_sig(rt_bool_t clean_state)298*10465441SEvalZero void rt_thread_handle_sig(rt_bool_t clean_state)
299*10465441SEvalZero {
300*10465441SEvalZero rt_base_t level;
301*10465441SEvalZero
302*10465441SEvalZero rt_thread_t tid = rt_thread_self();
303*10465441SEvalZero struct siginfo_node *si_node;
304*10465441SEvalZero
305*10465441SEvalZero level = rt_hw_interrupt_disable();
306*10465441SEvalZero if (tid->sig_pending & tid->sig_mask)
307*10465441SEvalZero {
308*10465441SEvalZero /* if thread is not waiting for signal */
309*10465441SEvalZero if (!(tid->stat & RT_THREAD_STAT_SIGNAL_WAIT))
310*10465441SEvalZero {
311*10465441SEvalZero while (tid->sig_pending & tid->sig_mask)
312*10465441SEvalZero {
313*10465441SEvalZero int signo, error;
314*10465441SEvalZero rt_sighandler_t handler;
315*10465441SEvalZero
316*10465441SEvalZero si_node = (struct siginfo_node *)tid->si_list;
317*10465441SEvalZero if (!si_node) break;
318*10465441SEvalZero
319*10465441SEvalZero /* remove this sig info node from list */
320*10465441SEvalZero if (si_node->list.next == RT_NULL)
321*10465441SEvalZero tid->si_list = RT_NULL;
322*10465441SEvalZero else
323*10465441SEvalZero tid->si_list = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
324*10465441SEvalZero
325*10465441SEvalZero signo = si_node->si.si_signo;
326*10465441SEvalZero handler = tid->sig_vectors[signo];
327*10465441SEvalZero rt_hw_interrupt_enable(level);
328*10465441SEvalZero
329*10465441SEvalZero LOG_D("handle signal: %d, handler 0x%08x", signo, handler);
330*10465441SEvalZero if (handler) handler(signo);
331*10465441SEvalZero
332*10465441SEvalZero level = rt_hw_interrupt_disable();
333*10465441SEvalZero tid->sig_pending &= ~sig_mask(signo);
334*10465441SEvalZero error = -RT_EINTR;
335*10465441SEvalZero
336*10465441SEvalZero rt_mp_free(si_node); /* release this siginfo node */
337*10465441SEvalZero /* set errno in thread tcb */
338*10465441SEvalZero tid->error = error;
339*10465441SEvalZero }
340*10465441SEvalZero
341*10465441SEvalZero /* whether clean signal status */
342*10465441SEvalZero if (clean_state == RT_TRUE) tid->stat &= ~RT_THREAD_STAT_SIGNAL;
343*10465441SEvalZero }
344*10465441SEvalZero }
345*10465441SEvalZero
346*10465441SEvalZero rt_hw_interrupt_enable(level);
347*10465441SEvalZero }
348*10465441SEvalZero
rt_thread_alloc_sig(rt_thread_t tid)349*10465441SEvalZero void rt_thread_alloc_sig(rt_thread_t tid)
350*10465441SEvalZero {
351*10465441SEvalZero int index;
352*10465441SEvalZero rt_base_t level;
353*10465441SEvalZero rt_sighandler_t *vectors;
354*10465441SEvalZero
355*10465441SEvalZero vectors = (rt_sighandler_t *)RT_KERNEL_MALLOC(sizeof(rt_sighandler_t) * RT_SIG_MAX);
356*10465441SEvalZero RT_ASSERT(vectors != RT_NULL);
357*10465441SEvalZero
358*10465441SEvalZero for (index = 0; index < RT_SIG_MAX; index ++)
359*10465441SEvalZero {
360*10465441SEvalZero vectors[index] = _signal_default_handler;
361*10465441SEvalZero }
362*10465441SEvalZero
363*10465441SEvalZero level = rt_hw_interrupt_disable();
364*10465441SEvalZero tid->sig_vectors = vectors;
365*10465441SEvalZero rt_hw_interrupt_enable(level);
366*10465441SEvalZero }
367*10465441SEvalZero
rt_thread_free_sig(rt_thread_t tid)368*10465441SEvalZero void rt_thread_free_sig(rt_thread_t tid)
369*10465441SEvalZero {
370*10465441SEvalZero rt_base_t level;
371*10465441SEvalZero struct siginfo_node *si_list;
372*10465441SEvalZero rt_sighandler_t *sig_vectors;
373*10465441SEvalZero
374*10465441SEvalZero level = rt_hw_interrupt_disable();
375*10465441SEvalZero si_list = (struct siginfo_node *)tid->si_list;
376*10465441SEvalZero tid->si_list = RT_NULL;
377*10465441SEvalZero
378*10465441SEvalZero sig_vectors = tid->sig_vectors;
379*10465441SEvalZero tid->sig_vectors = RT_NULL;
380*10465441SEvalZero rt_hw_interrupt_enable(level);
381*10465441SEvalZero
382*10465441SEvalZero if (si_list)
383*10465441SEvalZero {
384*10465441SEvalZero struct rt_slist_node *node;
385*10465441SEvalZero struct siginfo_node *si_node;
386*10465441SEvalZero
387*10465441SEvalZero LOG_D("free signal info list");
388*10465441SEvalZero node = &(si_list->list);
389*10465441SEvalZero do
390*10465441SEvalZero {
391*10465441SEvalZero si_node = rt_slist_entry(node, struct siginfo_node, list);
392*10465441SEvalZero rt_mp_free(si_node);
393*10465441SEvalZero
394*10465441SEvalZero node = node->next;
395*10465441SEvalZero } while (node);
396*10465441SEvalZero }
397*10465441SEvalZero
398*10465441SEvalZero if (sig_vectors)
399*10465441SEvalZero {
400*10465441SEvalZero RT_KERNEL_FREE(sig_vectors);
401*10465441SEvalZero }
402*10465441SEvalZero }
403*10465441SEvalZero
rt_thread_kill(rt_thread_t tid,int sig)404*10465441SEvalZero int rt_thread_kill(rt_thread_t tid, int sig)
405*10465441SEvalZero {
406*10465441SEvalZero siginfo_t si;
407*10465441SEvalZero rt_base_t level;
408*10465441SEvalZero struct siginfo_node *si_node;
409*10465441SEvalZero
410*10465441SEvalZero RT_ASSERT(tid != RT_NULL);
411*10465441SEvalZero if (!sig_valid(sig)) return -RT_EINVAL;
412*10465441SEvalZero
413*10465441SEvalZero LOG_I("send signal: %d", sig);
414*10465441SEvalZero si.si_signo = sig;
415*10465441SEvalZero si.si_code = SI_USER;
416*10465441SEvalZero si.si_value.sival_ptr = RT_NULL;
417*10465441SEvalZero
418*10465441SEvalZero level = rt_hw_interrupt_disable();
419*10465441SEvalZero if (tid->sig_pending & sig_mask(sig))
420*10465441SEvalZero {
421*10465441SEvalZero /* whether already emits this signal? */
422*10465441SEvalZero struct rt_slist_node *node;
423*10465441SEvalZero struct siginfo_node *entry;
424*10465441SEvalZero
425*10465441SEvalZero node = (struct rt_slist_node *)tid->si_list;
426*10465441SEvalZero rt_hw_interrupt_enable(level);
427*10465441SEvalZero
428*10465441SEvalZero /* update sig info */
429*10465441SEvalZero rt_enter_critical();
430*10465441SEvalZero for (; (node) != RT_NULL; node = node->next)
431*10465441SEvalZero {
432*10465441SEvalZero entry = rt_slist_entry(node, struct siginfo_node, list);
433*10465441SEvalZero if (entry->si.si_signo == sig)
434*10465441SEvalZero {
435*10465441SEvalZero memcpy(&(entry->si), &si, sizeof(siginfo_t));
436*10465441SEvalZero rt_exit_critical();
437*10465441SEvalZero return 0;
438*10465441SEvalZero }
439*10465441SEvalZero }
440*10465441SEvalZero rt_exit_critical();
441*10465441SEvalZero
442*10465441SEvalZero /* disable interrupt to protect tcb */
443*10465441SEvalZero level = rt_hw_interrupt_disable();
444*10465441SEvalZero }
445*10465441SEvalZero else
446*10465441SEvalZero {
447*10465441SEvalZero /* a new signal */
448*10465441SEvalZero tid->sig_pending |= sig_mask(sig);
449*10465441SEvalZero }
450*10465441SEvalZero rt_hw_interrupt_enable(level);
451*10465441SEvalZero
452*10465441SEvalZero si_node = (struct siginfo_node *) rt_mp_alloc(_rt_siginfo_pool, 0);
453*10465441SEvalZero if (si_node)
454*10465441SEvalZero {
455*10465441SEvalZero rt_slist_init(&(si_node->list));
456*10465441SEvalZero memcpy(&(si_node->si), &si, sizeof(siginfo_t));
457*10465441SEvalZero
458*10465441SEvalZero level = rt_hw_interrupt_disable();
459*10465441SEvalZero if (!tid->si_list) tid->si_list = si_node;
460*10465441SEvalZero else
461*10465441SEvalZero {
462*10465441SEvalZero struct siginfo_node *si_list;
463*10465441SEvalZero
464*10465441SEvalZero si_list = (struct siginfo_node *)tid->si_list;
465*10465441SEvalZero rt_slist_append(&(si_list->list), &(si_node->list));
466*10465441SEvalZero }
467*10465441SEvalZero rt_hw_interrupt_enable(level);
468*10465441SEvalZero }
469*10465441SEvalZero else
470*10465441SEvalZero {
471*10465441SEvalZero LOG_E("The allocation of signal info node failed.");
472*10465441SEvalZero }
473*10465441SEvalZero
474*10465441SEvalZero /* deliver signal to this thread */
475*10465441SEvalZero _signal_deliver(tid);
476*10465441SEvalZero
477*10465441SEvalZero return RT_EOK;
478*10465441SEvalZero }
479*10465441SEvalZero
rt_system_signal_init(void)480*10465441SEvalZero int rt_system_signal_init(void)
481*10465441SEvalZero {
482*10465441SEvalZero _rt_siginfo_pool = rt_mp_create("signal", RT_SIG_INFO_MAX, sizeof(struct siginfo_node));
483*10465441SEvalZero if (_rt_siginfo_pool == RT_NULL)
484*10465441SEvalZero {
485*10465441SEvalZero LOG_E("create memory pool for signal info failed.");
486*10465441SEvalZero RT_ASSERT(0);
487*10465441SEvalZero }
488*10465441SEvalZero
489*10465441SEvalZero return 0;
490*10465441SEvalZero }
491*10465441SEvalZero
492*10465441SEvalZero #endif
493