<commit_before>#include <iostream>
#include <iomanip>
#include <string>
#include <memory>

#include <windows.h>
#include <psapi.h> //GetModuleFileNameEx
#include <TlHelp32.h>

// Setting DLL access controls
#include <AccCtrl.h>
#include <Aclapi.h>
#include <Sddl.h>

// UWP
#include <atlbase.h>
#include <appmodel.h>

#include "MinConsole.hpp"

namespace Console = MinConsole;

const wchar_t* DLLFile = L"UWPDumper.dll";

void SetAccessControl(
	const std::wstring &ExecutableName,
	const wchar_t *AccessString
);

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring &DLLpath);

std::wstring GetRunningDirectory();

int main()
{
	SetConsoleOutputCP(437);

	Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
	std::wcout << "UWPInjector Build date (" << __DATE__ << " : " << __TIME__ << ")" << std::endl;
	Console::SetTextColor(Console::Color::Input);
	std::wcout << "\t-https://github.com/Wunkolo/UWPDumper\n";
	Console::SetTextColor(Console::Color::Magenta);
	std::wcout << std::wstring(Console::GetWidth() - 1, '-') << std::endl;
	Console::SetTextColor(Console::Color::Info);

	uint32_t ProcessID = 0;

	std::cout << "Currently running UWP Apps:" << std::endl;
	void* ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 ProcessEntry;
	ProcessEntry.dwSize = sizeof(PROCESSENTRY32);

	if( Process32First(ProcessSnapshot, &ProcessEntry) )
	{
		while( Process32Next(ProcessSnapshot, &ProcessEntry) )
		{
			void* ProcessHandle = OpenProcess(
				PROCESS_QUERY_LIMITED_INFORMATION,
				false,
				ProcessEntry.th32ProcessID
			);
			if( ProcessHandle )
			{
				uint32_t NameLength = 0;
				int32_t ProcessCode = GetPackageFamilyName(
					ProcessHandle,
					&NameLength,
					nullptr
				);
				if( NameLength )
				{
					Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
					std::wcout
						<< std::setw(12)
						<< ProcessEntry.th32ProcessID;

					Console::SetTextColor(Console::Color::Info);
					std::wcout
						<< " | "
						<< ProcessEntry.szExeFile << " :\n\t\t-";
					std::unique_ptr<wchar_t[]> PackageName(new wchar_t[NameLength]());

					ProcessCode = GetPackageFamilyName(
						ProcessHandle,
						&NameLength,
						PackageName.get()
					);

					if( ProcessCode != ERROR_SUCCESS )
					{
						std::wcout << "GetPackageFamilyName Error: " << ProcessCode;
					}

					std::wcout << PackageName.get() << std::endl;

					PackageName.reset();
				}
			}
			CloseHandle(ProcessHandle);
		}
	}
	else
	{
		// Error iterating processes
	}
	std::cout << "Enter ProcessID: ";
	Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
	std::cin >> ProcessID;
	Console::SetTextColor(Console::Color::Info);

	SetAccessControl(GetRunningDirectory() + L"\\" + DLLFile, L"S-1-15-2-1");

	if( DLLInjectRemote(ProcessID, GetRunningDirectory() + L"\\" + DLLFile) )
	{
		Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
		std::cout << "Success!" << std::endl;
	}
	else
	{
		Console::SetTextColor(Console::Color::Red | Console::Color::Bright);
		std::cout << "Failed" << std::endl;
		system("pause");
	}

	return 0;
}

void SetAccessControl(const std::wstring &ExecutableName, const wchar_t* AccessString)
{
	PSECURITY_DESCRIPTOR SecurityDescriptor = nullptr;
	EXPLICIT_ACCESSW ExplicitAccess = { 0 };

	ACL *AccessControlCurrent = nullptr;
	ACL *AccessControlNew = nullptr;

	SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION;
	PSID SecurityIdentifier = nullptr;

	if( GetNamedSecurityInfoW(
		ExecutableName.c_str(),
		SE_FILE_OBJECT,
		DACL_SECURITY_INFORMATION,
		nullptr,
		nullptr,
		&AccessControlCurrent,
		nullptr,
		&SecurityDescriptor) == ERROR_SUCCESS
		)
	{
		ConvertStringSidToSidW(AccessString, &SecurityIdentifier);
		if( SecurityIdentifier != nullptr )
		{
			ExplicitAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
			ExplicitAccess.grfAccessMode = SET_ACCESS;
			ExplicitAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
			ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ExplicitAccess.Trustee.ptstrName = reinterpret_cast<wchar_t*>(SecurityIdentifier);

			if( SetEntriesInAclW(
				1,
				&ExplicitAccess,
				AccessControlCurrent,
				&AccessControlNew) == ERROR_SUCCESS )
			{
				SetNamedSecurityInfoW(
					const_cast<wchar_t*>(ExecutableName.c_str()),
					SE_FILE_OBJECT,
					SecurityInfo,
					nullptr,
					nullptr,
					AccessControlNew,
					nullptr
				);
			};
		}
	}
	if( SecurityDescriptor )
	{
		LocalFree(
			reinterpret_cast<HLOCAL>(SecurityDescriptor)
		);
	}
	if( AccessControlNew )
	{
		LocalFree(
			reinterpret_cast<HLOCAL>(AccessControlNew)
		);
	}
}

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath)
{
	const size_t DLLPathSize = ((DLLpath.size() + 1) * sizeof(wchar_t));
	uint32_t Result = 0;
	if( !ProcessID )
	{
		std::wcout << "Invalid Process ID: " << ProcessID << std::endl;
		return false;
	}

	if( GetFileAttributesW(DLLpath.c_str()) == INVALID_FILE_ATTRIBUTES )
	{
		std::wcout << "DLL file: " << DLLpath << " does not exists" << std::endl;
		return false;
	}

	SetAccessControl(DLLpath, L"S-1-15-2-1");

	void* ProcLoadLibrary = reinterpret_cast<void*>(
		GetProcAddress(
			GetModuleHandleW(L"kernel32.dll"),
			"LoadLibraryW")
		);

	if( !ProcLoadLibrary )
	{
		std::wcout << "Unable to find LoadLibraryW procedure" << std::endl;
		return false;
	}

	void* Process = OpenProcess(
		PROCESS_ALL_ACCESS,
		false,
		ProcessID);
	if( Process == nullptr )
	{
		std::wcout << "Unable to open process ID" << ProcessID << " for writing" << std::endl;
		return false;
	}
	void* VirtualAlloc = reinterpret_cast<void*>(
		VirtualAllocEx(
			Process,
			nullptr,
			DLLPathSize,
			MEM_RESERVE | MEM_COMMIT,
			PAGE_READWRITE
		)
		);

	if( VirtualAlloc == nullptr )
	{
		std::wcout << "Unable to remotely allocate memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	SIZE_T BytesWritten = 0;
	Result = WriteProcessMemory(
		Process,
		VirtualAlloc,
		DLLpath.data(),
		DLLPathSize,
		&BytesWritten
	);

	if( Result == 0 )
	{
		std::wcout << "Unable to write process memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	if( BytesWritten != DLLPathSize )
	{
		std::wcout << "Failed to write remote DLL path name" << std::endl;
		CloseHandle(Process);
		return false;
	}

	void* RemoteThread =
		CreateRemoteThread(
			Process,
			nullptr,
			0,
			reinterpret_cast<LPTHREAD_START_ROUTINE>(ProcLoadLibrary),
			VirtualAlloc,
			0,
			0
		);

	// Wait for remote thread to finish
	if( RemoteThread )
	{
		// Explicitly wait for LoadLibraryW to complete before releasing memory
		// avoids causing a remote memory leak
		WaitForSingleObject(RemoteThread, INFINITE);
		CloseHandle(RemoteThread);
	}
	else
	{
		// Failed to create thread
		std::wcout << "Unable to create remote thread" << std::endl;
	}

	VirtualFreeEx(Process, VirtualAlloc, 0, MEM_RELEASE);
	CloseHandle(Process);
	return true;
}

std::wstring GetRunningDirectory()
{
	wchar_t RunPath[MAX_PATH];
	GetModuleFileNameW(GetModuleHandleW(nullptr), RunPath, MAX_PATH);
	PathRemoveFileSpecW(RunPath);
	return std::wstring(RunPath);
}<commit_msg>Add process iteration failure message<commit_after>#include <iostream>
#include <iomanip>
#include <string>
#include <memory>

#include <windows.h>
#include <psapi.h> //GetModuleFileNameEx
#include <TlHelp32.h>

// Setting DLL access controls
#include <AccCtrl.h>
#include <Aclapi.h>
#include <Sddl.h>

// UWP
#include <atlbase.h>
#include <appmodel.h>

#include "MinConsole.hpp"

namespace Console = MinConsole;

const wchar_t* DLLFile = L"UWPDumper.dll";

void SetAccessControl(
	const std::wstring &ExecutableName,
	const wchar_t *AccessString
);

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring &DLLpath);

std::wstring GetRunningDirectory();

int main()
{
	SetConsoleOutputCP(437);

	Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
	std::wcout << "UWPInjector Build date (" << __DATE__ << " : " << __TIME__ << ")" << std::endl;
	Console::SetTextColor(Console::Color::Input);
	std::wcout << "\t-https://github.com/Wunkolo/UWPDumper\n";
	Console::SetTextColor(Console::Color::Magenta);
	std::wcout << std::wstring(Console::GetWidth() - 1, '-') << std::endl;
	Console::SetTextColor(Console::Color::Info);

	uint32_t ProcessID = 0;

	std::cout << "Currently running UWP Apps:" << std::endl;
	void* ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 ProcessEntry;
	ProcessEntry.dwSize = sizeof(PROCESSENTRY32);

	if( Process32First(ProcessSnapshot, &ProcessEntry) )
	{
		while( Process32Next(ProcessSnapshot, &ProcessEntry) )
		{
			void* ProcessHandle = OpenProcess(
				PROCESS_QUERY_LIMITED_INFORMATION,
				false,
				ProcessEntry.th32ProcessID
			);
			if( ProcessHandle )
			{
				uint32_t NameLength = 0;
				int32_t ProcessCode = GetPackageFamilyName(
					ProcessHandle,
					&NameLength,
					nullptr
				);
				if( NameLength )
				{
					Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
					std::wcout
						<< std::setw(12)
						<< ProcessEntry.th32ProcessID;

					Console::SetTextColor(Console::Color::Info);
					std::wcout
						<< " | "
						<< ProcessEntry.szExeFile << " :\n\t\t-";
					std::unique_ptr<wchar_t[]> PackageName(new wchar_t[NameLength]());

					ProcessCode = GetPackageFamilyName(
						ProcessHandle,
						&NameLength,
						PackageName.get()
					);

					if( ProcessCode != ERROR_SUCCESS )
					{
						std::wcout << "GetPackageFamilyName Error: " << ProcessCode;
					}

					std::wcout << PackageName.get() << std::endl;

					PackageName.reset();
				}
			}
			CloseHandle(ProcessHandle);
		}
	}
	else
	{
		Console::SetTextColor(Console::Color::Red | Console::Color::Bright);
		std::cout << "Unable to iterate active processes" << std::endl;
		system("pause");
		return 1;
	}
	std::cout << "Enter ProcessID: ";
	Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
	std::cin >> ProcessID;
	Console::SetTextColor(Console::Color::Info);

	SetAccessControl(GetRunningDirectory() + L"\\" + DLLFile, L"S-1-15-2-1");

	if( DLLInjectRemote(ProcessID, GetRunningDirectory() + L"\\" + DLLFile) )
	{
		Console::SetTextColor(Console::Color::Green | Console::Color::Bright);
		std::cout << "Success!" << std::endl;
	}
	else
	{
		Console::SetTextColor(Console::Color::Red | Console::Color::Bright);
		std::cout << "Failed" << std::endl;
		system("pause");
	}

	return 0;
}

void SetAccessControl(const std::wstring &ExecutableName, const wchar_t* AccessString)
{
	PSECURITY_DESCRIPTOR SecurityDescriptor = nullptr;
	EXPLICIT_ACCESSW ExplicitAccess = { 0 };

	ACL *AccessControlCurrent = nullptr;
	ACL *AccessControlNew = nullptr;

	SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION;
	PSID SecurityIdentifier = nullptr;

	if( GetNamedSecurityInfoW(
		ExecutableName.c_str(),
		SE_FILE_OBJECT,
		DACL_SECURITY_INFORMATION,
		nullptr,
		nullptr,
		&AccessControlCurrent,
		nullptr,
		&SecurityDescriptor) == ERROR_SUCCESS
		)
	{
		ConvertStringSidToSidW(AccessString, &SecurityIdentifier);
		if( SecurityIdentifier != nullptr )
		{
			ExplicitAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
			ExplicitAccess.grfAccessMode = SET_ACCESS;
			ExplicitAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
			ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ExplicitAccess.Trustee.ptstrName = reinterpret_cast<wchar_t*>(SecurityIdentifier);

			if( SetEntriesInAclW(
				1,
				&ExplicitAccess,
				AccessControlCurrent,
				&AccessControlNew) == ERROR_SUCCESS )
			{
				SetNamedSecurityInfoW(
					const_cast<wchar_t*>(ExecutableName.c_str()),
					SE_FILE_OBJECT,
					SecurityInfo,
					nullptr,
					nullptr,
					AccessControlNew,
					nullptr
				);
			};
		}
	}
	if( SecurityDescriptor )
	{
		LocalFree(
			reinterpret_cast<HLOCAL>(SecurityDescriptor)
		);
	}
	if( AccessControlNew )
	{
		LocalFree(
			reinterpret_cast<HLOCAL>(AccessControlNew)
		);
	}
}

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath)
{
	const size_t DLLPathSize = ((DLLpath.size() + 1) * sizeof(wchar_t));
	uint32_t Result = 0;
	if( !ProcessID )
	{
		std::wcout << "Invalid Process ID: " << ProcessID << std::endl;
		return false;
	}

	if( GetFileAttributesW(DLLpath.c_str()) == INVALID_FILE_ATTRIBUTES )
	{
		std::wcout << "DLL file: " << DLLpath << " does not exists" << std::endl;
		return false;
	}

	SetAccessControl(DLLpath, L"S-1-15-2-1");

	void* ProcLoadLibrary = reinterpret_cast<void*>(
		GetProcAddress(
			GetModuleHandleW(L"kernel32.dll"),
			"LoadLibraryW")
		);

	if( !ProcLoadLibrary )
	{
		std::wcout << "Unable to find LoadLibraryW procedure" << std::endl;
		return false;
	}

	void* Process = OpenProcess(
		PROCESS_ALL_ACCESS,
		false,
		ProcessID);
	if( Process == nullptr )
	{
		std::wcout << "Unable to open process ID" << ProcessID << " for writing" << std::endl;
		return false;
	}
	void* VirtualAlloc = reinterpret_cast<void*>(
		VirtualAllocEx(
			Process,
			nullptr,
			DLLPathSize,
			MEM_RESERVE | MEM_COMMIT,
			PAGE_READWRITE
		)
		);

	if( VirtualAlloc == nullptr )
	{
		std::wcout << "Unable to remotely allocate memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	SIZE_T BytesWritten = 0;
	Result = WriteProcessMemory(
		Process,
		VirtualAlloc,
		DLLpath.data(),
		DLLPathSize,
		&BytesWritten
	);

	if( Result == 0 )
	{
		std::wcout << "Unable to write process memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	if( BytesWritten != DLLPathSize )
	{
		std::wcout << "Failed to write remote DLL path name" << std::endl;
		CloseHandle(Process);
		return false;
	}

	void* RemoteThread =
		CreateRemoteThread(
			Process,
			nullptr,
			0,
			reinterpret_cast<LPTHREAD_START_ROUTINE>(ProcLoadLibrary),
			VirtualAlloc,
			0,
			0
		);

	// Wait for remote thread to finish
	if( RemoteThread )
	{
		// Explicitly wait for LoadLibraryW to complete before releasing memory
		// avoids causing a remote memory leak
		WaitForSingleObject(RemoteThread, INFINITE);
		CloseHandle(RemoteThread);
	}
	else
	{
		// Failed to create thread
		std::wcout << "Unable to create remote thread" << std::endl;
	}

	VirtualFreeEx(Process, VirtualAlloc, 0, MEM_RELEASE);
	CloseHandle(Process);
	return true;
}

std::wstring GetRunningDirectory()
{
	wchar_t RunPath[MAX_PATH];
	GetModuleFileNameW(GetModuleHandleW(nullptr), RunPath, MAX_PATH);
	PathRemoveFileSpecW(RunPath);
	return std::wstring(RunPath);
}<|endoftext|>


<commit_before>// Copyright (c) 2016-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/test/rpcnestedtests.h>

#include <interfaces/node.h>
#include <rpc/server.h>
#include <qt/rpcconsole.h>
#include <test/util/setup_common.h>
#include <univalue.h>
#include <util/system.h>

#include <QDir>
#include <QtGlobal>

static RPCHelpMan rpcNestedTest_rpc()
{
    return RPCHelpMan{
        "rpcNestedTest",
        "echo the passed string(s)",
        {
            {"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
            {"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
            {"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
        },
        {},
        RPCExamples{""},
        [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
            return request.params.write(0, 0);
        },
    };
}

static const CRPCCommand vRPCCommands[] = {
    {"test", "rpcNestedTest", &rpcNestedTest_rpc, {"arg1", "arg2", "arg3"}},
};

void RPCNestedTests::rpcNestedTests()
{
    // do some test setup
    // could be moved to a more generic place when we add more tests on QT level
    tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]);

    TestingSetup test;

    if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished();

    std::string result;
    std::string result2;
    std::string filtered;
    interfaces::Node* node = &m_node;
    RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()[chain]", &filtered); //simple result filtering with path
    QVERIFY(result=="main");
    QVERIFY(filtered == "getblockchaininfo()[chain]");

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getbestblockhash())"); //simple 2 level nesting
    RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getblock(getbestblockhash())[hash], true)");

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo");
    QVERIFY(result.substr(0,1) == "{");

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()");
    QVERIFY(result.substr(0,1) == "{");

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo "); //whitespace at the end will be tolerated
    QVERIFY(result.substr(0,1) == "{");

    (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key
    QVERIFY(result == "null");

    (RPCConsole::RPCExecuteCommandLine(*node, result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
    (RPCConsole::RPCExecuteCommandLine(*node, result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
    QVERIFY(result == result2);
    (RPCConsole::RPCExecuteCommandLine(*node, result2, "createrawtransaction( [],  {} , 0   )")); //whitespace between parameters is allowed
    QVERIFY(result == result2);

    RPCConsole::RPCExecuteCommandLine(*node, result, "getblock(getbestblockhash())[tx][0]", &filtered);
    QVERIFY(result == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
    QVERIFY(filtered == "getblock(getbestblockhash())[tx][0]");

    RPCConsole::RPCParseCommandLine(nullptr, result, "importprivkey", false, &filtered);
    QVERIFY(filtered == "importprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc", false, &filtered);
    QVERIFY(filtered == "signmessagewithprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc,def", false, &filtered);
    QVERIFY(filtered == "signmessagewithprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signrawtransactionwithkey(abc)", false, &filtered);
    QVERIFY(filtered == "signrawtransactionwithkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrase(help())", false, &filtered);
    QVERIFY(filtered == "walletpassphrase(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrasechange(help(walletpassphrasechange(abc)))", false, &filtered);
    QVERIFY(filtered == "walletpassphrasechange(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(encryptwallet(abc, def))", false, &filtered);
    QVERIFY(filtered == "help(encryptwallet(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey())", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(help()))", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(abc), walletpassphrase(def))", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…), walletpassphrase(…))");

    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest");
    QVERIFY(result == "[]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest ''");
    QVERIFY(result == "[\"\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest \"\"");
    QVERIFY(result == "[\"\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest '' abc");
    QVERIFY(result == "[\"\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc '' abc");
    QVERIFY(result == "[\"abc\",\"\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc  abc");
    QVERIFY(result == "[\"abc\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc\t\tabc");
    QVERIFY(result == "[\"abc\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc )");
    QVERIFY(result == "[\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest( abc )");
    QVERIFY(result == "[\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(   abc   ,   cba )");
    QVERIFY(result == "[\"abc\",\"cba\"]");

    // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
    (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
    (RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo()()()")); //tolerate non command brackts
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "getblockchaininfo(True)"), UniValue); //invalid argument
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "a(getblockchaininfo(True))"), UniValue); //method not found
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using ,
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using ,
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(*node, result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
}
<commit_msg>qt/test: [FIX] Add forgotten Context setting in RPCNestedTests<commit_after>// Copyright (c) 2016-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/test/rpcnestedtests.h>

#include <interfaces/node.h>
#include <rpc/server.h>
#include <qt/rpcconsole.h>
#include <test/util/setup_common.h>
#include <univalue.h>
#include <util/system.h>

#include <QDir>
#include <QtGlobal>

static RPCHelpMan rpcNestedTest_rpc()
{
    return RPCHelpMan{
        "rpcNestedTest",
        "echo the passed string(s)",
        {
            {"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
            {"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
            {"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""},
        },
        {},
        RPCExamples{""},
        [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
            return request.params.write(0, 0);
        },
    };
}

static const CRPCCommand vRPCCommands[] = {
    {"test", "rpcNestedTest", &rpcNestedTest_rpc, {"arg1", "arg2", "arg3"}},
};

void RPCNestedTests::rpcNestedTests()
{
    // do some test setup
    // could be moved to a more generic place when we add more tests on QT level
    tableRPC.appendCommand("rpcNestedTest", &vRPCCommands[0]);

    TestingSetup test;
    m_node.setContext(&test.m_node);

    if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished();

    std::string result;
    std::string result2;
    std::string filtered;
    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()[chain]", &filtered); //simple result filtering with path
    QVERIFY(result=="main");
    QVERIFY(filtered == "getblockchaininfo()[chain]");

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock(getbestblockhash())"); //simple 2 level nesting
    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock(getblock(getbestblockhash())[hash], true)");

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock( getblock( getblock(getbestblockhash())[hash] )[hash], true)"); //4 level nesting with whitespace, filtering path and boolean parameter

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo");
    QVERIFY(result.substr(0,1) == "{");

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()");
    QVERIFY(result.substr(0,1) == "{");

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo "); //whitespace at the end will be tolerated
    QVERIFY(result.substr(0,1) == "{");

    (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child containing the quotes in the key
    QVERIFY(result == "null");

    (RPCConsole::RPCExecuteCommandLine(m_node, result, "createrawtransaction [] {} 0")); //parameter not in brackets are allowed
    (RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction([],{},0)")); //parameter in brackets are allowed
    QVERIFY(result == result2);
    (RPCConsole::RPCExecuteCommandLine(m_node, result2, "createrawtransaction( [],  {} , 0   )")); //whitespace between parameters is allowed
    QVERIFY(result == result2);

    RPCConsole::RPCExecuteCommandLine(m_node, result, "getblock(getbestblockhash())[tx][0]", &filtered);
    QVERIFY(result == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
    QVERIFY(filtered == "getblock(getbestblockhash())[tx][0]");

    RPCConsole::RPCParseCommandLine(nullptr, result, "importprivkey", false, &filtered);
    QVERIFY(filtered == "importprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc", false, &filtered);
    QVERIFY(filtered == "signmessagewithprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signmessagewithprivkey abc,def", false, &filtered);
    QVERIFY(filtered == "signmessagewithprivkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "signrawtransactionwithkey(abc)", false, &filtered);
    QVERIFY(filtered == "signrawtransactionwithkey(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrase(help())", false, &filtered);
    QVERIFY(filtered == "walletpassphrase(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "walletpassphrasechange(help(walletpassphrasechange(abc)))", false, &filtered);
    QVERIFY(filtered == "walletpassphrasechange(…)");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(encryptwallet(abc, def))", false, &filtered);
    QVERIFY(filtered == "help(encryptwallet(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey())", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(help()))", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…))");
    RPCConsole::RPCParseCommandLine(nullptr, result, "help(importprivkey(abc), walletpassphrase(def))", false, &filtered);
    QVERIFY(filtered == "help(importprivkey(…), walletpassphrase(…))");

    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest");
    QVERIFY(result == "[]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest ''");
    QVERIFY(result == "[\"\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest \"\"");
    QVERIFY(result == "[\"\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest '' abc");
    QVERIFY(result == "[\"\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc '' abc");
    QVERIFY(result == "[\"abc\",\"\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc  abc");
    QVERIFY(result == "[\"abc\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc\t\tabc");
    QVERIFY(result == "[\"abc\",\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc )");
    QVERIFY(result == "[\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest( abc )");
    QVERIFY(result == "[\"abc\"]");
    RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(   abc   ,   cba )");
    QVERIFY(result == "[\"abc\",\"cba\"]");

    // do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
    (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
    (RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo()()()")); //tolerate non command brackts
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "getblockchaininfo(True)"), UniValue); //invalid argument
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "a(getblockchaininfo(True))"), UniValue); //method not found
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using ,
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using ,
    QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(m_node, result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
}
<|endoftext|>


<commit_before>#include <windows.h>
#include "overlay.h"
#include <OvRender.h>
#include "osd.h"
#include "menu.h"
#include <stdio.h>

BOOLEAN g_FontInited = FALSE;
BOOLEAN IsStableFramerate;
BOOLEAN IsStableFrametime;
BOOLEAN IsLimitedFrametime;
BOOLEAN DisableAutoOverclock;
UINT16 DiskResponseTime;
UINT64 CyclesWaited;
HANDLE RenderThreadHandle;
UINT32 DisplayFrequency;
double FrameTimeAvg;
double FrameRate;
UINT8 FrameLimit = 80; //80 fps
int debugInt = 1;

VOID DebugRec();
VOID InitializeKeyboardHook();

double PCFreq = 0.0;
__int64 CounterStart = 0;
typedef enum _OVERCLOCK_UNIT
{
    OC_ENGINE,
    OC_MEMORY

}OVERCLOCK_UNIT;
VOID Overclock(OVERCLOCK_UNIT Unit);
extern "C" LONG __stdcall NtQueryPerformanceCounter(
    LARGE_INTEGER* PerformanceCounter,
    LARGE_INTEGER* PerformanceFrequency
    );
VOID StartCounter()
{
    LARGE_INTEGER perfCount;
    LARGE_INTEGER frequency;

    NtQueryPerformanceCounter(&perfCount, &frequency);

    PCFreq = (double)frequency.QuadPart / 1000.0;;
}

double GetPerformanceCounter()
{
    LARGE_INTEGER li;

    NtQueryPerformanceCounter(&li, NULL);

    return (double)li.QuadPart / PCFreq;
}

BOOLEAN IsGpuLag()
{
    if (PushSharedMemory->HarwareInformation.DisplayDevice.Load > 95)
    {
        return TRUE;
    }

    return FALSE;
}

#define TSAMP 60
double garb[TSAMP];
int addint = 0;

double GetAverageFrameTime()
{

    UINT32 i;
    double total = 0;

    for (i = 0; i < TSAMP; i++)
        total += garb[i];

    return total / TSAMP;
}

#include <math.h>
bool approximatelyEqual(double a, double b, double epsilon)
{
    return fabs(a - b) < epsilon;
}

VOID RunFrameStatistics()
{
    static double newTickCount = 0.0, lastTickCount_FrameLimiter = 0.0,
        oldTick = 0.0, delta = 0.0,
        oldTick2 = 0.0, frameTime = 0.0, acceptableFrameTime = 0.0, lastTickCount;

    static BOOLEAN inited = FALSE;

    if (!inited)
    {
        DEVMODE devMode;
        StartCounter();
        inited = TRUE;

        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);

        DisplayFrequency = devMode.dmDisplayFrequency;
        acceptableFrameTime = (double)1000 / (double)(devMode.dmDisplayFrequency - 1);

        if (PushSharedMemory->FrameLimit > 1)
            FrameLimit = PushSharedMemory->FrameLimit;

        newTickCount = oldTick = lastTickCount_FrameLimiter = GetPerformanceCounter();
    }

    newTickCount = GetPerformanceCounter();
    delta = newTickCount - oldTick;
    frameTime = newTickCount - lastTickCount;
    lastTickCount = newTickCount;

    IsLimitedFrametime = FALSE;

    garb[addint] = frameTime;
    addint++;

    if (addint == TSAMP)
        addint = 0;

    FrameTimeAvg = GetAverageFrameTime();

    static double OldfFPS = 0.0f;
    FrameRate = 1000.0f / FrameTimeAvg;

    FrameRate = FrameRate * 0.1 + OldfFPS * 0.9;
    //FrameRate = FrameRate * 0.01 + OldfFPS * 0.99; even slower damping

    OldfFPS = FrameRate;

    // Every second.
    if (delta > 1000)
    {
        oldTick = newTickCount;

        //if (PushSharedMemory->ThreadOptimization || PushSharedMemory->OSDFlags & OSD_MTU)
        //{
            PushRefreshThreadMonitor();

            //if (PushSharedMemory->OSDFlags & OSD_MTU)
            PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage = PushGetMaxThreadUsage();
        //}

        RenderThreadHandle = GetCurrentThread();
    }

    // Simple Diagnostics.

    if (frameTime > acceptableFrameTime)
    {
        if (PushSharedMemory->HarwareInformation.Processor.Load > 95)
            PushSharedMemory->Overloads |= OSD_CPU_LOAD;

        if (PushSharedMemory->HarwareInformation.Processor.MaxCoreUsage > 95)
            PushSharedMemory->Overloads |= OSD_MCU;

        if (PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage > 95)
            PushSharedMemory->Overloads |= OSD_MTU;

        if (IsGpuLag()) PushSharedMemory->Overloads |= OSD_GPU_LOAD;

        if (PushSharedMemory->HarwareInformation.Memory.Used > PushSharedMemory->HarwareInformation.Memory.Total)
            PushSharedMemory->Overloads |= OSD_RAM;

        PushSharedMemory->HarwareInformation.Disk.ResponseTime = DiskResponseTime;

        if (PushSharedMemory->HarwareInformation.Disk.ResponseTime > 4000)
        {
            PushSharedMemory->Overloads |= OSD_DISK_RESPONSE;
            PushSharedMemory->OSDFlags |= OSD_DISK_RESPONSE;
        }

        if (PushSharedMemory->AutoLogFileIo)
            PushSharedMemory->LogFileIo = TRUE;

        if (PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage > 95)
        {
            PushSharedMemory->Overloads |= OSD_MTU;
            PushSharedMemory->OSDFlags |= OSD_MTU;
        }
    }

    if (newTickCount - oldTick2 > 30000)
        //frame rate has been stable for at least 30 seconds.
        IsStableFramerate = TRUE;
    else
        IsStableFramerate = FALSE;

    if (FrameTimeAvg > acceptableFrameTime)
    {
        //reset the timer
        oldTick2 = newTickCount;

        // Lazy overclock
        if (debugInt++ % DisplayFrequency == 0)
        {
            if (!DisableAutoOverclock && IsGpuLag())
            {
                PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;
                PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;
                PushSharedMemory->Overloads |= OSD_GPU_E_CLK;
                PushSharedMemory->Overloads |= OSD_GPU_M_CLK;

                if (PushSharedMemory->HarwareInformation.DisplayDevice.EngineClockMax < PushSharedMemory->HarwareInformation.DisplayDevice.EngineOverclock)
                    Overclock(OC_ENGINE);

                if (PushSharedMemory->HarwareInformation.DisplayDevice.MemoryClockMax < PushSharedMemory->HarwareInformation.DisplayDevice.MemoryOverclock)
                    Overclock(OC_MEMORY);
            }
        }
    }

    double frameTimeDamped = 1000.0f / FrameRate;

    if (frameTimeDamped > acceptableFrameTime)
        IsStableFrametime = FALSE;
    else
        IsStableFrametime = TRUE;

    if (PushSharedMemory->FrameLimit)
    {
        double frameTimeMin = (double)1000 / (double)FrameLimit;

        frameTime = newTickCount - lastTickCount_FrameLimiter;

        if (approximatelyEqual(frameTimeDamped, frameTimeMin, 0.100))
        {
            IsLimitedFrametime = TRUE;
        }

        if (frameTime < frameTimeMin)
        {
            UINT64 cyclesStart, cyclesStop;

            RenderThreadHandle = GetCurrentThread();

            QueryThreadCycleTime(RenderThreadHandle, &cyclesStart);

            lastTickCount_FrameLimiter = newTickCount;

            while (frameTime < frameTimeMin)
            {
                newTickCount = GetPerformanceCounter();

                frameTime += (newTickCount - lastTickCount_FrameLimiter);

                lastTickCount_FrameLimiter = newTickCount;
            }

            QueryThreadCycleTime(RenderThreadHandle, &cyclesStop);

            CyclesWaited += cyclesStop - cyclesStart;
        }

        lastTickCount_FrameLimiter = newTickCount;
    }
}

VOID RnRender( OvOverlay* Overlay )
{
    static BOOLEAN rendering = FALSE;

    if (!rendering)
    {
        rendering = TRUE;

        InitializeKeyboardHook();
    }

    Osd_Draw( Overlay );
    MnuRender( Overlay );
    RunFrameStatistics();

    //Overlay->DrawText(L"u can draw anything in this render loop!\n");
}
<commit_msg>adopt acceptableFrameTime to FrameLimit<commit_after>#include <windows.h>
#include "overlay.h"
#include <OvRender.h>
#include "osd.h"
#include "menu.h"
#include <stdio.h>

BOOLEAN g_FontInited = FALSE;
BOOLEAN IsStableFramerate;
BOOLEAN IsStableFrametime;
BOOLEAN IsLimitedFrametime;
BOOLEAN DisableAutoOverclock;
UINT16 DiskResponseTime;
UINT64 CyclesWaited;
HANDLE RenderThreadHandle;
UINT32 DisplayFrequency;
double FrameTimeAvg;
double FrameRate;
UINT8 FrameLimit = 80; //80 fps
int debugInt = 1;

VOID DebugRec();
VOID InitializeKeyboardHook();

double PCFreq = 0.0;
__int64 CounterStart = 0;
typedef enum _OVERCLOCK_UNIT
{
    OC_ENGINE,
    OC_MEMORY

}OVERCLOCK_UNIT;
VOID Overclock(OVERCLOCK_UNIT Unit);
extern "C" LONG __stdcall NtQueryPerformanceCounter(
    LARGE_INTEGER* PerformanceCounter,
    LARGE_INTEGER* PerformanceFrequency
    );
VOID StartCounter()
{
    LARGE_INTEGER perfCount;
    LARGE_INTEGER frequency;

    NtQueryPerformanceCounter(&perfCount, &frequency);

    PCFreq = (double)frequency.QuadPart / 1000.0;;
}

double GetPerformanceCounter()
{
    LARGE_INTEGER li;

    NtQueryPerformanceCounter(&li, NULL);

    return (double)li.QuadPart / PCFreq;
}

BOOLEAN IsGpuLag()
{
    if (PushSharedMemory->HarwareInformation.DisplayDevice.Load > 95)
    {
        return TRUE;
    }

    return FALSE;
}

#define TSAMP 60
double garb[TSAMP];
int addint = 0;

double GetAverageFrameTime()
{

    UINT32 i;
    double total = 0;

    for (i = 0; i < TSAMP; i++)
        total += garb[i];

    return total / TSAMP;
}

#include <math.h>
bool approximatelyEqual(double a, double b, double epsilon)
{
    return fabs(a - b) < epsilon;
}

VOID RunFrameStatistics()
{
    static double newTickCount = 0.0, lastTickCount_FrameLimiter = 0.0,
        oldTick = 0.0, delta = 0.0,
        oldTick2 = 0.0, frameTime = 0.0, acceptableFrameTime = 0.0, lastTickCount;

    static BOOLEAN inited = FALSE;

    if (!inited)
    {
        DEVMODE devMode;
        StartCounter();
        inited = TRUE;

        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);

        DisplayFrequency = devMode.dmDisplayFrequency;
        acceptableFrameTime = (double)1000 / (double)(devMode.dmDisplayFrequency - 1);

        if (PushSharedMemory->FrameLimit > 1)
        {
            FrameLimit = PushSharedMemory->FrameLimit;
            acceptableFrameTime = 1000.0f / (double)(FrameLimit - 1);
        }

        newTickCount = oldTick = lastTickCount_FrameLimiter = GetPerformanceCounter();
    }

    newTickCount = GetPerformanceCounter();
    delta = newTickCount - oldTick;
    frameTime = newTickCount - lastTickCount;
    lastTickCount = newTickCount;

    IsLimitedFrametime = FALSE;

    garb[addint] = frameTime;
    addint++;

    if (addint == TSAMP)
        addint = 0;

    FrameTimeAvg = GetAverageFrameTime();

    static double OldfFPS = 0.0f;
    FrameRate = 1000.0f / FrameTimeAvg;

    FrameRate = FrameRate * 0.1 + OldfFPS * 0.9;
    //FrameRate = FrameRate * 0.01 + OldfFPS * 0.99; even slower damping

    OldfFPS = FrameRate;

    // Every second.
    if (delta > 1000)
    {
        oldTick = newTickCount;

        //if (PushSharedMemory->ThreadOptimization || PushSharedMemory->OSDFlags & OSD_MTU)
        //{
            PushRefreshThreadMonitor();

            //if (PushSharedMemory->OSDFlags & OSD_MTU)
            PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage = PushGetMaxThreadUsage();
        //}

        RenderThreadHandle = GetCurrentThread();
    }

    // Simple Diagnostics.

    if (frameTime > acceptableFrameTime)
    {
        if (PushSharedMemory->HarwareInformation.Processor.Load > 95)
            PushSharedMemory->Overloads |= OSD_CPU_LOAD;

        if (PushSharedMemory->HarwareInformation.Processor.MaxCoreUsage > 95)
            PushSharedMemory->Overloads |= OSD_MCU;

        if (PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage > 95)
            PushSharedMemory->Overloads |= OSD_MTU;

        if (IsGpuLag()) PushSharedMemory->Overloads |= OSD_GPU_LOAD;

        if (PushSharedMemory->HarwareInformation.Memory.Used > PushSharedMemory->HarwareInformation.Memory.Total)
            PushSharedMemory->Overloads |= OSD_RAM;

        PushSharedMemory->HarwareInformation.Disk.ResponseTime = DiskResponseTime;

        if (PushSharedMemory->HarwareInformation.Disk.ResponseTime > 4000)
        {
            PushSharedMemory->Overloads |= OSD_DISK_RESPONSE;
            PushSharedMemory->OSDFlags |= OSD_DISK_RESPONSE;
        }

        if (PushSharedMemory->AutoLogFileIo)
            PushSharedMemory->LogFileIo = TRUE;

        if (PushSharedMemory->HarwareInformation.Processor.MaxThreadUsage > 95)
        {
            PushSharedMemory->Overloads |= OSD_MTU;
            PushSharedMemory->OSDFlags |= OSD_MTU;
        }
    }

    if (newTickCount - oldTick2 > 30000)
        //frame rate has been stable for at least 30 seconds.
        IsStableFramerate = TRUE;
    else
        IsStableFramerate = FALSE;

    if (FrameTimeAvg > acceptableFrameTime)
    {
        //reset the timer
        oldTick2 = newTickCount;

        // Lazy overclock
        if (debugInt++ % DisplayFrequency == 0)
        {
            if (!DisableAutoOverclock && IsGpuLag())
            {
                PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;
                PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;
                PushSharedMemory->Overloads |= OSD_GPU_E_CLK;
                PushSharedMemory->Overloads |= OSD_GPU_M_CLK;

                if (PushSharedMemory->HarwareInformation.DisplayDevice.EngineClockMax < PushSharedMemory->HarwareInformation.DisplayDevice.EngineOverclock)
                    Overclock(OC_ENGINE);

                if (PushSharedMemory->HarwareInformation.DisplayDevice.MemoryClockMax < PushSharedMemory->HarwareInformation.DisplayDevice.MemoryOverclock)
                    Overclock(OC_MEMORY);
            }
        }
    }

    double frameTimeDamped = 1000.0f / FrameRate;

    if (frameTimeDamped > acceptableFrameTime)
        IsStableFrametime = FALSE;
    else
        IsStableFrametime = TRUE;

    if (PushSharedMemory->FrameLimit)
    {
        double frameTimeMin = (double)1000 / (double)FrameLimit;

        frameTime = newTickCount - lastTickCount_FrameLimiter;

        if (approximatelyEqual(frameTimeDamped, frameTimeMin, 0.100))
        {
            IsLimitedFrametime = TRUE;
        }

        if (frameTime < frameTimeMin)
        {
            UINT64 cyclesStart, cyclesStop;

            RenderThreadHandle = GetCurrentThread();

            QueryThreadCycleTime(RenderThreadHandle, &cyclesStart);

            lastTickCount_FrameLimiter = newTickCount;

            while (frameTime < frameTimeMin)
            {
                newTickCount = GetPerformanceCounter();

                frameTime += (newTickCount - lastTickCount_FrameLimiter);

                lastTickCount_FrameLimiter = newTickCount;
            }

            QueryThreadCycleTime(RenderThreadHandle, &cyclesStop);

            CyclesWaited += cyclesStop - cyclesStart;
        }

        lastTickCount_FrameLimiter = newTickCount;
    }
}

VOID RnRender( OvOverlay* Overlay )
{
    static BOOLEAN rendering = FALSE;

    if (!rendering)
    {
        rendering = TRUE;

        InitializeKeyboardHook();
    }

    Osd_Draw( Overlay );
    MnuRender( Overlay );
    RunFrameStatistics();

    //Overlay->DrawText(L"u can draw anything in this render loop!\n");
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 Roman Neuhauser
// Distributed under the MIT license (see LICENSE file)
// vim: sw=4 sts=4 et fdm=marker cms=\ //\ %s

#include "php_iniphile.hpp"
#include "iniphile.hpp"

#include "zend_exceptions.h"

zend_class_entry *iniphile_ce;
zend_object_handlers iniphile_object_handlers;

struct phpini
// {{{
{
    zend_object std;
    iniphile_bridge *impl;
}; // }}}

#define PHPTHIS() \
    static_cast<phpini *>( \
        zend_object_store_get_object(getThis() TSRMLS_CC) \
    )

void
iniphile_free_storage(void *object TSRMLS_DC) // {{{
{
    phpini *obj = static_cast<phpini *>(object);
    delete obj->impl;

    zend_hash_destroy(obj->std.properties);
    FREE_HASHTABLE(obj->std.properties);

    efree(obj);
} // }}}

static
void
init(zend_object *zob, zend_class_entry *type TSRMLS_DC) // {{{
{
    zob->ce = type;

    ALLOC_HASHTABLE(zob->properties);
    zend_hash_init(
        zob->properties
      , 0
      , 0
      , ZVAL_PTR_DTOR
      , 0
    );

    zval *tmp;

    zend_hash_copy(
        zob->properties
      , &(zob->ce)->default_properties
      , reinterpret_cast<copy_ctor_func_t>(zval_add_ref)
      , static_cast<void *>(&tmp)
      , sizeof(zval *)
    );

} // }}}

zend_object_value
iniphile_create_handler(zend_class_entry *type TSRMLS_DC) // {{{
{
    phpini *obj = static_cast<phpini *>(
        emalloc(sizeof(phpini))
    );
    memset(obj, 0, sizeof(phpini));

    zend_object *zob(&obj->std);

    init(zob, type TSRMLS_CC);
    zend_object_value retval;

    retval.handle = zend_objects_store_put(
        obj
      , 0
      , iniphile_free_storage
      , 0 TSRMLS_CC
    );
    retval.handlers = &iniphile_object_handlers;

    return retval;
} // }}}

static
void
get_strings(zval *dst, zval const *src, phpini *obj, char const *path) // {{{
{
    typedef std::vector<std::string> Strings;
    zval **elm;
    HashPosition i;
    HashTable *hash = Z_ARRVAL_P(src);
    Strings dv;
    dv.reserve(zend_hash_num_elements(hash));
    for (
        zend_hash_internal_pointer_reset_ex(hash, &i);
        SUCCESS == zend_hash_get_current_data_ex(hash, (void**) &elm, &i);
        zend_hash_move_forward_ex(hash, &i)
    ) {
        dv.push_back(Z_STRVAL_PP(elm));
    }
    Strings rv(obj->impl->get(path, dv));
    array_init(dst);
    for (int i = 0; i < rv.size(); ++i) {
        add_next_index_string(dst, estrdup(rv[i].c_str()), 0);
    }
} // }}}

#define PHPINI_THROW(m) \
    zend_throw_exception( \
        zend_exception_get_default(TSRMLS_C) \
      , m \
      , 0 TSRMLS_CC \
    );

#if ZEND_MODULE_API_NO >= 20090626

#define PHPINI_EH_DECL zend_error_handling error_handling
#define PHPINI_EH_THROWING \
	zend_replace_error_handling( \
        EH_THROW \
      , NULL \
      , &error_handling TSRMLS_CC \
    )
#define PHPINI_EH_NORMAL zend_restore_error_handling(&error_handling TSRMLS_CC)

#else

#define PHPINI_EH_DECL
#define PHPINI_EH_THROWING \
	php_set_error_handling( \
        EH_THROW \
      , zend_exception_get_default(TSRMLS_C) TSRMLS_CC \
    )
#define PHPINI_EH_NORMAL php_std_error_handling()

#endif

PHP_METHOD(iniphile, __construct) // {{{
{
    char *path;
    int pathlen;
    PHPINI_EH_DECL;

    PHPINI_EH_THROWING;
    if (FAILURE == zend_parse_parameters(
        ZEND_NUM_ARGS() TSRMLS_CC
      , "s"
      , &path
      , &pathlen
    )) {
        PHPINI_EH_NORMAL;
        return;
    }
    PHPINI_EH_NORMAL;

    phpini *obj = PHPTHIS();
    try {
        obj->impl = new iniphile_bridge(path);
    } catch (std::exception &e) {
        zend_throw_exception_ex(
            zend_exception_get_default(TSRMLS_C)
          , 0 TSRMLS_CC
          , "'%s' could not be open"
          , path
        );
    }
} // }}}
PHP_METHOD(iniphile, path) // {{{
{
    phpini *obj = PHPTHIS();
    RETURN_STRING(estrdup(obj->impl->path().c_str()), 0);
} // }}}
PHP_METHOD(iniphile, get) // {{{
{
    phpini *obj = PHPTHIS();
    char *path;
    int path_len;
    zval *dflt;
    if (FAILURE == zend_parse_parameters(
        ZEND_NUM_ARGS() TSRMLS_CC
      , "sz"
      , &path
      , &path_len
      , &dflt
    )) {
        RETURN_NULL();
    }
    switch (Z_TYPE_P(dflt)) {
    case IS_BOOL:
        RETURN_BOOL(obj->impl->get(path, !!Z_LVAL_P(dflt)));
    case IS_LONG:
        RETURN_LONG(obj->impl->get(path, Z_LVAL_P(dflt)));
    case IS_DOUBLE:
        RETURN_DOUBLE(obj->impl->get(path, Z_DVAL_P(dflt)));
    case IS_STRING:
        RETURN_STRING(estrdup(obj->impl->get(path, std::string(Z_STRVAL_P(dflt))).c_str()), 0);
    case IS_ARRAY:
        get_strings(return_value, dflt, obj, path);
    }
} // }}}

function_entry iniphile_methods[] = // {{{
{
    PHP_ME(iniphile, __construct, 0, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(iniphile, path, 0, ZEND_ACC_PUBLIC)
    PHP_ME(iniphile, get, 0, ZEND_ACC_PUBLIC)
    {0, 0, 0}
}; // }}}

PHP_MINIT_FUNCTION(iniphile) // {{{
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "iniphile", iniphile_methods);
    iniphile_ce = zend_register_internal_class(&ce TSRMLS_CC);
    iniphile_ce->create_object = &iniphile_create_handler;
    memcpy(
        &iniphile_object_handlers
      , zend_get_std_object_handlers()
      , sizeof(zend_object_handlers)
    );
    iniphile_object_handlers.clone_obj = 0;

    return SUCCESS;
} // }}}

zend_module_entry iniphile_module_entry = // {{{
{
    STANDARD_MODULE_HEADER,
    PHP_INIPHILE_EXTNAME,
    0, // functions
    PHP_MINIT(iniphile),
    0, // MSHUTDOWN
    0, // RINIT
    0, // RSHUTDOWN
    0, // MINFO
    PHP_INIPHILE_EXTVER,
    STANDARD_MODULE_PROPERTIES
}; // }}}

#ifdef COMPILE_DL_INIPHILE
extern "C" {
ZEND_GET_MODULE(iniphile)
}
#endif
<commit_msg>userland iniphile::get throws on unsupported value types<commit_after>// Copyright (c) 2009 Roman Neuhauser
// Distributed under the MIT license (see LICENSE file)
// vim: sw=4 sts=4 et fdm=marker cms=\ //\ %s

#include "php_iniphile.hpp"
#include "iniphile.hpp"

#include "zend_exceptions.h"

zend_class_entry *iniphile_ce;
zend_object_handlers iniphile_object_handlers;

struct phpini
// {{{
{
    zend_object std;
    iniphile_bridge *impl;
}; // }}}

#define PHPTHIS() \
    static_cast<phpini *>( \
        zend_object_store_get_object(getThis() TSRMLS_CC) \
    )

void
iniphile_free_storage(void *object TSRMLS_DC) // {{{
{
    phpini *obj = static_cast<phpini *>(object);
    delete obj->impl;

    zend_hash_destroy(obj->std.properties);
    FREE_HASHTABLE(obj->std.properties);

    efree(obj);
} // }}}

static
void
init(zend_object *zob, zend_class_entry *type TSRMLS_DC) // {{{
{
    zob->ce = type;

    ALLOC_HASHTABLE(zob->properties);
    zend_hash_init(
        zob->properties
      , 0
      , 0
      , ZVAL_PTR_DTOR
      , 0
    );

    zval *tmp;

    zend_hash_copy(
        zob->properties
      , &(zob->ce)->default_properties
      , reinterpret_cast<copy_ctor_func_t>(zval_add_ref)
      , static_cast<void *>(&tmp)
      , sizeof(zval *)
    );

} // }}}

zend_object_value
iniphile_create_handler(zend_class_entry *type TSRMLS_DC) // {{{
{
    phpini *obj = static_cast<phpini *>(
        emalloc(sizeof(phpini))
    );
    memset(obj, 0, sizeof(phpini));

    zend_object *zob(&obj->std);

    init(zob, type TSRMLS_CC);
    zend_object_value retval;

    retval.handle = zend_objects_store_put(
        obj
      , 0
      , iniphile_free_storage
      , 0 TSRMLS_CC
    );
    retval.handlers = &iniphile_object_handlers;

    return retval;
} // }}}

static
void
get_strings(zval *dst, zval const *src, phpini *obj, char const *path) // {{{
{
    typedef std::vector<std::string> Strings;
    zval **elm;
    HashPosition i;
    HashTable *hash = Z_ARRVAL_P(src);
    Strings dv;
    dv.reserve(zend_hash_num_elements(hash));
    for (
        zend_hash_internal_pointer_reset_ex(hash, &i);
        SUCCESS == zend_hash_get_current_data_ex(hash, (void**) &elm, &i);
        zend_hash_move_forward_ex(hash, &i)
    ) {
        dv.push_back(Z_STRVAL_PP(elm));
    }
    Strings rv(obj->impl->get(path, dv));
    array_init(dst);
    for (int i = 0; i < rv.size(); ++i) {
        add_next_index_string(dst, estrdup(rv[i].c_str()), 0);
    }
} // }}}

#define PHPINI_THROW(m) \
    zend_throw_exception( \
        zend_exception_get_default(TSRMLS_C) \
      , m \
      , 0 TSRMLS_CC \
    );

#if ZEND_MODULE_API_NO >= 20090626

#define PHPINI_EH_DECL zend_error_handling error_handling
#define PHPINI_EH_THROWING \
	zend_replace_error_handling( \
        EH_THROW \
      , NULL \
      , &error_handling TSRMLS_CC \
    )
#define PHPINI_EH_NORMAL zend_restore_error_handling(&error_handling TSRMLS_CC)

#else

#define PHPINI_EH_DECL
#define PHPINI_EH_THROWING \
	php_set_error_handling( \
        EH_THROW \
      , zend_exception_get_default(TSRMLS_C) TSRMLS_CC \
    )
#define PHPINI_EH_NORMAL php_std_error_handling()

#endif

PHP_METHOD(iniphile, __construct) // {{{
{
    char *path;
    int pathlen;
    PHPINI_EH_DECL;

    PHPINI_EH_THROWING;
    if (FAILURE == zend_parse_parameters(
        ZEND_NUM_ARGS() TSRMLS_CC
      , "s"
      , &path
      , &pathlen
    )) {
        PHPINI_EH_NORMAL;
        return;
    }
    PHPINI_EH_NORMAL;

    phpini *obj = PHPTHIS();
    try {
        obj->impl = new iniphile_bridge(path);
    } catch (std::exception &e) {
        zend_throw_exception_ex(
            zend_exception_get_default(TSRMLS_C)
          , 0 TSRMLS_CC
          , "'%s' could not be open"
          , path
        );
    }
} // }}}
PHP_METHOD(iniphile, path) // {{{
{
    phpini *obj = PHPTHIS();
    RETURN_STRING(estrdup(obj->impl->path().c_str()), 0);
} // }}}
PHP_METHOD(iniphile, get) // {{{
{
    phpini *obj = PHPTHIS();
    char *path;
    int path_len;
    zval *dflt;
    if (FAILURE == zend_parse_parameters(
        ZEND_NUM_ARGS() TSRMLS_CC
      , "sz"
      , &path
      , &path_len
      , &dflt
    )) {
        RETURN_NULL();
    }
    switch (Z_TYPE_P(dflt)) {
    case IS_BOOL:
        RETURN_BOOL(obj->impl->get(path, !!Z_LVAL_P(dflt)));
    case IS_LONG:
        RETURN_LONG(obj->impl->get(path, Z_LVAL_P(dflt)));
    case IS_DOUBLE:
        RETURN_DOUBLE(obj->impl->get(path, Z_DVAL_P(dflt)));
    case IS_STRING:
        RETURN_STRING(estrdup(obj->impl->get(path, std::string(Z_STRVAL_P(dflt))).c_str()), 0);
    case IS_ARRAY:
        get_strings(return_value, dflt, obj, path);
        break;
    default:
        PHPINI_THROW("Unsupported value type");
    }
} // }}}

function_entry iniphile_methods[] = // {{{
{
    PHP_ME(iniphile, __construct, 0, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(iniphile, path, 0, ZEND_ACC_PUBLIC)
    PHP_ME(iniphile, get, 0, ZEND_ACC_PUBLIC)
    {0, 0, 0}
}; // }}}

PHP_MINIT_FUNCTION(iniphile) // {{{
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "iniphile", iniphile_methods);
    iniphile_ce = zend_register_internal_class(&ce TSRMLS_CC);
    iniphile_ce->create_object = &iniphile_create_handler;
    memcpy(
        &iniphile_object_handlers
      , zend_get_std_object_handlers()
      , sizeof(zend_object_handlers)
    );
    iniphile_object_handlers.clone_obj = 0;

    return SUCCESS;
} // }}}

zend_module_entry iniphile_module_entry = // {{{
{
    STANDARD_MODULE_HEADER,
    PHP_INIPHILE_EXTNAME,
    0, // functions
    PHP_MINIT(iniphile),
    0, // MSHUTDOWN
    0, // RINIT
    0, // RSHUTDOWN
    0, // MINFO
    PHP_INIPHILE_EXTVER,
    STANDARD_MODULE_PROPERTIES
}; // }}}

#ifdef COMPILE_DL_INIPHILE
extern "C" {
ZEND_GET_MODULE(iniphile)
}
#endif
<|endoftext|>


<commit_before>/**
 * \file
 * \brief Scheduler class implementation
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-08-01
 */

#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/scheduler/idleThreadControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"

#include "distortos/distortosConfiguration.h"

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

Scheduler::Scheduler() :
		currentThreadControlBlock_{},
		runnableList_{ThreadControlBlock::State::Runnable},
		sleepingList_{ThreadControlBlock::State::Sleeping},
		tickCount_{0}
{

}

void Scheduler::add(ThreadControlBlock &thread_control_block)
{
	architecture::InterruptMaskingLock lock;
	runnableList_.sortedEmplace(thread_control_block);
}

uint64_t Scheduler::getTickCount() const
{
	architecture::InterruptMaskingLock lock;
	return tickCount_;
}

Scheduler::TimePoint Scheduler::getTimePoint() const
{
	using TickDuration = std::chrono::duration<TimePoint::duration::rep, std::ratio<1, CONFIG_TICK_RATE_HZ>>;

	const auto tick_count = getTickCount();
	const TickDuration duration {tick_count};
	const TimePoint time_point {duration};
	return time_point;
}

void Scheduler::sleepFor(const uint64_t ticks)
{
	sleepUntil(getTickCount() + ticks + 1);
}

void Scheduler::sleepUntil(const uint64_t tick_value)
{
	architecture::InterruptMaskingLock lock;

	getCurrentThreadControlBlock().setSleepUntil(tick_value);
	sleepingList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	yield();
}

void Scheduler::start()
{
	add(idleThreadControlBlock);

	currentThreadControlBlock_ = runnableList_.begin();

	architecture::startScheduling();
}

void * Scheduler::switchContext(void *stack_pointer)
{
	architecture::InterruptMaskingLock lock;

	getCurrentThreadControlBlock().getStack().setStackPointer(stack_pointer);

	// if the object is on the "runnable" list do the rotation - move current thread to the end of same-priority group
	// to implement round-robin scheduling
	if (getCurrentThreadControlBlock().getState() == ThreadControlBlock::State::Runnable)
		runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	currentThreadControlBlock_ = runnableList_.begin();

	return getCurrentThreadControlBlock().getStack().getStackPointer();
}

bool Scheduler::tickInterruptHandler()
{
	architecture::InterruptMaskingLock lock;

	++tickCount_;

	auto iterator = sleepingList_.begin();

	// wake all threads that reached their timeout
	while (iterator != sleepingList_.end() && iterator->get().getSleepUntil() <= tickCount_)
	{
		runnableList_.sortedSplice(sleepingList_, iterator);
		++iterator;
	}

	return isContextSwitchRequired_();
}

void Scheduler::yield() const
{
	if (isContextSwitchRequired_() == true)
		architecture::requestContextSwitch();
}

/*---------------------------------------------------------------------------------------------------------------------+
| private functions
+---------------------------------------------------------------------------------------------------------------------*/

bool Scheduler::isContextSwitchRequired_() const
{
	if (getCurrentThreadControlBlock().getState() != ThreadControlBlock::State::Runnable)
		return true;

	if (runnableList_.size() == 1)	// single thread available?
		return false;				// no context switch possible

	if (runnableList_.begin() != currentThreadControlBlock_)	// is there a higher-priority thread available?
		return true;

	const auto next_thread = ++runnableList_.begin();
	const auto next_thread_priority = next_thread->get().getPriority();
	if (getCurrentThreadControlBlock().getPriority() == next_thread_priority)	// next thread has the same priority?
		return true;	// switch context to do round-robin scheduling

	return false;
}

}	// namespace scheduler

}	// namespace distortos
<commit_msg>scheduler: fix loop that wakes sleeping threads in Scheduler::tickInterruptHandler() - after the transfer the iterator no longer points to the sleeping list<commit_after>/**
 * \file
 * \brief Scheduler class implementation
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2014-08-01
 */

#include "distortos/scheduler/Scheduler.hpp"

#include "distortos/scheduler/idleThreadControlBlock.hpp"

#include "distortos/architecture/InterruptMaskingLock.hpp"

#include "distortos/distortosConfiguration.h"

namespace distortos
{

namespace scheduler
{

/*---------------------------------------------------------------------------------------------------------------------+
| public functions
+---------------------------------------------------------------------------------------------------------------------*/

Scheduler::Scheduler() :
		currentThreadControlBlock_{},
		runnableList_{ThreadControlBlock::State::Runnable},
		sleepingList_{ThreadControlBlock::State::Sleeping},
		tickCount_{0}
{

}

void Scheduler::add(ThreadControlBlock &thread_control_block)
{
	architecture::InterruptMaskingLock lock;
	runnableList_.sortedEmplace(thread_control_block);
}

uint64_t Scheduler::getTickCount() const
{
	architecture::InterruptMaskingLock lock;
	return tickCount_;
}

Scheduler::TimePoint Scheduler::getTimePoint() const
{
	using TickDuration = std::chrono::duration<TimePoint::duration::rep, std::ratio<1, CONFIG_TICK_RATE_HZ>>;

	const auto tick_count = getTickCount();
	const TickDuration duration {tick_count};
	const TimePoint time_point {duration};
	return time_point;
}

void Scheduler::sleepFor(const uint64_t ticks)
{
	sleepUntil(getTickCount() + ticks + 1);
}

void Scheduler::sleepUntil(const uint64_t tick_value)
{
	architecture::InterruptMaskingLock lock;

	getCurrentThreadControlBlock().setSleepUntil(tick_value);
	sleepingList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	yield();
}

void Scheduler::start()
{
	add(idleThreadControlBlock);

	currentThreadControlBlock_ = runnableList_.begin();

	architecture::startScheduling();
}

void * Scheduler::switchContext(void *stack_pointer)
{
	architecture::InterruptMaskingLock lock;

	getCurrentThreadControlBlock().getStack().setStackPointer(stack_pointer);

	// if the object is on the "runnable" list do the rotation - move current thread to the end of same-priority group
	// to implement round-robin scheduling
	if (getCurrentThreadControlBlock().getState() == ThreadControlBlock::State::Runnable)
		runnableList_.sortedSplice(runnableList_, currentThreadControlBlock_);

	currentThreadControlBlock_ = runnableList_.begin();

	return getCurrentThreadControlBlock().getStack().getStackPointer();
}

bool Scheduler::tickInterruptHandler()
{
	architecture::InterruptMaskingLock lock;

	++tickCount_;

	// wake all threads that reached their timeout
	for (auto iterator = sleepingList_.begin();
			iterator != sleepingList_.end() && iterator->get().getSleepUntil() <= tickCount_;
			iterator = sleepingList_.begin())
		runnableList_.sortedSplice(sleepingList_, iterator);

	return isContextSwitchRequired_();
}

void Scheduler::yield() const
{
	if (isContextSwitchRequired_() == true)
		architecture::requestContextSwitch();
}

/*---------------------------------------------------------------------------------------------------------------------+
| private functions
+---------------------------------------------------------------------------------------------------------------------*/

bool Scheduler::isContextSwitchRequired_() const
{
	if (getCurrentThreadControlBlock().getState() != ThreadControlBlock::State::Runnable)
		return true;

	if (runnableList_.size() == 1)	// single thread available?
		return false;				// no context switch possible

	if (runnableList_.begin() != currentThreadControlBlock_)	// is there a higher-priority thread available?
		return true;

	const auto next_thread = ++runnableList_.begin();
	const auto next_thread_priority = next_thread->get().getPriority();
	if (getCurrentThreadControlBlock().getPriority() == next_thread_priority)	// next thread has the same priority?
		return true;	// switch context to do round-robin scheduling

	return false;
}

}	// namespace scheduler

}	// namespace distortos
<|endoftext|>


<commit_before>#include <VMDE/VMDE.hpp>

#ifndef _INCLUDE_TILES_H
#define _INCLUDE_TILES_H

namespace VM76 {
	class Tile {
	public:
		GDrawable* obj[6] = {NULL, NULL, NULL, NULL, NULL, NULL};

	private:
		GLfloat *vtx[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
		GLuint *itx[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
		glm::mat4 *mat = NULL;

	public:
		Tile(int tid);
		void render();
		void dispose();
	};
}

#endif
<commit_msg>.....<commit_after>#include "global.hpp"

#ifndef _INCLUDE_TILES_H
#define _INCLUDE_TILES_H

namespace VM76 {
	class Tile {
	public:
		GDrawable* obj[6] = {NULL, NULL, NULL, NULL, NULL, NULL};

	private:
		GLfloat *vtx[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
		GLuint *itx[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
		glm::mat4 *mat = NULL;

	public:
		Tile(int tid);
		void render();
		void dispose();
	};
}

#endif
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * Copyright 2011 Intel corporation
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

#include <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>

#include "cli.hpp"

#include "os_string.hpp"

#include "trace_callset.hpp"
#include "trace_parser.hpp"
#include "trace_writer.hpp"

static const char *synopsis = "Create a new trace by trimming an existing trace.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace trim [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help               show this help message and exit\n"
        "        --calls=CALLSET      only retain specified calls\n"
        "        --thread=THREAD_ID   only retain calls from specified thread\n"
        "    -o, --output=TRACE_FILE  output trace file\n"
        "\n"
    ;
}

enum {
    CALLS_OPT = CHAR_MAX + 1,
    THREAD_OPT,
};

const static char *
shortOptions = "ho:";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"calls", required_argument, 0, CALLS_OPT},
    {"thread", required_argument, 0, THREAD_OPT},
    {"output", required_argument, 0, 'o'},
    {0, 0, 0, 0}
};

static int
command(int argc, char *argv[])
{
    std::string output;
    trace::CallSet calls(trace::FREQUENCY_ALL);
    int thread = -1;
    int i;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case CALLS_OPT:
            calls = trace::CallSet(optarg);
            break;
        case THREAD_OPT:
            thread = atoi(optarg);
            break;
        case 'o':
            output = optarg;
            break;
        default:
            std::cerr << "error: unexpected option `" << opt << "`\n";
            usage();
            return 1;
        }
    }

    if (optind >= argc) {
        std::cerr << "error: apitrace trim requires a trace file as an argument.\n";
        usage();
        return 1;
    }

    for (i = optind; i < argc; ++i) {
        trace::Parser p;
        if (!p.open(argv[i])) {
            return 1;
        }

        if (output.empty()) {
            os::String base(argv[i]);
            base.trimExtension();

            output = std::string(base.str()) + std::string("-trim.trace");
        }

        trace::Writer writer;
        if (!writer.open(output.c_str())) {
            std::cerr << "error: failed to create " << argv[i] << "\n";
            return 1;
        }

        trace::Call *call;
        while ((call = p.parse_call())) {
            if (calls.contains(*call) &&
                (thread == -1 || call->thread_id == thread)) {
                writer.writeCall(call);
            }
            delete call;
        }

        std::cout << "Trimmed trace is available as " << output << "\n";
    }

    return 0;
}

const Command trim_command = {
    "trim",
    synopsis,
    usage,
    command
};
<commit_msg>trim: Add framework for performing dependency analysis while trimming<commit_after>/**************************************************************************
 *
 * Copyright 2010 VMware, Inc.
 * Copyright 2011 Intel corporation
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

#include <string.h>
#include <limits.h> // for CHAR_MAX
#include <getopt.h>

#include <set>

#include "cli.hpp"

#include "os_string.hpp"

#include "trace_callset.hpp"
#include "trace_parser.hpp"
#include "trace_writer.hpp"

static const char *synopsis = "Create a new trace by trimming an existing trace.";

static void
usage(void)
{
    std::cout
        << "usage: apitrace trim [OPTIONS] TRACE_FILE...\n"
        << synopsis << "\n"
        "\n"
        "    -h, --help               Show this help message and exit\n"
        "        --calls=CALLSET      Include specified calls in the trimmed output\n"
        "        --deps               Perform dependency analysis and include dependent\n"
        "                             calls as needed. This is the default behavior.\n"
        "        --no-deps            Do not perform dependency analysis. Include only\n"
        "                             those calls explicitly listed in --calls\n"
        "        --thread=THREAD_ID   Only retain calls from specified thread\n"
        "    -o, --output=TRACE_FILE  Output trace file\n"
        "\n"
    ;
}

enum {
    CALLS_OPT = CHAR_MAX + 1,
    DEPS_OPT,
    NO_DEPS_OPT,
    THREAD_OPT,
};

const static char *
shortOptions = "ho:";

const static struct option
longOptions[] = {
    {"help", no_argument, 0, 'h'},
    {"calls", required_argument, 0, CALLS_OPT},
    {"deps", no_argument, 0, DEPS_OPT},
    {"no-deps", no_argument, 0, NO_DEPS_OPT},
    {"thread", required_argument, 0, THREAD_OPT},
    {"output", required_argument, 0, 'o'},
    {0, 0, 0, 0}
};

struct stringCompare {
    bool operator() (const char *a, const char *b) const {
        return strcmp(a, b) < 0;
    }
};

class TraceAnalyzer {
    /* Map for tracking resource dependencies between calls. */
    std::map<const char *, std::set<unsigned>, stringCompare > resources;

    /* The final set of calls required. This consists of calls added
     * explicitly with the require() method as well as all calls
     * implicitly required by those through resource dependencies. */
    std::set<unsigned> required;

public:
    TraceAnalyzer() {}
    ~TraceAnalyzer() {}

    /* Compute and record all the resources provided by this call. */
    void analyze(trace::Call *call) {
        resources["state"].insert(call->no);
    }

    /* Require this call and all of its dependencies to be included in
     * the final trace. */
    void require(trace::Call *call) {
        std::set<unsigned> *dependencies;
        std::set<unsigned>::iterator i;

        /* First, find and insert all calls that this call depends on. */
        dependencies = &resources["state"];
        for (i = dependencies->begin(); i != dependencies->end(); i++) {
            required.insert(*i);
        }
        resources["state"].clear();

        /* Then insert this call itself. */
        required.insert(call->no);
    }

    /* Return a set of all the required calls, (both those calls added
     * explicitly with require() and those implicitly depended
     * upon. */
    std::set<unsigned> *get_required(void) {
        return &required;
    }
};

struct trim_options {
    /* Calls to be included in trace. */
    trace::CallSet calls;

    /* Whether dependency analysis should be performed. */
    bool dependency_analysis;

    /* Output filename */
    std::string output;

    /* Emit only calls from this thread (-1 == all threads) */
    int thread;
};

static int
trim_trace(const char *filename, struct trim_options *options)
{
    trace::ParseBookmark beginning;
    trace::Parser p;
    TraceAnalyzer analyzer;
    std::set<unsigned> *required;

    if (!p.open(filename)) {
        std::cerr << "error: failed to open " << filename << "\n";
        return 1;
    }

    /* Mark the beginning so we can return here for pass 2. */
    p.getBookmark(beginning);

    /* In pass 1, analyze which calls are needed. */
    trace::Call *call;
    while ((call = p.parse_call())) {
        /* If requested, ignore all calls not belonging to the specified thread. */
        if (options->thread != -1 && call->thread_id != options->thread)
            continue;

        /* If this call is included in the user-specified call
         * set, then we don't need to perform any analysis on
         * it. We know it must be included. */
        if (options->calls.contains(*call)) {
            analyzer.require(call);
        } else {
            if (options->dependency_analysis)
                analyzer.analyze(call);
        }
    }

    /* Prepare output file and writer for output. */
    if (options->output.empty()) {
        os::String base(filename);
        base.trimExtension();

        options->output = std::string(base.str()) + std::string("-trim.trace");
    }

    trace::Writer writer;
    if (!writer.open(options->output.c_str())) {
        std::cerr << "error: failed to create " << filename << "\n";
        return 1;
    }

    /* Reset bookmark for pass 2. */
    p.setBookmark(beginning);

    /* In pass 2, emit the calls that are required. */
    required = analyzer.get_required();

    while ((call = p.parse_call())) {
        if (required->find(call->no) != required->end()) {
            writer.writeCall(call);
        }
        delete call;
    }

    std::cout << "Trimmed trace is available as " << options->output << "\n";

    return 0;
}

static int
command(int argc, char *argv[])
{
    struct trim_options options;

    options.calls = trace::CallSet(trace::FREQUENCY_ALL);
    options.dependency_analysis = true;
    options.output = "";
    options.thread = -1;

    int opt;
    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case CALLS_OPT:
            options.calls = trace::CallSet(optarg);
            break;
        case DEPS_OPT:
            options.dependency_analysis = true;
            break;
        case NO_DEPS_OPT:
            options.dependency_analysis = false;
            break;
        case THREAD_OPT:
            options.thread = atoi(optarg);
            break;
        case 'o':
            options.output = optarg;
            break;
        default:
            std::cerr << "error: unexpected option `" << opt << "`\n";
            usage();
            return 1;
        }
    }

    if (optind >= argc) {
        std::cerr << "error: apitrace trim requires a trace file as an argument.\n";
        usage();
        return 1;
    }

    return trim_trace(argv[optind], &options);
}

const Command trim_command = {
    "trim",
    synopsis,
    usage,
    command
};
<|endoftext|>


<commit_before>#include <ap_int.h>
#include "spbits.h"
#include "match_seg.h"
using namespace std;
#define add if(this->pr==1)

void match_seg::find_segment_n1_62(
		 ap_uint<bpow+1> ph_pat_p, // ph detected in pattern
		 ap_uint<6> ph_pat_q_p, // pattern valid

		 /* ph from segments [bx_history][chamber][segment]segments are coming from
		  chambers in the interesting zone onlyfor example, in zone 0 ME1 segments
		  should come from chambers subsector1: 1,2,3, subsector2: 1,2,3*/
		 ap_uint<bw_fph> ph_seg_p[max_drift][zone_cham][seg_ch],

		 // valid flags for segments
		 ap_uint<seg_ch> ph_seg_v_p[max_drift][zone_cham],
		 ap_uint<bw_th> th_seg_p[max_drift][zone_cham][zone_seg],
		 ap_uint<4> cpat_seg_p[max_drift][zone_cham][seg_ch],

		 // indexes of best match
		 ap_uint<seg_ch> *vid, // match valid, each flag shows validity of th coord
		 ap_uint<2> *hid, // history id
		 ap_uint<3> *cid, // chamber id
		 ap_uint<1> *sid, // segment id
		 ap_uint<bw_fph> *ph_match, // ph from matching segment

		 // all th's from matching chamber, we don't know which one will fit best
		 ap_uint<bw_th> th_match[zone_seg],
		 ap_uint<4> *cpat_match // pattern from matching segment
		)
{
#pragma HLS ARRAY_PARTITION variable=th_match complete dim=0
#pragma HLS ARRAY_PARTITION variable=cpat_seg_p complete dim=0
#pragma HLS ARRAY_PARTITION variable=th_seg_p complete dim=0
#pragma HLS ARRAY_PARTITION variable=ph_seg_v_p complete dim=0
#pragma HLS ARRAY_PARTITION variable=ph_seg_p complete dim=0

   const int tot_diff = max_drift*6/*zone_cham*/*seg_ch;
   const int max_ph_diff=7;
   const int bw_phdiff=4;
   const int nodiff=15;

	int i,j,k,di;
	ap_uint<bpow+1> ph_pat; // ph detected in pattern
	ap_uint<1> ph_pat_v; // pattern valid
	ap_uint<bw_fph> ph_seg [max_drift][zone_cham][seg_ch];
	ap_uint<seg_ch> ph_seg_v [max_drift][zone_cham];
	ap_uint<bw_th> th_seg [max_drift][zone_cham][zone_seg];
	ap_uint<4> cpat_seg [max_drift][zone_cham][seg_ch];
	ap_uint<bpow+1> ph_segr;
	ap_uint<bpow+1> ph_diff_tmp;
	ap_uint<bw_phdiff> ph_diff [tot_diff];
	ap_uint<2> rcomp;

	ap_uint<6> diffi0 [tot_diff];
	ap_uint<bw_phdiff> cmp1 [tot_diff/3];
	ap_uint<6> diffi1 [tot_diff/3];
	ap_uint<bw_phdiff> cmp2 [tot_diff/9];
	ap_uint<6> diffi2 [tot_diff/9];
	ap_uint<bw_phdiff> cmp3 [tot_diff/18];
	ap_uint<6> diffi3 [tot_diff/18];
	ap_uint<bw_phdiff> cmp4;
	ap_uint<6> diffi4;
	ap_uint<2> ri;
	ap_uint<3> rj;
	ap_uint<1> rk;

	 ap_uint<seg_ch> a_vid; // match valid, each flag shows validity of th coord
	 ap_uint<2> a_hid; // history id
	 ap_uint<3> a_cid; // chamber id
	 ap_uint<1> a_sid;

/*for(int i=0;i<3;i++){
	for(int j=0;j<3zone_cham;j++){
		for(int k=0;k<2zone_seg;k++){
			  cout<<hex<<"th_seg_p["<<i<<"]["<<j<<"]["<<k<<"]= "<<th_seg_p[i][j][k]<<hex<<endl;
		}

	}
}*/
	 if(this->pr==1){
	 cout<<"ph_pat_p= "<<ph_pat_p<<endl;
	 cout<<"ph_pat_q_p= "<<ph_pat_q_p<<endl;
	 for(int i=0;i<3;i++){
	 	for(int j=0;j<6/*zone_cham*/;j++){
	 		for(int k=0;k<2;k++){
	 			  cout<<hex<<"ph_seg_p["<<i<<"]["<<j<<"]["<<k<<"]= "<<ph_seg_p[i][j][k]<<hex<<endl;
	 		}

	 	}
	 }
	 }
	 ph_pat = ph_pat_p;
	 	ph_pat_v = ph_pat_q_p != 0; // non-zero quality means valid pattern
	 	find_segment_st1_label0:for(int i=0;i<max_drift;i++){
	 #pragma HLS UNROLL
	 		find_segment_st1_label1:for(int j=0;j<6/*zone_cham*/;j++){
	 #pragma HLS UNROLL
	 			find_segment_st1_label2:for(int k=0;k<seg_ch;k++){
	 #pragma HLS UNROLL
	 				ph_seg[i][j][k] = ph_seg_p[i][j][k];
	 			}

	 			ph_seg_v[i][j] = ph_seg_v_p[i][j];
	 			find_segment_st1_label3:for(int k=0;k<2/*zone_seg*/;k++){
	 #pragma HLS UNROLL
	 				th_seg[i][j][k] = th_seg_p[i][j][k];
					  if(this->pr==1 && ph_pat_p==0x49){
										  //for(int i=0;i<36;i++){
		//  cout<<"th_seg_p["<<i<<"]["<<j<<"]["<<k<<"]= "<<th_seg_p[i][j][k]<<hex<<endl;
					  }
	 			}
	 			find_segment_st1_label4:for(int k=0;k<seg_ch;k++){
	 #pragma HLS UNROLL
	 				cpat_seg[i][j][k] = cpat_seg_p[i][j][k];
	 			}
	 		}
	 	}

	 	// calculate abs differences
	 	di = 0;
	 	find_segment_st1_label5:for (i = 0; i < max_drift; i = i+1){ // history loop
	 #pragma HLS UNROLL
	 		find_segment_st1_label6:for (j = 0; j < 6/*zone_cham*/; j = j+1){ // chamber loop
	 #pragma HLS UNROLL
	 			find_segment_st1_label7:for (k = 0; k < seg_ch; k = k+1){ // segment loop
	 #pragma HLS UNROLL
	 				// remove unused low bits from segment ph
	 				ph_segr = ph_seg[i][j][k](bw_fph-1 , bw_fph-bpow-1);

	 				// get abs difference
	 				if (ph_seg_v[i][j][k])
	 					    ph_diff_tmp = (ph_pat > ph_segr) ? ph_pat - ph_segr : ph_segr - ph_pat;
	 				else
	 					ph_diff_tmp = nodiff; // if segment invalid put max value into diff

	 			    if((ph_diff_tmp) > (max_ph_diff))
	 					    ph_diff[i*6/*zone_cham*/*seg_ch + j*seg_ch + k] = nodiff; // difference is too high, cannot be the same pattern
	 			    else
	 			 	    ph_diff[i*6/*zone_cham*/*seg_ch + j*seg_ch + k] = ph_diff_tmp(bw_phdiff-1,0);

	 				ri = i;
	 				rj = j;
	 				rk = k;
	 				// diffi variables carry track indexes
	 				diffi0[i*6/*zone_cham*/*seg_ch + j*seg_ch + k] = (ri, rj, rk);
	 			}
	 		}
	 	} // for (i = 0; i < max_drift; i = i+1)

	 	/*************sort differences*****************/
	 			// first stage
	 			find_segment_st1_label8:for (i = 0; i < tot_diff/3; i = i+1){
	 #pragma HLS UNROLL			// compare 3 values
	 				rcomp = comp3(ph_diff[i*3], ph_diff[i*3+1], ph_diff[i*3+2]);
	 				// fill outputs
	 				switch(rcomp){
	 				case 0: cmp1[i] = ph_diff[i*3+0]; diffi1[i] = diffi0[i*3+0];
	 						break;
	 				case 1: cmp1[i] = ph_diff[i*3+1]; diffi1[i] = diffi0[i*3+1];
	 						break;
	 				case 2: cmp1[i] = ph_diff[i*3+2]; diffi1[i] = diffi0[i*3+2];
	 						break;
	 				default: break;
	 				}
	 			}

	 			// second stage
	 			find_segment_st1_label9:for (i = 0; i < tot_diff/9; i = i+1){
	 #pragma HLS UNROLL	// compare 3 values
	 				rcomp = comp3(cmp1[i*3], cmp1[i*3+1], cmp1[i*3+2]);
	 				// fill outputs
	 				switch(rcomp){
	 				case 0: cmp2[i] = cmp1[i*3+0]; diffi2[i] = diffi1[i*3+0];
	 						break;
	 				case 1: cmp2[i] = cmp1[i*3+1]; diffi2[i] = diffi1[i*3+1];
	 						break;
	 				case 2: cmp2[i] = cmp1[i*3+2]; diffi2[i] = diffi1[i*3+2];
	 						break;
	 				default: break;
	 				}
	 			}

	 			// third stage
	 			find_segment_st1_label10:for (i = 0; i < tot_diff/18; i = i+1){
	 #pragma HLS UNROLL	// compare 2 values
	 				rcomp[0] = cmp2[i*2] >= cmp2[i*2+1];
	 				// fill outputs
	 				switch(int(rcomp[0])){
	 				case 0: cmp3[i] = cmp2[i*2+0]; diffi3[i] = diffi2[i*2+0];
	 						break;
	 				case 1: cmp3[i] = cmp2[i*2+1]; diffi3[i] = diffi2[i*2+1];
	 						break;
	 				default: break;
	 				}
	 			}
	 			// last stage depends on number of input segments
	 			if (tot_diff == 36)
	 			{
	 				// compare 2 values
	 				rcomp[0] = cmp3[0] >= cmp3[1];
	 				// fill outputs
	 				switch(int(rcomp[0])){
	 				case 0: cmp4 = cmp3[0]; diffi4 = diffi3[0];
	 						break;
	 				case 1: cmp4 = cmp3[1]; diffi4 = diffi3[1];
	 						break;
	 				default: break;
	 				}
	 			}
	 			else
	 			{
	 				cmp4 = cmp3[0];
	 				diffi4 = diffi3[0];
	 			}

	 			a_hid=diffi4(5,4);
	 			a_cid=diffi4(3,1);
	 			a_sid = diffi4[0];
	 			a_vid = ph_seg_v[a_hid][a_cid][a_sid];

	 			// if pattern invalid or all differences invalid remove valid flags
	 			if (!ph_pat_v || cmp4 == nodiff) a_vid = 0;

	 			*ph_match = ph_seg[a_hid][a_cid][a_sid]; // route best matching phi to output

	 			find_segment_st1_label11:for(int i=0;i<2/*zone_seg*/;i++)
	 			{
	 			#pragma HLS UNROLL
	 				th_match[i] = th_seg[a_hid][a_cid][i]; // route all th coords from matching chamber to output
	 			}

	 			*cpat_match = cpat_seg[a_hid][a_cid][a_sid]; // route pattern to output
	 			*hid=a_hid;
	 			*cid=a_cid;
	 			*sid=a_sid;
	 			*vid=a_vid;

	 }
<commit_msg>Delete find_segment_n1_62.cpp<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef ITEM_HH
#define ITEM_HH
#include "config.h"
#include "mutex.hh"
#include <string>
#include <string.h>
#include <stdio.h>
#include <memcached/engine.h>

/**
 * The Item structure we use to pass information between the memcached
 * core and the backend. Please note that the kvstore don't store these
 * objects, so we do have an extra layer of memory copying :(
 */
class Item {
public:
    Item() {
        initialize("", 0, 0, NULL, 0, 0);
    }

    Item(const void* k, const size_t nk, const size_t nb,
         const int fl, const rel_time_t exp)
    {
        std::string _k(static_cast<const char*>(k), nk);
        initialize(_k, fl, exp, NULL, nb, 0);
    }

    Item(const void* k, const size_t nk, const size_t nb,
         const int fl, const rel_time_t exp, uint64_t theCas)
    {
        std::string _k(static_cast<const char*>(k), nk);
        initialize(_k, fl, exp, NULL, nb, theCas);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb)
    {
        initialize(k, fl, exp, static_cast<const char*>(dta), nb, 0);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas)
    {
        initialize(k, fl, exp, static_cast<const char*>(dta), nb, theCas);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const std::string &val)
    {
        initialize(k, fl, exp, val.c_str(), val.size(), 0);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const std::string &val, uint64_t theCas)
    {
        initialize(k, fl, exp, val.c_str(), val.size(), theCas);
    }

    Item(const void *k, uint16_t nk, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb) :
        key(static_cast<const char*>(k), nk)
    {
        std::string _k(static_cast<const char*>(k), nk);
        initialize(_k, fl, exp, static_cast<const char*>(dta), nb, 0);
    }

    Item(const void *k, uint16_t nk, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas) :
        key(static_cast<const char*>(k), nk)
    {
        std::string _k(static_cast<const char*>(k), nk);
        initialize(_k, fl, exp, static_cast<const char*>(dta), nb, theCas);
    }

    ~Item() {
        delete []data;
    }

    Item(const Item &itm) {
        initialize(itm.key, itm.flags, itm.exptime, itm.data, itm.nbytes, itm.cas);
    }

    Item* clone() {
        return new Item(key, flags, exptime, data, nbytes, cas);
    }

    char *getData() {
        return data;
    }

    const std::string &getKey() const {
        return key;
    }

    int getNKey() const {
        return key.length();
    }

    uint32_t getNBytes() const {
        return nbytes;
    }

    rel_time_t getExptime() const {
        return exptime;
    }

    int getFlags() const {
        return flags;
    }

    uint64_t getCas() const {
        return cas;
    }

    void setCas() {
        cas = nextCas();
    }

    void setCas(uint64_t ncas) {
        cas = ncas;
    }

private:
    /**
     * Initialize all of the members in this object. Unfortunately the items
     * needs to end with "\r\n". Initialize adds this sequence if you pass
     * data along and append this sequence.
     */
    void initialize(const std::string &k, const int fl, const rel_time_t exp,
                    const char *dta, const size_t nb, uint64_t theCas)
    {
        key.assign(k);
        nbytes = static_cast<uint32_t>(nb);
        flags = fl;
        exptime = exp;
        cas = theCas;

        if (dta != NULL) {
            if (nbytes < 2 || memcmp(dta + nb - 2, "\r\n", 2) != 0) {
                nbytes += 2;
            }
        }

        if (nbytes > 0) {
            data = new char[nbytes];
        } else {
            data = NULL;
        }

        if (data && dta) {
            memcpy(data, dta, nbytes);
            if (nb != nbytes) {
                memcpy(data + nb, "\r\n", 2);
            }
        }
    }

    int flags;
    rel_time_t exptime;
    uint32_t nbytes;
    std::string key;
    char *data;
    uint64_t cas;

    static uint64_t nextCas(void) {
        uint64_t ret;
        casMutex.aquire();
        ret = casCounter++;
        casMutex.release();
        if ((ret % casNotificationFrequency) == 0) {
            casNotifier(ret);
        }

        return ret;
    }

    static void initializeCas(uint64_t initial, void (*notifier)(uint64_t current), uint64_t frequency) {
        casCounter = initial;
        casNotifier = notifier;
        casNotificationFrequency = frequency;
    }

    static uint64_t casNotificationFrequency;
    static void (*casNotifier)(uint64_t);
    static uint64_t casCounter;
    static Mutex casMutex;
};

#endif
<commit_msg>Refactor Item constructors.<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef ITEM_HH
#define ITEM_HH
#include "config.h"
#include "mutex.hh"
#include <string>
#include <string.h>
#include <stdio.h>
#include <memcached/engine.h>

/**
 * The Item structure we use to pass information between the memcached
 * core and the backend. Please note that the kvstore don't store these
 * objects, so we do have an extra layer of memory copying :(
 */
class Item {
public:
    Item() : flags(0), exptime(0), cas(0)
    {
        key.assign("");
        setData(NULL, 0);
    }

    Item(const void* k, const size_t nk, const size_t nb,
         const int fl, const rel_time_t exp, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(NULL, nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const std::string &val, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(val.c_str(), val.size());
    }

    Item(const void *k, uint16_t nk, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const Item &itm) : flags(itm.flags), exptime(itm.exptime), cas(itm.cas)
    {
        key.assign(itm.key);
        setData(itm.data, itm.nbytes);
    }

    ~Item() {
        delete []data;
    }

    Item* clone() {
        return new Item(key, flags, exptime, data, nbytes, cas);
    }

    char *getData() {
        return data;
    }

    const std::string &getKey() const {
        return key;
    }

    int getNKey() const {
        return key.length();
    }

    uint32_t getNBytes() const {
        return nbytes;
    }

    rel_time_t getExptime() const {
        return exptime;
    }

    int getFlags() const {
        return flags;
    }

    uint64_t getCas() const {
        return cas;
    }

    void setCas() {
        cas = nextCas();
    }

    void setCas(uint64_t ncas) {
        cas = ncas;
    }

private:
    /**
     * Set the item's data. This is only used by constructors, so we
     * make it private.
     */
    void setData(const char *dta, const size_t nb) {
        nbytes = static_cast<uint32_t>(nb);

        if (dta != NULL) {
            if (nbytes < 2 || memcmp(dta + nb - 2, "\r\n", 2) != 0) {
                nbytes += 2;
            }
        }

        if (nbytes > 0) {
            data = new char[nbytes];
        } else {
            data = NULL;
        }

        if (data && dta) {
            memcpy(data, dta, nbytes);
            if (nb != nbytes) {
                memcpy(data + nb, "\r\n", 2);
            }
        }
    }

    int flags;
    rel_time_t exptime;
    uint32_t nbytes;
    std::string key;
    char *data;
    uint64_t cas;

    static uint64_t nextCas(void) {
        uint64_t ret;
        casMutex.aquire();
        ret = casCounter++;
        casMutex.release();
        if ((ret % casNotificationFrequency) == 0) {
            casNotifier(ret);
        }

        return ret;
    }

    static void initializeCas(uint64_t initial, void (*notifier)(uint64_t current), uint64_t frequency) {
        casCounter = initial;
        casNotifier = notifier;
        casNotificationFrequency = frequency;
    }

    static uint64_t casNotificationFrequency;
    static void (*casNotifier)(uint64_t);
    static uint64_t casCounter;
    static Mutex casMutex;
};

#endif
<|endoftext|>