1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-11-30     Shell        Add itimer support
9  */
10 
11 #define _GNU_SOURCE
12 #include <sys/time.h>
13 #undef _GNU_SOURCE
14 
15 #define DBG_TAG "lwp.signal"
16 #define DBG_LVL DBG_INFO
17 #include <rtdbg.h>
18 
19 #include <rthw.h>
20 #include <rtthread.h>
21 #include <string.h>
22 
23 #include "lwp_internal.h"
24 #include "sys/signal.h"
25 #include "syscall_generic.h"
26 
lwp_signal_setitimer(rt_lwp_t lwp,int which,const struct itimerspec * restrict new,struct itimerspec * restrict old)27 rt_err_t lwp_signal_setitimer(rt_lwp_t lwp, int which, const struct itimerspec *restrict new, struct itimerspec *restrict old)
28 {
29     rt_err_t rc = RT_EOK;
30     timer_t timerid = 0;
31     int flags = 0;
32 
33     if (lwp->signal.real_timer == LWP_SIG_INVALID_TIMER)
34     {
35         struct sigevent sevp = {
36             .sigev_signo = SIGALRM,
37             .sigev_notify = SIGEV_SIGNAL,
38         };
39 
40         rc = timer_create(CLOCK_REALTIME_ALARM, &sevp, &timerid);
41         if (rc == RT_EOK)
42         {
43             RT_ASSERT(timerid != LWP_SIG_INVALID_TIMER);
44             lwp->signal.real_timer = timerid;
45         }
46         else
47         {
48             /* failed to create timer */
49         }
50     }
51     else
52     {
53         timerid = lwp->signal.real_timer;
54     }
55 
56     if (rc == RT_EOK)
57     {
58         switch (which)
59         {
60             case ITIMER_REAL:
61                 rc = timer_settime(timerid, flags, new, old);
62                 break;
63             default:
64                 rc = -ENOSYS;
65                 LOG_W("%s() unsupported timer", __func__);
66                 break;
67         }
68     }
69 
70     return rc;
71 }
72