1 /**
2  * Framework code for benchmarking individual functions.
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <vladimir@thecybershadow.net>
12  */
13 
14 module ae.sys.benchmark;
15 
16 import win32.windows;
17 import std.exception;
18 import core.memory;
19 
20 ulong rdtsc() { asm { rdtsc; } }
21 
22 private ulong benchStartTime;
23 
24 void benchStart()
25 {
26 	GC.collect();
27 	version(DOS) asm { cli; }
28 	benchStartTime = rdtsc();
29 }
30 
31 ulong benchEnd()
32 {
33 	auto time = rdtsc() - benchStartTime;
34 	version(DOS) asm { sti; }
35 	return time;
36 }
37 
38 static this()
39 {
40 	try
41 	{
42 		version(DOS)
43 		{}
44 		else
45 		{
46 			HANDLE proc = GetCurrentProcess();
47 			HANDLE thr  = GetCurrentThread();
48 
49 			HANDLE tok;
50 			enforce(OpenProcessToken(proc, TOKEN_ADJUST_PRIVILEGES, &tok), "OpenProcessToken");
51 
52 			LUID luid;
53 			enforce(LookupPrivilegeValue(null,
54 				"SeIncreaseBasePriorityPrivilege",
55 				&luid), "LookupPrivilegeValue");
56 
57 			TOKEN_PRIVILEGES tp;
58 			tp.PrivilegeCount = 1;
59 			tp.Privileges[0].Luid = luid;
60 			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
61 
62 			AdjustTokenPrivileges(tok, FALSE, &tp, tp.sizeof, null, null);
63 			enforce(GetLastError() == ERROR_SUCCESS, "AdjustTokenPrivileges");
64 
65 			enforce(SetPriorityClass(proc, REALTIME_PRIORITY_CLASS), "SetPriorityClass");
66 		//	enforce(SetPriorityClass(proc, HIGH_PRIORITY_CLASS), "SetPriorityClass");
67 			enforce(SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL), "SetThreadPriority");
68 
69 			enforce(SetProcessAffinityMask(proc, 1), "SetProcessAffinityMask");
70 		}
71 	}
72 	catch (Exception e)
73 	{
74 		import std.stdio;
75 		writeln("Benchmark initialization error: ", e.msg);
76 	}
77 
78 	GC.disable();
79 }