Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/local_includes/clock.h')
-rw-r--r--winsup/cygwin/local_includes/clock.h177
1 files changed, 177 insertions, 0 deletions
diff --git a/winsup/cygwin/local_includes/clock.h b/winsup/cygwin/local_includes/clock.h
new file mode 100644
index 000000000..7323299df
--- /dev/null
+++ b/winsup/cygwin/local_includes/clock.h
@@ -0,0 +1,177 @@
+/* clock.h: Definitions for clock calculations
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+#include <mmsystem.h>
+
+/* Must be a power of 2. */
+#define MAX_CLOCKS (16)
+
+/* Conversions for per-process and per-thread clocks */
+#define CLOCKID(cid) \
+ ((cid) % MAX_CLOCKS)
+#define PID_TO_CLOCKID(pid) \
+ ((pid) * MAX_CLOCKS + CLOCK_PROCESS_CPUTIME_ID)
+#define CLOCKID_TO_PID(cid) \
+ (((cid) - CLOCK_PROCESS_CPUTIME_ID) / MAX_CLOCKS)
+#define CLOCKID_IS_PROCESS(cid) \
+ (CLOCKID(cid) == CLOCK_PROCESS_CPUTIME_ID)
+#define THREADID_TO_CLOCKID(tid) \
+ ((tid) * MAX_CLOCKS + CLOCK_THREAD_CPUTIME_ID)
+#define CLOCKID_TO_THREADID(cid) \
+ (((cid) - CLOCK_THREAD_CPUTIME_ID) / MAX_CLOCKS)
+#define CLOCKID_IS_THREAD(cid) \
+ (CLOCKID(cid) == CLOCK_THREAD_CPUTIME_ID)
+
+/* Largest delay in ms for sleep and alarm calls.
+ Allow actual delay to exceed requested delay by 10 s.
+ Express as multiple of 1000 (i.e. seconds) + max resolution
+ The tv_sec argument in timeval structures cannot exceed
+ CLOCK_DELAY_MAX / 1000 - 1, so that adding fractional part
+ and rounding won't exceed CLOCK_DELAY_MAX */
+#define CLOCK_DELAY_MAX ((((UINT_MAX - 10000) / 1000) * 1000) + 10)
+
+/* 100ns difference between Windows and UNIX timebase. */
+#define FACTOR (0x19db1ded53e8000LL)
+/* # of nanosecs per second. */
+#define NSPERSEC (1000000000LL)
+/* # of 100ns intervals per second. */
+#define NS100PERSEC (10000000LL)
+/* # of microsecs per second. */
+#define USPERSEC (1000000LL)
+/* # of millisecs per second. */
+#define MSPERSEC (1000L)
+
+class clk_t
+{
+ protected:
+ /* Some values are returned as ticks/s, some as 100ns period of a
+ single tick. Store the original value and use a computation method
+ making the most sense for the value given, to avoid rounding issues. */
+ union
+ {
+ LONGLONG ticks_per_sec;
+ LONGLONG period;
+ };
+ void init ();
+ virtual int now (clockid_t, struct timespec *) = 0;
+
+ public:
+ int nsecs (clockid_t _id, struct timespec *ts)
+ {
+ return now (_id, ts);
+ }
+ virtual void resolution (struct timespec *);
+
+ /* shortcuts for non-process/thread clocks */
+ void nsecs (struct timespec *ts)
+ {
+ now (0, ts);
+ }
+ ULONGLONG nsecs ()
+ {
+ struct timespec ts;
+ now (0, &ts);
+ return (ULONGLONG) ts.tv_sec * NSPERSEC + ts.tv_nsec;
+ }
+ LONGLONG n100secs ()
+ {
+ struct timespec ts;
+ now (0, &ts);
+ return ts.tv_sec * NS100PERSEC + ts.tv_nsec / (NSPERSEC/NS100PERSEC);
+ }
+ LONGLONG usecs ()
+ {
+ struct timespec ts;
+ now (0, &ts);
+ return ts.tv_sec * USPERSEC + ts.tv_nsec / (NSPERSEC/USPERSEC);
+ }
+ LONGLONG msecs ()
+ {
+ struct timespec ts;
+ now (0, &ts);
+ return ts.tv_sec * MSPERSEC + ts.tv_nsec / (NSPERSEC/MSPERSEC);
+ }
+};
+
+class clk_realtime_coarse_t : public clk_t
+{
+ virtual int now (clockid_t, struct timespec *);
+};
+
+class clk_realtime_t : public clk_t
+{
+ void init ();
+ virtual int now (clockid_t, struct timespec *);
+ public:
+ virtual void resolution (struct timespec *);
+};
+
+class clk_process_t : public clk_t
+{
+ virtual int now (clockid_t, struct timespec *);
+};
+
+class clk_thread_t : public clk_t
+{
+ virtual int now (clockid_t, struct timespec *);
+};
+
+class clk_monotonic_t : public clk_t
+{
+ protected:
+ void init ();
+ private:
+ virtual int now (clockid_t, struct timespec *);
+ public:
+ virtual void resolution (struct timespec *);
+ /* Under strace 1st call is so early that vtable is NULL. */
+ LONGLONG strace_usecs ()
+ {
+ struct timespec ts;
+ clk_monotonic_t::now (0, &ts);
+ return ts.tv_sec * USPERSEC + ts.tv_nsec / (NSPERSEC/USPERSEC);
+ }
+};
+
+class clk_monotonic_coarse_t : public clk_t
+{
+ virtual int now (clockid_t, struct timespec *);
+};
+
+class clk_boottime_t : public clk_monotonic_t
+{
+ virtual int now (clockid_t, struct timespec *);
+};
+
+clk_t *get_clock (clockid_t clk_id);
+
+/* Compute interval between two timespec timestamps: ts1 = ts1 - ts0. */
+static inline void
+ts_diff (const struct timespec &ts0, struct timespec &ts1)
+{
+ ts1.tv_nsec -= ts0.tv_nsec;
+ if (ts1.tv_nsec < 0)
+ {
+ ts1.tv_nsec += NSPERSEC;
+ --ts1.tv_sec;
+ }
+ ts1.tv_sec -= ts0.tv_sec;
+}
+
+static inline bool
+valid_timespec (const timespec& ts)
+{
+ if (ts.tv_nsec < 0 || ts.tv_nsec >= NSPERSEC || ts.tv_sec < 0)
+ return false;
+ return true;
+}
+
+#endif /*__CLOCK_H__*/