cosmetix
[iv.d.git] / pxclock.d
bloba7c5204600f0a26a325207550d4a0d5c93605127
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv.pxclock /*is aliced*/;
19 private:
20 import iv.alice;
23 // ////////////////////////////////////////////////////////////////////////// //
24 version(Posix) {
25 import core.sys.posix.time;
27 enum ClockType = CLOCK_REALTIME;
28 //enum ClockType = CLOCK_MONOTONIC;
30 __gshared timespec stt;
32 shared static this () {
33 if (clock_getres(ClockType, &stt) != 0) assert(0, "cannot get clock resolution");
34 if (stt.tv_sec != 0 || stt.tv_nsec > 1_000_000) assert(0, "clock resolution too big"); // at least millisecond
35 if (clock_gettime(ClockType, &stt) != 0) assert(0, "cannot get clock starting time");
39 ///
40 public ulong clockMicro () nothrow @trusted @nogc {
41 timespec ts;
42 if (clock_gettime(ClockType, &ts) != 0) assert(0, "cannot get clock time");
43 // ignore nanoseconds in stt here: we need only 'differential' time, and it can start with something weird
44 return (cast(ulong)(ts.tv_sec-stt.tv_sec))*1000000+ts.tv_nsec/1000;
48 ///
49 public ulong clockMilli () nothrow @trusted @nogc {
50 timespec ts;
51 if (clock_gettime(ClockType, &ts) != 0) assert(0, "cannot get clock time");
52 // ignore nanoseconds in stt here: we need only 'differential' time, and it can start with something weird
53 return (cast(ulong)(ts.tv_sec-stt.tv_sec))*1000+ts.tv_nsec/1000000;
57 extern(C) int clock_nanosleep (clockid_t clock_id, int flags, const(timespec)* request, const(timespec)* remain) nothrow @trusted @nogc;
59 void clockDoSleep (ref timespec rq) nothrow @trusted @nogc {
60 timespec rem;
61 for (;;) {
62 if (rq.tv_sec == 0 && rq.tv_nsec == 0) break;
63 import core.stdc.errno;
64 auto err = clock_nanosleep(ClockType, 0, &rq, &rem);
65 if (err == 0) break;
66 if (err != EINTR) assert(0, "sleeping error");
67 // continue sleeping
68 rq = rem;
73 ///
74 public void clockSleepMicro (uint microsecs) nothrow @trusted @nogc {
75 if (microsecs == 0) return;
76 timespec rq;
77 rq.tv_sec = cast(uint)microsecs/1000000;
78 rq.tv_nsec = cast(ulong)(microsecs%1000000)*1000;
79 clockDoSleep(rq);
83 ///
84 public void clockSleepMilli (uint millisecs) nothrow @trusted @nogc {
85 if (millisecs == 0) return;
86 timespec rq;
87 rq.tv_sec = cast(uint)millisecs/1000;
88 rq.tv_nsec = cast(ulong)(millisecs%1000)*1000000;
89 clockDoSleep(rq);
92 } else {
93 pragma(msg, "please, use real OS");
95 import core.sys.windows.winbase : GetTickCount, Sleep, QueryPerformanceCounter, QueryPerformanceFrequency;
97 __gshared long pcfreq;
99 shared static this () { QueryPerformanceFrequency(&pcfreq); }
101 public ulong clockMicro () nothrow @trusted @nogc {
102 long c;
103 if (!QueryPerformanceCounter(&c)) return cast(ulong)GetTickCount*1000;
104 return c*1000*1000/pcfreq;
106 public ulong clockMilli () nothrow @trusted @nogc {
107 long c;
108 if (!QueryPerformanceCounter(&c)) return cast(ulong)GetTickCount*1000;
109 return c*1000/pcfreq;
111 public void clockSleepMicro (uint microsecs) nothrow @trusted @nogc {
112 auto start = clockMicro();
113 while (clockMicro-start < microsecs) {}
115 public void clockSleepMilli (uint millisecs) nothrow @trusted @nogc {
116 if (millisecs >= 50) { Sleep(millisecs); return; }
117 auto start = clockMilli();
118 while (clockMilli-start < millisecs) {}