diff --git a/buildall.bat b/buildall.bat deleted file mode 100644 index cacdbc5..0000000 --- a/buildall.bat +++ /dev/null @@ -1,5 +0,0 @@ -REM MS yo me cago en tus putisimos muertos que cojones es este bug centenario estupido y miserable con los parametros? -REM este comentario es de cuando me lo encontre hace rato, pero me hace gracia, asi que se queda - -CALL buildlib.bat -CALL buildtest.bat diff --git a/builddall.bat b/builddall.bat deleted file mode 100644 index 122e1ea..0000000 --- a/builddall.bat +++ /dev/null @@ -1,5 +0,0 @@ -REM MS yo me cago en tus putisimos muertos que cojones es este bug centenario estupido y miserable con los parametros? -REM este comentario es de cuando me lo encontre hace rato, pero me hace gracia, asi que se queda - -CALL builddlib.bat -CALL builddtest.bat diff --git a/builddlib.bat b/builddlib.bat deleted file mode 100644 index e69d0df..0000000 --- a/builddlib.bat +++ /dev/null @@ -1,3 +0,0 @@ -clang++ -DDEBUG -D_DEBUG -shared src\tmrtsc.cpp -o build\libtmrtscd.dll -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -Wl,-Bstatic -l c++ -l unwind --verbose - -REM -lmsvcrt -lucrtbase -lvcruntime140_app diff --git a/builddtest.bat b/builddtest.bat deleted file mode 100644 index e729880..0000000 --- a/builddtest.bat +++ /dev/null @@ -1,4 +0,0 @@ -clang++ -DDEBUG -D_DEBUG -dynamic src\test\test.cpp -o build\testd.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -L D:\Contenido\Capybara\Cositas\tmr\build -Wl,-Bstatic -l c++ -l unwind -Wl,-Bdynamic -l tmrtsc --verbose - -REM -fms-runtime-lib dll_dbgx -REM -lmsvcrt -lucrtbase -lvcruntime140_app diff --git a/buildlib.bat b/buildlib.bat index 8c6000b..9397441 100644 --- a/buildlib.bat +++ b/buildlib.bat @@ -1,2 +1 @@ -clang++ -shared src\tmrtsc.cpp -o build\libtmrtsc.dll -Wall -Wextra -Wpedantic -std=c++11 -L C:\capybara\libclang\x86_64-w64-mingw32\bin -Wl,-Bstatic -l c++ -l unwind --verbose - +clang++ -D DEBUG src\tmrtsc.hpp -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -l c++ -l unwind --verbose diff --git a/buildtest.bat b/buildtest.bat deleted file mode 100644 index 3ea2ae5..0000000 --- a/buildtest.bat +++ /dev/null @@ -1 +0,0 @@ -clang++ -dynamic src\test\test.cpp -o build\test.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\capybara\libclang\x86_64-w64-mingw32\bin -L D:\Contenido\Capybara\Cositas\tmr\build -Wl,-Bstatic -l c++ -l unwind -Wl,-Bdynamic -l tmrtsc --verbose \ No newline at end of file diff --git a/src/test/test.cpp b/src/test/test.cpp deleted file mode 100644 index 1587e16..0000000 --- a/src/test/test.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifdef _WIN64 - #define UNICODE - #define WIN32_LEAN_AND_MEAN - #define DllImport __declspec( dllimport ) - #define _MT - #define _DLL - #include - #include -#endif - -#include "../debug.h" -#include "../tmrtsc.hpp" - -using namespace tmr; - -#ifdef _WIN64 -int main(int argc, char** argv){ - HMODULE dell; - DWORD fracaso; - //DllImport TSCTimer* timer; - int sleep = 1000; - - /* - * dell = LoadLibraryExW(TEXT("libtmrtsc.dll"), NULL, NULL); - * if (dell == NULL) { - * fracaso = GetLastError(); - * return -1; - * } - */ - TSCTimer* timer = nullptr; - timer = TSCTimer::getTimer(); - if(timer == nullptr) - return -2; - uint64_t t1 = timer->getTimeStamp(); - Sleep(sleep); - uint64_t t2 = timer->getTimeStamp(); - uint64_t fr = timer->getBaseFrequency(); - std::cout << "Siestecita de: " << sleep << " ms" << std::endl; - std::cout << "Windows Momento: \nt1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; - std::cout << "restita: " << t2-t1 << std::endl; - return 0; -} - -#else -int main(int argc, char** argv){ - return -9; -} -#endif diff --git a/src/tmrtsc.cpp b/src/tmrtsc.cpp deleted file mode 100644 index aacffde..0000000 --- a/src/tmrtsc.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//TODO juntar heaps? -#include "tmrtsc.hpp" - -#if _WIN64 - extern "C" { -#endif - -namespace tmr { - - TSCTimer::TSCTimer(char* vendorName, int64_t baseFreq) { - this->vendorName = vendorName; - this->baseFreq = baseFreq; - this->availableRDTSCP = (checkRDTSCP()) ? true : false; - } - - TSCTimer::~TSCTimer () { - free(vendorName); - } - - bool TSCTimer::checkInvariantTSC() { - uint64_t rdx; - asm volatile (".intel_syntax noprefix\t\n" \ - "mov eax, 0x80000007\t\n" \ - "cpuid\t\n" : "=d" (rdx) ); - bool iTSC = rdx & (1<<8); - return iTSC; - } - - - char* TSCTimer::readVendorName () { - char* palabritas = (char*)malloc(sizeof(char) * 13); - uint8_t siguienteLetra = 0; - uint64_t regs[3]; - asm volatile ( ".intel_syntax noprefix\t\n" \ - "mov eax, 0x0\t\n" \ - "cpuid\t\n" : "=b" (regs[0]), "=c" (regs[2]), "=d" (regs[1]) ); - int byte = 0; - for (int reg = 0; reg < 3; reg++, byte = 0){ - char* charifiedReg = (char*)®s[reg]; - for(; byte < 4; byte++, siguienteLetra++ ){ - palabritas[siguienteLetra] = charifiedReg[byte]; - } - } - palabritas[siguienteLetra] = '\0'; - return palabritas; - } - - int64_t TSCTimer::intelRetrieveART(){ - //TODO: Find a valid Intel CPU to debug ART route - //if (freq == nullptr) return - - - uint64_t raxde, rbxnum, rcxhz; - asm volatile ( ".intel_syntax noprefix\t\n" \ - "mov eax, 0x15\t\n" \ - "cpuid\t\n" : "=a" (raxde), "=b" (rbxnum), "=c" (rcxhz) ); - log_debugcpp("hmm " << raxde << " " << rbxnum << " " << rcxhz); - if (rbxnum == 0 || rcxhz == 0) return ART_NOT_REPORTED; - int64_t TSCFreq = (rcxhz * rbxnum)/raxde; - //*freq = TSCFreq; - log_debugcpp("raxo " << TSCFreq << " " << TSCFreq); - return TSCFreq; - } - - #ifdef _WIN64 - - int64_t TSCTimer::getFreqFromSystem(){ - //TODO: close opened key - const WORD STRING_SIZE = 4; - const WCHAR COMPARE_TARGET[STRING_SIZE + 1] = L"~MHz"; - DWORD longestDataSize; - - LSTATUS status; - HKEY key; - DWORD numValues; - - WCHAR valName[MAX_VALUE_NAME]; //uint32_t wtf - DWORD valLen = MAX_VALUE_NAME; - - LPBYTE dataContent = nullptr; - DWORD dataLen; - - status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, - KEY_QUERY_VALUE, &key); - if(status != ERROR_SUCCESS) return CANT_OPEN_KEY; - - status = RegQueryInfoKey( - key, // key handle - NULL, // buffer for class name - NULL, // size of class string - NULL, // reserved - NULL, // num of subkeys - NULL, // longest subkey size - NULL, // longest class string - &numValues, // num of values for this key - NULL, // longest value name - &longestDataSize, // longest value data - NULL, // security descriptor - NULL); // last write time - if(status != ERROR_SUCCESS) return CANT_RETRIEVE_KEY_INFO; - - dataLen = sizeof(REG_QWORD) * (longestDataSize); - dataContent = (LPBYTE)malloc(dataLen); - for (DWORD i = 0; i < numValues; i++){ - valLen = MAX_VALUE_NAME; - dataLen = sizeof(REG_QWORD) * (longestDataSize); - status = RegEnumValueW(key, - i, - valName, - &valLen, - NULL, - NULL, - dataContent, - &dataLen - ); - - if(status != ERROR_SUCCESS) return CANT_READ_DATA_FROM_VALUE; - - if (CSTR_EQUAL == CompareStringEx( - LOCALE_NAME_INVARIANT, - NORM_LINGUISTIC_CASING, - valName, - valLen, - COMPARE_TARGET, - STRING_SIZE, - NULL, - NULL, - 0 - ) - ) { - LPDWORD PMHz = (LPDWORD)dataContent; - DWORD MHz = *PMHz; - free(dataContent); - return MHz * 1000000; - } - } - return CANT_READ_DATA_FROM_VALUE; - } - - #endif - - bool TSCTimer::checkRDTSCP(){ //Generic - uint64_t rdx; - asm volatile (".intel_syntax noprefix\t\n" \ - "mov eax, 0x80000001\t\n" \ - // 080000007h\t\n" - "cpuid\t\n" : "=d" (rdx) ); - bool RDTSCP = rdx & (1<<27); - //"and edx, 10000000\n") - return RDTSCP; - } - - uint64_t TSCTimer::readRDTSC() { - uint64_t raxlo,rdxho; - asm volatile ( ".intel_syntax noprefix\t\n" - "lfence\n" \ - "rdtsc\n" \ - "lfence\n" : "=a" (raxlo), "=d" (rdxho)); - return (rdxho << 32) + raxlo; //| - } - - uint64_t TSCTimer::readRDTSCP(uint64_t* logicore) { - uint64_t raxlo,rdxho, rcx; - asm volatile ( ".intel_syntax noprefix\t\n" - "rdtscp\t\n" - "lfence\t\n": "=a" (raxlo), "=d" (rdxho), "=c" (rcx) ); - if (logicore != nullptr) *logicore = rcx; - return (rdxho << 32) + raxlo; //| - } - - TSCTimer* TSCTimer::getTimer() { - if (!checkInvariantTSC()) return nullptr; - //TODO debug dis - const char vendorNames[2][13] = { - {"AuthenticAMD"}, - {"GenuineIntel"} - }; - char* vendorName = readVendorName(); - int64_t baseFreq = ART_NOT_REPORTED; - - if (strcmp(vendorName, vendorNames[1]) == 0) - baseFreq = intelRetrieveART(); - if (baseFreq == ART_NOT_REPORTED) - baseFreq = getFreqFromSystem(); - if (baseFreq < OPERATION_SUCCESSFUL) - return nullptr; - - //timer = - return new TSCTimer(vendorName, baseFreq); - //return OPERATION_SUCCESSFUL; - } - - uint64_t TSCTimer::getTimeStamp(){ - if (availableRDTSCP) - return readRDTSCP(); - else - return readRDTSC(); - } - - uint64_t TSCTimer::getBaseFrequency(){ - return baseFreq; - } - -} - - -#ifdef _WIN64 -} -#endif - diff --git a/src/tmrtsc.hpp b/src/tmrtsc.hpp index 5eb10b5..051e85c 100644 --- a/src/tmrtsc.hpp +++ b/src/tmrtsc.hpp @@ -1,5 +1,4 @@ //TODO It's threadin' time -#pragma once #ifdef _WIN64 #define LIB_EXPORT __declspec(dllexport) @@ -8,8 +7,6 @@ #define _WIN32_WINNT _WIN32_WINNT_WIN10 //0x0A00 #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 32767 - #define _MT - #define _DLL #include #include #include @@ -23,22 +20,22 @@ #include #include "debug.h" - -#if _WIN64 - extern "C" { -#endif - +/* + * #if _WIN64 + * extern "C" {) + * #endif + */ namespace tmr { #ifdef _WIN64 - enum winReturnValues{ + enum LIB_EXPORT winReturnValues{ CANT_OPEN_KEY = -1, CANT_RETRIEVE_KEY_INFO = -2, CANT_READ_DATA_FROM_VALUE = -3, CANT_RETRIEVE_FREQUENCY = -4 }; #endif - enum ReturnValues { + enum LIB_EXPORT ReturnValues { OPERATION_SUCCESSFUL = 0, INVARIANT_TSC_NOT_SUPPORTED = -1, UNSUPPORTED_CPU = -2, @@ -49,49 +46,211 @@ namespace tmr { class LIB_EXPORT TSCTimer { private: - //static TSCTimer timer; + static TSCTimer timer; char* vendorName; int64_t baseFreq = ART_NOT_REPORTED; - bool availableRDTSCP = false; + bool availableRDTSCP; int64_t art; //reserved - TSCTimer(char* vendorName, int64_t baseFreq); + TSCTimer (char* vendorName, int64_t baseFreq) { + this->vendorName = vendorName; + this->baseFreq = baseFreq; + availableRDTSCP = (checkRDTSCP()) ? true : false; + } - ~TSCTimer(); + ~TSCTimer () { + free(vendorName); + } - static bool checkInvariantTSC(); + static bool checkInvariantTSC() { + uint64_t rdx; + asm volatile (".intel_syntax noprefix\t\n" \ + "mov eax, 0x80000007\t\n" \ + "cpuid\t\n" : "=d" (rdx) ); + bool iTSC = rdx & (1<<8); + return iTSC; + } - static char* readVendorName (); + + static char* readVendorName () { + char* palabritas = (char*)malloc(sizeof(char) * 13); + uint8_t siguienteLetra = 0; + uint64_t regs[3]; + asm volatile ( ".intel_syntax noprefix\t\n" \ + "mov eax, 0x0\t\n" \ + "cpuid\t\n" : "=b" (regs[0]), "=c" (regs[2]), "=d" (regs[1]) ); + int byte = 0; + for (int reg = 0; reg < 3; reg++, byte = 0){ + char* charifiedReg = (char*)®s[reg]; + for(; byte < 4; byte++, siguienteLetra++ ){ + palabritas[siguienteLetra] = charifiedReg[byte]; + } + } + palabritas[siguienteLetra] = '\0'; + return palabritas; + } - static int64_t intelRetrieveART(); + static int64_t intelRetrieveART(){ + //TODO: Find a valid Intel CPU to debug ART route + //if (freq == nullptr) return - + + uint64_t raxde, rbxnum, rcxhz; + asm volatile ( ".intel_syntax noprefix\t\n" \ + "mov eax, 0x15\t\n" \ + "cpuid\t\n" : "=a" (raxde), "=b" (rbxnum), "=c" (rcxhz) ); + log_debugcpp("hmm " << raxde << " " << rbxnum << " " << rcxhz); + if (rbxnum == 0 || rcxhz == 0) return ART_NOT_REPORTED; + int64_t TSCFreq = (rcxhz * rbxnum)/raxde; + //*freq = TSCFreq; + log_debugcpp("raxo " << TSCFreq << " " << TSCFreq); + return TSCFreq; + } #ifdef _WIN64 - static int64_t getFreqFromSystem(); + static int64_t getFreqFromSystem(){ + //TODO: close opened key + const WORD STRING_SIZE = 4; + const WCHAR COMPARE_TARGET[STRING_SIZE + 1] = L"~MHz"; + DWORD longestDataSize; + + LSTATUS status; + HKEY key; + DWORD numValues; + + WCHAR valName[MAX_VALUE_NAME]; //uint32_t wtf + DWORD valLen = MAX_VALUE_NAME; + + LPBYTE dataContent = nullptr; + DWORD dataLen; + + status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, + KEY_QUERY_VALUE, &key); + if(status != ERROR_SUCCESS) return CANT_OPEN_KEY; + + status = RegQueryInfoKey( + key, // key handle + NULL, // buffer for class name + NULL, // size of class string + NULL, // reserved + NULL, // num of subkeys + NULL, // longest subkey size + NULL, // longest class string + &numValues, // num of values for this key + NULL, // longest value name + &longestDataSize, // longest value data + NULL, // security descriptor + NULL); // last write time + if(status != ERROR_SUCCESS) return CANT_RETRIEVE_KEY_INFO; + + dataLen = sizeof(REG_QWORD) * (longestDataSize); + dataContent = (LPBYTE)malloc(dataLen); + for (DWORD i = 0; i < numValues; i++){ + valLen = MAX_VALUE_NAME; + dataLen = sizeof(REG_QWORD) * (longestDataSize); + status = RegEnumValueW(key, + i, + valName, + &valLen, + NULL, + NULL, + dataContent, + &dataLen + ); + + if(status != ERROR_SUCCESS) return CANT_READ_DATA_FROM_VALUE; + + if (CSTR_EQUAL == CompareStringEx( + LOCALE_NAME_INVARIANT, + NORM_LINGUISTIC_CASING, + valName, + valLen, + COMPARE_TARGET, + STRING_SIZE, + NULL, + NULL, + 0 + ) + ) { + LPDWORD PMHz = (LPDWORD)dataContent; + DWORD MHz = *PMHz; + free(dataContent); + return MHz * 1000000; + } + } + return CANT_READ_DATA_FROM_VALUE; + } #endif - bool checkRDTSCP(); + bool checkRDTSCP(){ //Generic + uint64_t rdx; + asm volatile (".intel_syntax noprefix\t\n" \ + "mov eax, 0x80000001\t\n" \ + // 080000007h\t\n" + "cpuid\t\n" : "=d" (rdx) ); + bool RDTSCP = rdx & (1<<27); + //"and edx, 10000000\n") + return RDTSCP; + } - uint64_t readRDTSC(); + uint64_t readRDTSC() { + uint64_t raxlo,rdxho; + asm volatile ( ".intel_syntax noprefix\t\n" + "lfence\n" \ + "rdtsc\n" \ + "lfence\n" : "=a" (raxlo), "=d" (rdxho)); + return (rdxho << 32) + raxlo; //| + } - uint64_t readRDTSCP(uint64_t* logicore = nullptr ); + uint64_t readRDTSCP(uint64_t* logicore = nullptr ) { + uint64_t raxlo,rdxho, rcx; + asm volatile ( ".intel_syntax noprefix\t\n" + "rdtscp\t\n" + "lfence\t\n": "=a" (raxlo), "=d" (rdxho), "=c" (rcx) ); + if (logicore != nullptr) *logicore = rcx; + return (rdxho << 32) + raxlo; //| + } public: - // static int getTimer(TSCTimer* timer = nullptr); - static TSCTimer* getTimer(); + static int getTimer(TSCTimer* timer = nullptr) { + if (!checkInvariantTSC()) return INVARIANT_TSC_NOT_SUPPORTED; + //TODO debug dis + const char vendorNames[2][13] = { + {"AuthenticAMD"}, + {"GenuineIntel"} + }; + char* vendorName = readVendorName(); + int64_t baseFreq; + + if (strcmp(vendorName, vendorNames[1])) + baseFreq = intelRetrieveART(); + if (baseFreq == ART_NOT_REPORTED) + baseFreq = getFreqFromSystem(); + if (baseFreq < OPERATION_SUCCESSFUL) + return CANT_READ_FREQUENCY_FROM_SYSTEM; - uint64_t getTimeStamp(); + timer = new TSCTimer(vendorName, baseFreq); + return OPERATION_SUCCESSFUL; + } - uint64_t getBaseFrequency(); - + uint64_t getTimeStamp(){ + if (availableRDTSCP) + return readRDTSCP(); + else + return readRDTSC(); + } + + uint64_t getBaseFrequency(){ + return baseFreq; + } }; } - -#ifdef _WIN64 -} -#endif - +/* + * #ifdef _WIN64 + * } + * #endif + */