Foundations

This commit is contained in:
2026-08-29 01:50:50 +08:00
parent bf5fc3bda6
commit 8e95904cc4
100 changed files with 13997 additions and 0 deletions
+258
View File
@@ -0,0 +1,258 @@
#ifndef INCLUDED_C_TIMESPEC_H
#define INCLUDED_C_TIMESPEC_H
#ifndef INCLUDED_C_TYPES_H
#include <c_Types.h>
#endif /*INCLUDED_C_TYPES_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#define C_NSEC_PER_USEC 1000L
#define C_USEC_PER_MSEC 1000L
#define C_MSEC_PER_SEC 1000L
#define C_NSEC_PER_MSEC 1000000L
#define C_USEC_PER_SEC 1000000L
#define C_NSEC_PER_SEC 1000000000L
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
struct timespec c_timespec_normalise(struct timespec ts)
{
while(ts.tv_nsec >= C_NSEC_PER_SEC)
{
++(ts.tv_sec);
ts.tv_nsec -= C_NSEC_PER_SEC;
}
while(ts.tv_nsec <= -C_NSEC_PER_SEC)
{
--(ts.tv_sec);
ts.tv_nsec += C_NSEC_PER_SEC;
}
if(ts.tv_nsec < 0)
{
/* Negative nanoseconds isn't valid according to POSIX.
* Decrement tv_sec and roll tv_nsec over.
*/
--(ts.tv_sec);
ts.tv_nsec = (C_NSEC_PER_SEC + ts.tv_nsec);
}
return ts;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
struct timespec c_timespec_add(struct timespec ts1, struct timespec ts2)
{
/* Normalise inputs to prevent tv_nsec rollover if whole-second values
* are packed in it.
*/
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
ts1.tv_sec += ts2.tv_sec;
ts1.tv_nsec += ts2.tv_nsec;
return c_timespec_normalise(ts1);
}
C_STATIC_FORCE_INLINE
struct timespec c_timespec_sub(struct timespec ts1, struct timespec ts2)
{
/* Normalise inputs to prevent tv_nsec rollover if whole-second values
* are packed in it.
*/
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
ts1.tv_sec -= ts2.tv_sec;
ts1.tv_nsec -= ts2.tv_nsec;
return c_timespec_normalise(ts1);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
int c_timespec_cmp(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
if(ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec == ts2.tv_nsec)
{
return 0;
}
else if((ts1.tv_sec > ts2.tv_sec)
|| (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec > ts2.tv_nsec))
{
return 1;
}
else {
return -1;
}
}
C_STATIC_FORCE_INLINE
bool c_timespec_eq(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
return (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec == ts2.tv_nsec);
}
C_STATIC_FORCE_INLINE
bool c_timespec_gt(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
return (ts1.tv_sec > ts2.tv_sec || (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec > ts2.tv_nsec));
}
C_STATIC_FORCE_INLINE
bool c_timespec_ge(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
return (ts1.tv_sec > ts2.tv_sec || (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec >= ts2.tv_nsec));
}
C_STATIC_FORCE_INLINE
bool c_timespec_lt(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
return (ts1.tv_sec < ts2.tv_sec || (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec < ts2.tv_nsec));
}
C_STATIC_FORCE_INLINE
bool c_timespec_le(struct timespec ts1, struct timespec ts2)
{
ts1 = c_timespec_normalise(ts1);
ts2 = c_timespec_normalise(ts2);
return (ts1.tv_sec < ts2.tv_sec || (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec <= ts2.tv_nsec));
}
C_STATIC_FORCE_INLINE
struct timespec c_timespec_min(struct timespec ts1, struct timespec ts2) {
if(c_timespec_le(ts1, ts2)) {
return ts1;
} else {
return ts2;
}
}
C_STATIC_FORCE_INLINE
struct timespec c_timespec_max(struct timespec ts1, struct timespec ts2) {
if(c_timespec_ge(ts1, ts2)) {
return ts1;
} else {
return ts2;
}
}
C_STATIC_FORCE_INLINE
struct timespec c_timespec_clamp(struct timespec ts, struct timespec min, struct timespec max) {
if(c_timespec_gt(ts, max)) {
return max;
}
if(c_timespec_lt(ts, min)) {
return min;
}
return ts;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
struct timespec c_timespec_from_double(double s)
{
struct timespec ts = {
.tv_sec = s,
.tv_nsec = (s - (long)(s)) * C_NSEC_PER_SEC,
};
return c_timespec_normalise(ts);
}
C_STATIC_FORCE_INLINE
double c_timespec_to_double(struct timespec ts)
{
return ((double)(ts.tv_sec) + ((double)(ts.tv_nsec) / C_NSEC_PER_SEC));
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
struct timespec c_timespec_from_timeval(struct timeval tv)
{
struct timespec ts = {
.tv_sec = tv.tv_sec,
.tv_nsec = tv.tv_usec * C_NSEC_PER_USEC
};
return c_timespec_normalise(ts);
}
C_STATIC_FORCE_INLINE
struct timeval c_timespec_to_timeval(struct timespec ts)
{
ts = c_timespec_normalise(ts);
struct timeval tv = {
.tv_sec = ts.tv_sec,
.tv_usec = ts.tv_nsec / C_NSEC_PER_USEC,
};
return tv;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
struct timespec c_timespec_from_ms(long milliseconds)
{
struct timespec ts = {
.tv_sec = (milliseconds / C_MSEC_PER_SEC),
.tv_nsec = (milliseconds % C_MSEC_PER_SEC) * C_NSEC_PER_MSEC,
};
return c_timespec_normalise(ts);
}
C_STATIC_FORCE_INLINE
long c_timespec_to_ms(struct timespec ts)
{
return (ts.tv_sec * C_MSEC_PER_SEC) + (ts.tv_nsec / C_NSEC_PER_MSEC);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
struct timespec c_timespec_mod(struct timespec ts1, struct timespec ts2);
#endif /*INCLUDED_C_TIMESPEC_H*/