Skip to content

Commit f102837

Browse files
GUIDINGLIxiaoxiang781216
authored andcommitted
sim: realize sim timer tickless
Signed-off-by: ligd <[email protected]>
1 parent d082af3 commit f102837

File tree

4 files changed

+122
-23
lines changed

4 files changed

+122
-23
lines changed

arch/sim/src/sim/posix/sim_hosttime.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,29 +93,40 @@ void host_sleepuntil(uint64_t nsec)
9393
* Set up a timer to send periodic signals.
9494
*
9595
* Input Parameters:
96-
* irq - a pointer where we save the host signal number for SIGALRM
96+
* nsec - timer expire time
9797
*
9898
* Returned Value:
9999
* On success, (0) zero value is returned, otherwise a negative value.
100100
*
101101
****************************************************************************/
102102

103-
int host_settimer(int *irq)
103+
int host_settimer(uint64_t nsec)
104104
{
105105
struct itimerval it;
106106

107-
if (irq == NULL)
108-
{
109-
return -EINVAL;
110-
}
111-
112-
*irq = SIGALRM;
113-
114107
it.it_interval.tv_sec = 0;
115-
it.it_interval.tv_usec = CONFIG_USEC_PER_TICK;
116-
it.it_value = it.it_interval;
117-
118-
/* Start a host timer at a rate indicated by CONFIG_USEC_PER_TICK */
108+
it.it_interval.tv_usec = 0;
109+
it.it_value.tv_sec = nsec / 1000000000;
110+
it.it_value.tv_usec = (nsec + 1000) / 1000;
119111

120112
return setitimer(ITIMER_REAL, &it, NULL);
121113
}
114+
115+
/****************************************************************************
116+
* Name: host_timerirq
117+
*
118+
* Description:
119+
* Get timer irq
120+
*
121+
* Input Parameters:
122+
* None
123+
*
124+
* Returned Value:
125+
* On success, irq num returned, otherwise a negative value.
126+
*
127+
****************************************************************************/
128+
129+
int host_timerirq(void)
130+
{
131+
return SIGALRM;
132+
}

arch/sim/src/sim/sim_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ void host_mallinfo(int *aordblks, int *uordblks);
177177
uint64_t host_gettime(bool rtc);
178178
void host_sleep(uint64_t nsec);
179179
void host_sleepuntil(uint64_t nsec);
180-
int host_settimer(int *irq);
180+
int host_timerirq(void);
181+
int host_settimer(uint64_t nsec);
181182

182183
/* sim_sigdeliver.c *********************************************************/
183184

arch/sim/src/sim/sim_oneshot.c

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,52 @@ static inline void sim_timer_current(struct timespec *ts)
122122
ts->tv_nsec = nsec;
123123
}
124124

125+
/****************************************************************************
126+
* Name: sim_update_hosttimer
127+
*
128+
* Description:
129+
* Ths function is called periodically to deliver the tick events to the
130+
* NuttX simulation.
131+
*
132+
****************************************************************************/
133+
134+
#ifdef CONFIG_SIM_WALLTIME_SIGNAL
135+
static void sim_update_hosttimer(void)
136+
{
137+
struct timespec *next = NULL;
138+
struct timespec current;
139+
sq_entry_t *entry;
140+
uint64_t nsec;
141+
142+
for (entry = sq_peek(&g_oneshot_list); entry; entry = sq_next(entry))
143+
{
144+
struct sim_oneshot_lowerhalf_s *priv =
145+
container_of(entry, struct sim_oneshot_lowerhalf_s, link);
146+
147+
if (next == NULL)
148+
{
149+
next = &priv->alarm;
150+
continue;
151+
}
152+
153+
if (clock_timespec_compare(next, &priv->alarm) > 0)
154+
{
155+
next = &priv->alarm;
156+
}
157+
}
158+
159+
sim_timer_current(&current);
160+
clock_timespec_subtract(next, &current, &current);
161+
162+
nsec = current.tv_sec * NSEC_PER_SEC;
163+
nsec += current.tv_nsec;
164+
165+
host_settimer(nsec);
166+
}
167+
#else
168+
# define sim_update_hosttimer()
169+
#endif
170+
125171
/****************************************************************************
126172
* Name: sim_timer_update_internal
127173
*
@@ -134,11 +180,18 @@ static inline void sim_timer_current(struct timespec *ts)
134180
static void sim_timer_update_internal(void)
135181
{
136182
sq_entry_t *entry;
183+
irqstate_t flags;
184+
185+
flags = enter_critical_section();
137186

138187
for (entry = sq_peek(&g_oneshot_list); entry; entry = sq_next(entry))
139188
{
140189
sim_process_tick(entry);
141190
}
191+
192+
sim_update_hosttimer();
193+
194+
leave_critical_section(flags);
142195
}
143196

144197
/****************************************************************************
@@ -244,15 +297,22 @@ static int sim_start(struct oneshot_lowerhalf_s *lower,
244297
struct sim_oneshot_lowerhalf_s *priv =
245298
(struct sim_oneshot_lowerhalf_s *)lower;
246299
struct timespec current;
300+
irqstate_t flags;
247301

248302
DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
249303

304+
flags = enter_critical_section();
305+
250306
sim_timer_current(&current);
251307
clock_timespec_add(&current, ts, &priv->alarm);
252308

253309
priv->callback = callback;
254310
priv->arg = arg;
255311

312+
sim_update_hosttimer();
313+
314+
leave_critical_section(flags);
315+
256316
return OK;
257317
}
258318

@@ -286,15 +346,25 @@ static int sim_cancel(struct oneshot_lowerhalf_s *lower,
286346
struct sim_oneshot_lowerhalf_s *priv =
287347
(struct sim_oneshot_lowerhalf_s *)lower;
288348
struct timespec current;
349+
irqstate_t flags;
289350

290351
DEBUGASSERT(priv != NULL && ts != NULL);
291352

353+
flags = enter_critical_section();
354+
292355
sim_timer_current(&current);
293356
clock_timespec_subtract(&priv->alarm, &current, ts);
294357

358+
priv->alarm.tv_sec = UINT_MAX;
359+
priv->alarm.tv_nsec = NSEC_PER_SEC - 1;
360+
361+
sim_update_hosttimer();
362+
295363
priv->callback = NULL;
296364
priv->arg = NULL;
297365

366+
leave_critical_section(flags);
367+
298368
return OK;
299369
}
300370

@@ -329,7 +399,7 @@ static int sim_current(struct oneshot_lowerhalf_s *lower,
329399

330400
#ifdef CONFIG_SIM_WALLTIME_SIGNAL
331401
/****************************************************************************
332-
* Name: sim_alarm_handler
402+
* Name: sim_timer_handler
333403
*
334404
* Description:
335405
* The signal handler is called periodically and is used to deliver TICK
@@ -342,7 +412,7 @@ static int sim_current(struct oneshot_lowerhalf_s *lower,
342412
*
343413
****************************************************************************/
344414

345-
static int sim_alarm_handler(int irq, void *context, void *arg)
415+
static int sim_timer_handler(int irq, void *context, void *arg)
346416
{
347417
sim_timer_update_internal();
348418
return OK;
@@ -408,14 +478,12 @@ struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
408478
void up_timer_initialize(void)
409479
{
410480
#ifdef CONFIG_SIM_WALLTIME_SIGNAL
411-
int host_alarm_irq;
412-
413-
host_settimer(&host_alarm_irq);
481+
int timer_irq = host_timerirq();
414482

415483
/* Enable the alarm handler and attach the interrupt to the NuttX logic */
416484

417-
up_enable_irq(host_alarm_irq);
418-
irq_attach(host_alarm_irq, sim_alarm_handler, NULL);
485+
up_enable_irq(timer_irq);
486+
irq_attach(timer_irq, sim_timer_handler, NULL);
419487
#endif
420488

421489
up_alarm_set_lowerhalf(oneshot_initialize(0, 0));

arch/sim/src/sim/win/sim_hosttime.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,33 @@ void host_sleepuntil(uint64_t nsec)
120120
* Set up a timer to send periodic signals.
121121
*
122122
* Input Parameters:
123-
* irq - a pointer where we save the host signal number for SIGALRM
123+
* nsec - timer expire time
124124
*
125125
* Returned Value:
126126
* On success, (0) zero value is returned, otherwise a negative value.
127127
*
128128
****************************************************************************/
129129

130-
int host_settimer(int *irq)
130+
int host_settimer(uint64_t nsec)
131131
{
132132
return -ENOSYS;
133133
}
134+
135+
/****************************************************************************
136+
* Name: host_timerirq
137+
*
138+
* Description:
139+
* Get timer irq
140+
*
141+
* Input Parameters:
142+
* None
143+
*
144+
* Returned Value:
145+
* On success, irq num returned, otherwise a negative value.
146+
*
147+
****************************************************************************/
148+
149+
int host_timerirq(void)
150+
{
151+
return 0;
152+
}

0 commit comments

Comments
 (0)