1
0
mirror of https://github.com/deadw00d/AROS.git synced 2025-12-09 16:00:35 +00:00
Files
AROS-v0/rom/timer/timer_macros.h
deadwood 51a9380a7e Reimplement CMPTIME to use unsigned comparison
Using local LONG variable had a side effect of interpreting large unsigned
results as signed, reporting wrong value out, as documented in this bug:

https://github.com/deadwood2/AROS/issues/157
2024-10-30 14:42:18 +01:00

83 lines
2.2 KiB
C

/*
* These are often used by timer.device itself, and inlining
* them saves us from function call overhead.
*/
/* Add, then normalize */
#define ADDTIME(dest, src) \
(dest)->tv_micro += (src)->tv_micro; \
(dest)->tv_secs += (src)->tv_secs; \
while((dest)->tv_micro > 999999) \
{ \
(dest)->tv_secs++; \
(dest)->tv_micro -= 1000000; \
}
/*
* Subtraction algorithm:
* 1. Normalize values
* 2. Check if wrap around will happen, when subtracting src->tv_micro
* from dest->tv_micro. If yes, then normalize, by adding 1 sec to
* micros and subtracting 1 sec from secs. Note: this check must be
* before subtracting src timeval from dest timeval!
*/
#define SUBTIME(dest, src) \
while ((src)->tv_micro > 999999) \
{ \
(src)->tv_secs++; \
(src)->tv_micro -= 1000000; \
} \
while ((dest)->tv_micro > 999999) \
{ \
(dest)->tv_secs++; \
(dest)->tv_micro -= 1000000; \
} \
if ((dest)->tv_micro < (src)->tv_micro) \
{ \
(dest)->tv_micro += 1000000; \
(dest)->tv_secs--; \
} \
(dest)->tv_micro -= (src)->tv_micro; \
(dest)->tv_secs -= (src)->tv_secs;
static inline LONG CMPTIME(struct timeval *dest, struct timeval *src)
{
if (dest->tv_secs > src->tv_secs)
return -1;
else if (dest->tv_secs < src->tv_secs)
return 1;
else
{
if (dest->tv_micro > src->tv_micro)
return -1;
else if (dest->tv_micro < src->tv_micro)
return 1;
}
return 0;
}
static inline LONG CMPTIME3232(struct timeval32 *dest, struct timeval32 *src)
{
return CMPTIME((struct timeval *)dest, (struct timeval *)src);
}
static inline LONG CMPTIMEXX32(struct timeval *dest, struct timeval32 *src)
{
return CMPTIME(dest, (struct timeval *)src);
}
/*
* Add 'diff' EClock ticks to timeval in 'time'.
* Fraction of second value is stored in in 'frac'.
* This macro relies on (CPU-specific) tick2usec() implementation
*/
#define INCTIME(time, frac, diff) \
(frac) += diff; \
if ((frac) >= TimerBase->tb_eclock_rate) \
{ \
(frac) -= TimerBase->tb_eclock_rate; \
(time).tv_secs++; \
} \
(time).tv_micro = tick2usec(frac);