aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmil Williams2026-02-20 05:32:11 +0000
committerEmil Williams2026-02-20 05:32:11 +0000
commit121737a30db4786d9670e2b95d9e4d3e337d75f5 (patch)
treec7cc69e69a88b9163408436e8fa5bb41dd1ef380
parent8035daa04137c5412050a2f30e6748db256a576b (diff)
downloadlibchad-121737a30db4786d9670e2b95d9e4d3e337d75f5.tar.xz
libchad-121737a30db4786d9670e2b95d9e4d3e337d75f5.tar.zst
+ macro.h timespec.h
-rw-r--r--chad/macros.h16
-rw-r--r--chad/timespec.h114
2 files changed, 130 insertions, 0 deletions
diff --git a/chad/macros.h b/chad/macros.h
new file mode 100644
index 0000000..b47ea12
--- /dev/null
+++ b/chad/macros.h
@@ -0,0 +1,16 @@
+#ifndef CHAD_MACROS_H
+#define CHAD_MACROS_H
+/* Usage of this acknoledges your allegiance to GNU. */
+
+#if defined(__GNUC__) || defined(__clang__)
+#define attribute(...) __attribute__((__VA_ARGS__))
+#define always_inline static inline attribute((always_inline))
+#define alias(x) __attribute__((alias(x)))
+#else
+#define attribute(...)
+#define NO_ATTRIBUTE
+#define always_inline static inline
+#define NO_ALWAYS_INLINE
+#define NO_ALIASES
+#endif
+#endif /* CHAD_MACROS_H */
diff --git a/chad/timespec.h b/chad/timespec.h
new file mode 100644
index 0000000..72ac6e2
--- /dev/null
+++ b/chad/timespec.h
@@ -0,0 +1,114 @@
+#ifndef TIMESPEC_H
+#define TIMESPEC_H
+/* ripped partly from glibc */
+#include <time.h>
+#include "macros.h"
+#include "terry.h"
+
+/* -- pontentially over designed and undertested. */
+/* -- consider this "LIKELY TO BE REVISED OR REMOVED!" */
+/* -- ESPECIALLY the generics and the from group */
+
+long TIMESPEC_HZ = 1000000000L;
+
+typedef struct timespec timespec_t;
+
+static const timespec_t one_second = {1, 0}, zero_seconds = {0, 0};
+
+always_inline f64 timespec_to_f64(timespec_t ts)
+{ return (f64) ts.tv_sec + ((f64) ts.tv_nsec / TIMESPEC_HZ); }
+
+always_inline f32 timespec_to_f32(timespec_t ts)
+{ return (f32) ts.tv_sec + ((f32) ts.tv_nsec / TIMESPEC_HZ); }
+
+#if defined(TERRY_SMALL_FLOAT_IMPRECISE) && !defined(NO_ALIASES)
+always_inline double timespec_to_double(timespec_t ts) alias("timespec_to_f64");
+always_inline float timespec_to_float(timespec_t ts) alias("timespec_to_f32");
+#else
+always_inline double timespec_to_double(timespec_t ts)
+{ return (double) ts.tv_sec + ((double) ts.tv_nsec / TIMESPEC_HZ); }
+always_inline float timespec_to_float(timespec_t ts)
+{ return (float) ts.tv_sec + ((float) ts.tv_nsec / TIMESPEC_HZ); }
+#endif
+
+
+#ifdef TERRY_SMALL_FLOAT_IMPRECISE
+#define _from_timespec(ts,to) _Generic((to), double *: double_from_timespec, float *: float_from_timespec)(ts,to)
+#else
+#define _from_timespec(ts,to) _Generic((to), f64 *: f64_from_timespec, f32 *: f32_from_timespec, double *: double_from_timespec, float *: float_from_timespec)(ts,to)
+#endif
+
+always_inline void from_timespec(timespec_t ts, )
+
+always_inline void f64_from_timespec(timespec_t ts, f64 * r)
+{ *r = (f64) ts.tv_sec + ((f64) ts.tv_nsec / TIMESPEC_HZ); }
+
+always_inline void f32_from_timespec(timespec_t ts, f32 * r)
+{ *r = (f32) ts.tv_sec + ((f32) ts.tv_nsec / TIMESPEC_HZ); }
+
+#if defined(TERRY_SMALL_FLOAT_IMPRECISE) && !defined(NO_ALIASES)
+always_inline void double_from_timespec(timespec_t ts, double * r) alias("timespec_to_f64");
+always_inline void float_from_timespec(timespec_t ts, float * r) alias("timespec_to_f32");
+#else
+always_inline void double_from_timespec(timespec_t ts, double * r)
+{ *r = (double) ts.tv_sec + ((double) ts.tv_nsec / TIMESPEC_HZ); }
+always_inline void float_from_timespec(timespec_t ts, float * r)
+{ *r = (float) ts.tv_sec + ((float) ts.tv_nsec / TIMESPEC_HZ); }
+#endif
+
+always_inline timespec_t timespec_add(timespec_t a, timespec_t b) {
+ a.tv_sec += b.tv_sec;
+ a.tv_nsec += b.tv_nsec;
+ if (a.tv_nsec >= TIMESPEC_HZ) {
+ a.tv_sec++;
+ a.tv_nsec -= TIMESPEC_HZ;
+ }
+ return a;
+}
+
+always_inline timespec_t timespec_sub(timespec_t a, timespec_t b) {
+ a.tv_sec -= b.tv_sec;
+ a.tv_nsec -= b.tv_nsec;
+ if (a.tv_nsec < 0) {
+ a.tv_sec--;
+ a.tv_nsec += TIMESPEC_HZ;
+ }
+ return a;
+}
+
+always_inline int timespec_cmp(timespec_t a, timespec_t b) {
+ return a.tv_sec > b.tv_sec ?
+ (1) :
+ a.tv_sec < b.tv_sec ?
+ (-1) :
+ (
+ a.tv_nsec > b.tv_nsec ?
+ (1) :
+ a.tv_nsec < b.tv_nsec ?
+ (-1) : 0
+ );
+}
+
+always_inline timespec_t timespec_max(timespec_t a, timespec_t b) {
+ return a.tv_sec > b.tv_sec ?
+ a :
+ a.tv_sec < b.tv_sec ?
+ b :
+ (
+ a.tv_nsec > b.tv_nsec ?
+ a : b
+ );
+}
+
+always_inline timespec_t timespec_min(timespec_t a, timespec_t b) {
+ return a.tv_sec < b.tv_sec ?
+ a :
+ a.tv_sec > b.tv_sec ?
+ b :
+ (
+ a.tv_nsec < b.tv_nsec ?
+ a : b
+ );
+}
+
+#endif /* TIMESPEC_H */