Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The following is a group of versatile C functions for timer management based on the gettimeofday() system call. All the timer properties are contained in a single ticktimer struct - the interval you want, the total running time since the timer initialization, a pointer to the desired callback you want to call, the number of times the callback was called. A callback function would look like this:</p> <pre><code>void your_timer_cb (struct ticktimer *t) { /* do your stuff here */ } </code></pre> <p>To initialize and start a timer, call ticktimer_init(your_timer, interval, TICKTIMER_RUN, your_timer_cb, 0).</p> <p>In the main loop of your program call ticktimer_tick(your_timer) and it will decide whether the appropriate amount of time has passed to invoke the callback.</p> <p>To stop a timer, just call ticktimer_ctl(your_timer, TICKTIMER_STOP).</p> <p>ticktimer.h:</p> <pre><code>#ifndef __TICKTIMER_H #define __TICKTIMER_H #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/time.h&gt; #include &lt;sys/types.h&gt; #define TICKTIMER_STOP 0x00 #define TICKTIMER_UNCOMPENSATE 0x00 #define TICKTIMER_RUN 0x01 #define TICKTIMER_COMPENSATE 0x02 struct ticktimer { u_int64_t tm_tick_interval; u_int64_t tm_last_ticked; u_int64_t tm_total; unsigned ticks_total; void (*tick)(struct ticktimer *); unsigned char flags; int id; }; void ticktimer_init (struct ticktimer *, u_int64_t, unsigned char, void (*)(struct ticktimer *), int); unsigned ticktimer_tick (struct ticktimer *); void ticktimer_ctl (struct ticktimer *, unsigned char); struct ticktimer *ticktimer_alloc (void); void ticktimer_free (struct ticktimer *); void ticktimer_tick_all (void); #endif </code></pre> <p>ticktimer.c:</p> <pre><code>#include "ticktimer.h" #define TIMER_COUNT 100 static struct ticktimer timers[TIMER_COUNT]; static struct timeval tm; /*! @brief Initializes/sets the ticktimer struct. @param timer Pointer to ticktimer struct. @param interval Ticking interval in microseconds. @param flags Flag bitmask. Use TICKTIMER_RUN | TICKTIMER_COMPENSATE to start a compensating timer; TICKTIMER_RUN to start a normal uncompensating timer. @param tick Ticking callback function. @param id Timer ID. Useful if you want to distinguish different timers within the same callback function. */ void ticktimer_init (struct ticktimer *timer, u_int64_t interval, unsigned char flags, void (*tick)(struct ticktimer *), int id) { gettimeofday(&amp;tm, NULL); timer-&gt;tm_tick_interval = interval; timer-&gt;tm_last_ticked = tm.tv_sec * 1000000 + tm.tv_usec; timer-&gt;tm_total = 0; timer-&gt;ticks_total = 0; timer-&gt;tick = tick; timer-&gt;flags = flags; timer-&gt;id = id; } /*! @brief Checks the status of a ticktimer and performs a tick(s) if necessary. @param timer Pointer to ticktimer struct. @return The number of times the timer was ticked. */ unsigned ticktimer_tick (struct ticktimer *timer) { register typeof(timer-&gt;tm_tick_interval) now; register typeof(timer-&gt;ticks_total) nticks, i; if (timer-&gt;flags &amp; TICKTIMER_RUN) { gettimeofday(&amp;tm, NULL); now = tm.tv_sec * 1000000 + tm.tv_usec; if (now &gt;= timer-&gt;tm_last_ticked + timer-&gt;tm_tick_interval) { timer-&gt;tm_total += now - timer-&gt;tm_last_ticked; if (timer-&gt;flags &amp; TICKTIMER_COMPENSATE) { nticks = (now - timer-&gt;tm_last_ticked) / timer-&gt;tm_tick_interval; timer-&gt;tm_last_ticked = now - ((now - timer-&gt;tm_last_ticked) % timer-&gt;tm_tick_interval); for (i = 0; i &lt; nticks; i++) { timer-&gt;tick(timer); timer-&gt;ticks_total++; if (timer-&gt;tick == NULL) { break; } } return nticks; } else { timer-&gt;tm_last_ticked = now; timer-&gt;tick(timer); timer-&gt;ticks_total++; return 1; } } } return 0; } /*! @brief Controls the behaviour of a ticktimer. @param timer Pointer to ticktimer struct. @param flags Flag bitmask. */ inline void ticktimer_ctl (struct ticktimer *timer, unsigned char flags) { timer-&gt;flags = flags; } /*! @brief Allocates a ticktimer struct from an internal statically allocated list. @return Pointer to the newly allocated ticktimer struct or NULL when no more space is available. */ struct ticktimer *ticktimer_alloc (void) { register int i; for (i = 0; i &lt; TIMER_COUNT; i++) { if (timers[i].tick == NULL) { return timers + i; } } return NULL; } /*! @brief Marks a previously allocated ticktimer struct as free. @param timer Pointer to ticktimer struct, usually returned by ticktimer_alloc(). */ inline void ticktimer_free (struct ticktimer *timer) { timer-&gt;tick = NULL; } /*! @brief Checks the status of all allocated timers from the internal list and performs ticks where necessary. @note Should be called in the main loop. */ inline void ticktimer_tick_all (void) { register int i; for (i = 0; i &lt; TIMER_COUNT; i++) { if (timers[i].tick != NULL) { ticktimer_tick(timers + i); } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload