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 <ae@cy.md>
12  */
13 
14 module ae.sys.benchmark;
15 version(Windows):
16 
17 import std.exception;
18 import core.memory;
19 
20 import ae.sys.windows.imports;
21 mixin(importWin32!q{windows});
22 
23 ulong rdtsc() { asm { rdtsc; } } /// Returns the result of the RDTSC instruction.
24 
25 private ulong benchStartTime;
26 
27 /// Begin benchmarking.
28 void benchStart()
29 {
30 	GC.collect();
31 	version(DOS) asm { cli; }
32 	benchStartTime = rdtsc();
33 }
34 
35 /// Finish benchmarking, and return the elapsed ticks.
36 ulong benchEnd()
37 {
38 	auto time = rdtsc() - benchStartTime;
39 	version(DOS) asm { sti; }
40 	return time;
41 }
42 
43 static this()
44 {
45 	try
46 	{
47 		version(DOS)
48 		{}
49 		else
50 		{
51 			HANDLE proc = GetCurrentProcess();
52 			HANDLE thr  = GetCurrentThread();
53 
54 			HANDLE tok;
55 			enforce(OpenProcessToken(proc, TOKEN_ADJUST_PRIVILEGES, &tok), "OpenProcessToken");
56 
57 			LUID luid;
58 			enforce(LookupPrivilegeValue(null,
59 				"SeIncreaseBasePriorityPrivilege",
60 				&luid), "LookupPrivilegeValue");
61 
62 			TOKEN_PRIVILEGES tp;
63 			tp.PrivilegeCount = 1;
64 			tp.Privileges[0].Luid = luid;
65 			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
66 
67 			AdjustTokenPrivileges(tok, FALSE, &tp, tp.sizeof, null, null);
68 			enforce(GetLastError() == ERROR_SUCCESS, "AdjustTokenPrivileges");
69 
70 			enforce(SetPriorityClass(proc, REALTIME_PRIORITY_CLASS), "SetPriorityClass");
71 		//	enforce(SetPriorityClass(proc, HIGH_PRIORITY_CLASS), "SetPriorityClass");
72 			enforce(SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL), "SetThreadPriority");
73 
74 			enforce(SetProcessAffinityMask(proc, 1), "SetProcessAffinityMask");
75 		}
76 	}
77 	catch (Exception e)
78 	{
79 		import std.stdio;
80 		writeln("Benchmark initialization error: ", e.msg);
81 	}
82 
83 	GC.disable();
84 }