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