machinarium: implement clock tick/timers invocation

This commit is contained in:
Dmitry Simonenko 2017-04-10 15:41:14 +03:00
parent 18d6a21a42
commit dbbd2704de
4 changed files with 51 additions and 1 deletions

View File

@ -48,6 +48,8 @@ int mm_clock_timer_add(mm_clock_t *clock, mm_timer_t *timer)
list[count - 1] = timer;
mm_buf_advance(&clock->timers, sizeof(mm_timer_t*));
timer->seq = clock->timers_seq++;
timer->timeout = clock->time + timer->timeout;
timer->active = 1;
qsort(list, count, sizeof(mm_timer_t*),
mm_timers_cmp);
clock->timers_count = count;
@ -56,6 +58,8 @@ int mm_clock_timer_add(mm_clock_t *clock, mm_timer_t *timer)
int mm_clock_timer_del(mm_clock_t *clock, mm_timer_t *timer)
{
if (! timer->active)
return -1;
assert(clock->timers_count >= 1);
mm_timer_t **list = (mm_timer_t**)clock->timers.start;
int i = 0;
@ -66,6 +70,7 @@ int mm_clock_timer_del(mm_clock_t *clock, mm_timer_t *timer)
list[j] = list[i];
j++;
}
timer->active = 0;
clock->timers.pos -= sizeof(mm_timer_t*);
clock->timers_count -= 1;
qsort(list, clock->timers_count, sizeof(mm_timer_t*),
@ -81,3 +86,35 @@ mm_clock_timer_min(mm_clock_t *clock)
mm_timer_t **list = (mm_timer_t**)clock->timers.start;
return list[0];
}
int mm_clock_step(mm_clock_t *clock)
{
if (clock->timers_count == 0)
return 0;
mm_timer_t **list = (mm_timer_t**)clock->timers.start;
int timers_hit = 0;
int i = 0;
for (; i < clock->timers_count; i++) {
mm_timer_t *timer = list[i];
if (clock->time < timer->timeout)
break;
timer->callback(timer);
timer->active = 0;
timers_hit++;
list[i] = NULL;
}
if (! timers_hit)
return 0;
int timers_left = clock->timers_count - timers_hit;
if (timers_left == 0) {
mm_buf_reset(&clock->timers);
clock->timers_count = 0;
return timers_hit;
}
memmove(clock->timers.start,
clock->timers.start + sizeof(mm_timer_t*) * timers_hit,
timers_left);
clock->timers.pos -= sizeof(mm_timer_t*) * timers_hit;
clock->timers_count -= timers_hit;
return timers_hit;
}

View File

@ -18,6 +18,7 @@ struct mm_clock_t {
void mm_clock_init(mm_clock_t*);
void mm_clock_free(mm_clock_t*);
int mm_clock_step(mm_clock_t*);
int mm_clock_timer_add(mm_clock_t*, mm_timer_t*);
int mm_clock_timer_del(mm_clock_t*, mm_timer_t*);
mm_timer_t*

View File

@ -39,6 +39,7 @@ int mm_loop_step(mm_loop_t *loop)
rc = loop->poll->iface->step(loop->poll, timeout);
if (rc == -1)
return -1;
mm_clock_step(&loop->clock);
return 0;
}

View File

@ -9,13 +9,24 @@
typedef struct mm_timer_t mm_timer_t;
typedef int (*mm_timer_callback_t)(mm_timer_t*);
typedef void (*mm_timer_callback_t)(mm_timer_t*);
struct mm_timer_t {
int active;
int timeout;
int seq;
mm_timer_callback_t callback;
void *arg;
};
static inline void
mm_timer_init(mm_timer_t *timer, mm_timer_callback_t cb, int interval)
{
timer->active = 0;
timer->timeout = interval;
timer->seq = 0;
timer->callback = cb;
timer->arg = NULL;
}
#endif