some updates
[iv.d.git] / pxclock.d
blob527de4ed12093e469df0c52b6f0557f9480f2717
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, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module iv.pxclock /*is aliced*/;
18 private:
19 import iv.alice;
22 // ////////////////////////////////////////////////////////////////////////// //
23 version(Posix) {
24 import core.sys.posix.time;
26 enum ClockType = CLOCK_REALTIME;
27 //enum ClockType = CLOCK_MONOTONIC;
29 __gshared timespec stt;
31 shared static this () {
32 if (clock_getres(ClockType, &stt) != 0) assert(0, "cannot get clock resolution");
33 if (stt.tv_sec != 0 || stt.tv_nsec > 1_000_000) assert(0, "clock resolution too big"); // at least millisecond
34 if (clock_gettime(ClockType, &stt) != 0) assert(0, "cannot get clock starting time");
38 ///
39 public ulong clockMicro () nothrow @trusted @nogc {
40 timespec ts;
41 if (clock_gettime(ClockType, &ts) != 0) assert(0, "cannot get clock time");
42 // ignore nanoseconds in stt here: we need only 'differential' time, and it can start with something weird
43 return (cast(ulong)(ts.tv_sec-stt.tv_sec))*1000000+ts.tv_nsec/1000;
47 ///
48 public ulong clockMilli () nothrow @trusted @nogc {
49 timespec ts;
50 if (clock_gettime(ClockType, &ts) != 0) assert(0, "cannot get clock time");
51 // ignore nanoseconds in stt here: we need only 'differential' time, and it can start with something weird
52 return (cast(ulong)(ts.tv_sec-stt.tv_sec))*1000+ts.tv_nsec/1000000;
56 extern(C) int clock_nanosleep (clockid_t clock_id, int flags, const(timespec)* request, const(timespec)* remain) nothrow @trusted @nogc;
58 void clockDoSleep (ref timespec rq) nothrow @trusted @nogc {
59 timespec rem;
60 for (;;) {
61 if (rq.tv_sec == 0 && rq.tv_nsec == 0) break;
62 import core.stdc.errno;
63 auto err = clock_nanosleep(ClockType, 0, &rq, &rem);
64 if (err == 0) break;
65 if (err != EINTR) assert(0, "sleeping error");
66 // continue sleeping
67 rq = rem;
72 ///
73 public void clockSleepMicro (uint microsecs) nothrow @trusted @nogc {
74 if (microsecs == 0) return;
75 timespec rq;
76 rq.tv_sec = cast(uint)microsecs/1000000;
77 rq.tv_nsec = cast(ulong)(microsecs%1000000)*1000;
78 clockDoSleep(rq);
82 ///
83 public void clockSleepMilli (uint millisecs) nothrow @trusted @nogc {
84 if (millisecs == 0) return;
85 timespec rq;
86 rq.tv_sec = cast(uint)millisecs/1000;
87 rq.tv_nsec = cast(ulong)(millisecs%1000)*1000000;
88 clockDoSleep(rq);
91 } else {
92 pragma(msg, "please, use real OS");
94 import core.sys.windows.winbase : GetTickCount, Sleep, QueryPerformanceCounter, QueryPerformanceFrequency;
96 __gshared long pcfreq;
98 shared static this () { QueryPerformanceFrequency(&pcfreq); }
100 public ulong clockMicro () nothrow @trusted @nogc {
101 long c;
102 if (!QueryPerformanceCounter(&c)) return cast(ulong)GetTickCount*1000;
103 return c*1000*1000/pcfreq;
105 public ulong clockMilli () nothrow @trusted @nogc {
106 long c;
107 if (!QueryPerformanceCounter(&c)) return cast(ulong)GetTickCount*1000;
108 return c*1000/pcfreq;
110 public void clockSleepMicro (uint microsecs) nothrow @trusted @nogc {
111 auto start = clockMicro();
112 while (clockMicro-start < microsecs) {}
114 public void clockSleepMilli (uint millisecs) nothrow @trusted @nogc {
115 if (millisecs >= 50) { Sleep(millisecs); return; }
116 auto start = clockMilli();
117 while (clockMilli-start < millisecs) {}