00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 module mango.base.System;
00043
00044 private import std.c.time;
00045
00046 private import std.thread;
00047
00048
00049
00050
00051
00052
00053
00054 version (Win32)
00055 {
00056 private import std.c.windows.windows;
00057
00058 static uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
00059 static uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
00060 static uint FORMAT_MESSAGE_FROM_STRING = 0x00000400;
00061 static uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
00062 static uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
00063 static uint FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
00064 static uint FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
00065
00066 WORD MAKELANGID(WORD p, WORD s) { return (((cast(WORD)s) << 10) | cast(WORD)p); }
00067 WORD PRIMARYLANGID(WORD lgid) { return (cast(WORD)lgid & 0x3ff); }
00068 WORD SUBLANGID(WORD lgid) { return (cast(WORD)lgid >> 10); }
00069
00070 alias HGLOBAL HLOCAL;
00071
00072 static uint LANG_NEUTRAL = 0x00;
00073 static uint SUBLANG_DEFAULT = 0x01;
00074
00075 extern (Windows)
00076 {
00077 DWORD FormatMessageA (DWORD dwFlags,
00078 LPCVOID lpSource,
00079 DWORD dwMessageId,
00080 DWORD dwLanguageId,
00081 LPTSTR lpBuffer,
00082 DWORD nSize,
00083 LPCVOID args
00084 );
00085
00086 HLOCAL LocalFree(HLOCAL hMem);
00087 int QueryPerformanceCounter (ulong *count);
00088 int QueryPerformanceFrequency (ulong *frequency);
00089
00090 VOID Sleep (DWORD millisecs);
00091 }
00092 }
00093
00094 version (Posix)
00095 {
00096 version (linux)
00097 private import std.c.linux.linux;
00098
00099 else version (darwin)
00100 private import std.c.darwin.darwin;
00101
00102 else static assert (0);
00103
00104 extern (C) char *strerror (int);
00105 extern (C) int strlen (char *);
00106 extern (C) int getErrno ();
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 static this()
00116 {
00117 version(Win32){}
00118 else
00119 version (Posix){}
00120 else
00121 throw new Exception ("Unsupported O/S environment (version is not Win32 or Posix).");
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 struct System
00134 {
00135 private static uint frequency;
00136 private static ulong beginTime;
00137 private static ulong beginCounter;
00138
00139
00140
00141
00142
00143
00144
00145
00146 enum Interval {
00147 Microsec = 1,
00148 Millisec = 1000,
00149 Second = 1_000_000,
00150 Minute = 60_000_000
00151 };
00152
00153
00154
00155
00156
00157
00158
00159
00160 static this ()
00161 {
00162 version (Posix)
00163 {
00164 timeval tv;
00165
00166 if (gettimeofday (&tv, null))
00167 throw new Exception ("high-resolution timer is not available");
00168
00169 beginTime = tv.tv_sec * 1000;
00170 }
00171
00172 version (Win32)
00173 {
00174 SYSTEMTIME sTime;
00175 FILETIME fTime;
00176
00177 GetSystemTime (&sTime);
00178 SystemTimeToFileTime (&sTime, &fTime);
00179
00180 ulong time1 = (cast(long) fTime.dwHighDateTime) << 32 |
00181 fTime.dwLowDateTime;
00182
00183
00184 sTime.wYear = 1969;
00185 sTime.wMonth = 12;
00186 sTime.wDayOfWeek = 3;
00187 sTime.wDay = 31;
00188 sTime.wHour = 23;
00189 sTime.wMinute = 0;
00190 sTime.wSecond = 0;
00191 sTime.wMilliseconds = 0;
00192 SystemTimeToFileTime (&sTime, &fTime);
00193
00194 ulong time2 = (cast(long) fTime.dwHighDateTime) << 32 |
00195 fTime.dwLowDateTime;
00196
00197 beginTime = (time1 - time2) / 10_000;
00198
00199
00200 ulong time;
00201 ulong freq;
00202
00203 if (! QueryPerformanceFrequency (&freq))
00204 throw new Exception ("high-resolution timer is not available");
00205
00206 frequency = freq / 1000;
00207 QueryPerformanceCounter (&time);
00208 beginCounter = time / frequency;
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 final static ulong getMillisecs ()
00219 {
00220 version (Posix)
00221 {
00222 timeval tv;
00223
00224 gettimeofday (&tv, null);
00225 return ((cast(ulong) tv.tv_sec) * 1000 + tv.tv_usec / 1000);
00226 }
00227
00228 version (Win32)
00229 {
00230 ulong time;
00231
00232 QueryPerformanceCounter (&time);
00233 return ((time / frequency) - beginCounter) + beginTime;
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242
00243 final static ulong getBeginTime ()
00244 {
00245 return beginTime;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 final static void sleep (uint interval = uint.max)
00257 {
00258 do {
00259 version (Posix)
00260 usleep (interval);
00261
00262 version (Win32)
00263 Sleep (interval / 1000);
00264 } while (interval == uint.max);
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 final static Thread createThread (int delegate() dg, bool start = false)
00275 {
00276 Thread t = new Thread (dg);
00277 if (start)
00278 t.start ();
00279 return t;
00280 }
00281
00282
00283
00284
00285
00286 final static char[] error ()
00287 {
00288 version (Win32)
00289 return error (GetLastError);
00290 else
00291 return error (getErrno);
00292 }
00293
00294
00295
00296
00297
00298 final static char[] error (uint errcode)
00299 {
00300 char[] text;
00301
00302 version (Win32)
00303 {
00304 DWORD r;
00305 LPVOID lpMsgBuf;
00306
00307 r = FormatMessageA (
00308 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00309 FORMAT_MESSAGE_FROM_SYSTEM |
00310 FORMAT_MESSAGE_IGNORE_INSERTS,
00311 null,
00312 errcode,
00313 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00314 cast(LPTSTR)&lpMsgBuf,
00315 0,
00316 null);
00317
00318
00319 if (r >= 2) r-= 2;
00320 text = (cast(char *)lpMsgBuf)[0..r].dup;
00321 LocalFree(cast(HLOCAL)lpMsgBuf);
00322 }
00323 else
00324 {
00325 uint r;
00326 char* pemsg;
00327
00328 pemsg = strerror(errcode);
00329 r = strlen(pemsg);
00330
00331
00332 if (pemsg[r-1] == '\n') r--;
00333 if (pemsg[r-1] == '\r') r--;
00334 text = pemsg[0..r].dup;
00335 }
00336
00337 return text;
00338 }
00339 }
00340