From 443593e9f08d30aa566ce8011a16204530b3f1c3 Mon Sep 17 00:00:00 2001 From: Hane Date: Tue, 25 Jul 2023 20:55:53 +0200 Subject: [PATCH 1/7] cleanup 2 --- build.bat | 1 - buildproto.bat | 1 + src/global.h | 15 --------------- src/{main.cpp => proto/proto.cpp} | 8 ++------ 4 files changed, 3 insertions(+), 22 deletions(-) delete mode 100644 build.bat create mode 100644 buildproto.bat delete mode 100644 src/global.h rename src/{main.cpp => proto/proto.cpp} (99%) diff --git a/build.bat b/build.bat deleted file mode 100644 index 755c16c..0000000 --- a/build.bat +++ /dev/null @@ -1 +0,0 @@ -clang++ src\main.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -l c++ -l unwind -static --verbose diff --git a/buildproto.bat b/buildproto.bat new file mode 100644 index 0000000..db46758 --- /dev/null +++ b/buildproto.bat @@ -0,0 +1 @@ +clang++ -DDEBUG src\proto\proto.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -l c++ -l unwind -static --verbose diff --git a/src/global.h b/src/global.h deleted file mode 100644 index 96d177b..0000000 --- a/src/global.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -//TODO enum capullo -#define ENDPOINT_MASTER_VOLUME -1 -#define ENDPOINT_LEFT_CHANNEL_VOLUME 0 -#define ENDPOINT_RIGHT_CHANNEL_VOLUME 1 - -#define STRING_MUTE "Mute" -#define STRING_UNMUTE "Unmute" -//INIT BACK - - -class OverseerHandler; -extern OverseerHandler *osh; - diff --git a/src/main.cpp b/src/proto/proto.cpp similarity index 99% rename from src/main.cpp rename to src/proto/proto.cpp index 8a44426..efe3c55 100644 --- a/src/main.cpp +++ b/src/proto/proto.cpp @@ -29,7 +29,7 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B #ifdef _WIN64 //#include - //#include + //#includqe //#include #define UNICODE #define WIN32_LEAN_AND_MEAN @@ -45,13 +45,9 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B //hilitos y tal #endif -#ifndef DEBUG - #define DEBUG -#endif - #include #include -#include "debug.h" +#include "../debug.h" bool checkInvariantTSC(){ //Generic uint64_t rdx; From dc837e2bb17532a8ad1521ec91e24ef4d0433c54 Mon Sep 17 00:00:00 2001 From: Hane Date: Tue, 25 Jul 2023 21:03:08 +0200 Subject: [PATCH 2/7] leanme --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 56c5521..929252b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ # tmr +no sé si desde dentro del dll/so, desde main, lo puedo forzar a X hilo. Es lo que faltaría para tener esta impl 100% funcional* +[20:59] +no puedo hacerlo bien del todo sin acceso a un procesador intel de 12a o 13a generación (editado) +[21:00] +si pudiese clampear la dll a hilo X desde ella misma cuando ntdll la carga, al menos estaría todo bien hardcodeadito al hilo 0 y funcionaría por el poder de ser un mugroso +[21:00] +va a funcionar igual en el 9X% de casos, porque todos los so intentan sincronizar el tsc de todos los hilos hasta en multisocket +[21:00] +pero eso está técnicamente mal +[21:01] +y bueno, necesito un procesador de intel más reciente para explorar el cálculo del ART, y 12/13 gen para explorar el tsc entre hilos de cpu de distinta uarch +[21:01] +no va a pasar, así que a joderse +[21:02] +intentaré clampear desde dll a un hilo, pondré el Modo Unix™️ y a otra cosa + From 0ff6488545679819e85d94ccf7a1cdf3507d95de Mon Sep 17 00:00:00 2001 From: Hane Date: Sat, 29 Jul 2023 01:43:21 +0200 Subject: [PATCH 3/7] linus comes into play --- src/proto/proto.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/proto/proto.cpp b/src/proto/proto.cpp index efe3c55..c5b2e7a 100644 --- a/src/proto/proto.cpp +++ b/src/proto/proto.cpp @@ -1,3 +1,7 @@ +<<<<<<< Updated upstream +======= +//si, bueno, testx +>>>>>>> Stashed changes /* * THREADIN THE LINUS: https://linux.die.net/man/2/sched_setaffinity */ From bbed99ba8c89a0c233ec914fbd9e07b72796262f Mon Sep 17 00:00:00 2001 From: Hane Date: Mon, 7 Aug 2023 15:17:36 +0200 Subject: [PATCH 4/7] missing reg key closing --- src/tmrtsc.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/tmrtsc.cpp b/src/tmrtsc.cpp index aacffde..bac4398 100644 --- a/src/tmrtsc.cpp +++ b/src/tmrtsc.cpp @@ -79,9 +79,12 @@ namespace tmr { 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 = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_QUERY_VALUE, &key); + + if(status != ERROR_SUCCESS) { + status = RegCloseKey(key); + return CANT_OPEN_KEY; + } status = RegQueryInfoKey( key, // key handle @@ -96,7 +99,10 @@ namespace tmr { &longestDataSize, // longest value data NULL, // security descriptor NULL); // last write time - if(status != ERROR_SUCCESS) return CANT_RETRIEVE_KEY_INFO; + if(status != ERROR_SUCCESS) { + status = RegCloseKey(key); + return CANT_RETRIEVE_KEY_INFO; + } dataLen = sizeof(REG_QWORD) * (longestDataSize); dataContent = (LPBYTE)malloc(dataLen); @@ -113,7 +119,10 @@ namespace tmr { &dataLen ); - if(status != ERROR_SUCCESS) return CANT_READ_DATA_FROM_VALUE; + if(status != ERROR_SUCCESS) { + RegCloseKey(key); + return CANT_READ_DATA_FROM_VALUE; + } if (CSTR_EQUAL == CompareStringEx( LOCALE_NAME_INVARIANT, @@ -125,14 +134,15 @@ namespace tmr { NULL, NULL, 0 - ) - ) { + )) + { LPDWORD PMHz = (LPDWORD)dataContent; DWORD MHz = *PMHz; free(dataContent); return MHz * 1000000; - } + } } + status = RegCloseKey(key); return CANT_READ_DATA_FROM_VALUE; } From 6136207436a140320232574f8274d375144fe22c Mon Sep 17 00:00:00 2001 From: Hane Date: Wed, 17 Jan 2024 20:07:53 +0100 Subject: [PATCH 5/7] refactored test --- buildtest.bat | 2 +- src/test/test.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/tmrtsc.cpp | 1 - src/tmrtsc.hpp | 14 ++++----- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/buildtest.bat b/buildtest.bat index 3ea2ae5..364e361 100644 --- a/buildtest.bat +++ b/buildtest.bat @@ -1 +1 @@ -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 +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 diff --git a/src/test/test.cpp b/src/test/test.cpp index 1587e16..35b9e1d 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -5,7 +5,8 @@ #define _MT #define _DLL #include - #include + #include +//#include #endif #include "../debug.h" @@ -14,11 +15,31 @@ using namespace tmr; #ifdef _WIN64 +static inline int64_t getQPCTicks() { + LARGE_INTEGER ticks; + if (!QueryPerformanceCounter(&ticks)) + { + return 0; + } + return ticks.QuadPart; +} + +static inline int64_t getQPCFrequency() { + LARGE_INTEGER ticks; + if (!QueryPerformanceFrequency(&ticks)) + { + return 0; + } + return ticks.QuadPart; +} + + int main(int argc, char** argv){ - HMODULE dell; - DWORD fracaso; + //HMODULE dell; + //DWORD fracaso; //DllImport TSCTimer* timer; - int sleep = 1000; + uint64_t sleep = 1; + uint64_t checks = 0; /* * dell = LoadLibraryExW(TEXT("libtmrtsc.dll"), NULL, NULL); @@ -31,13 +52,42 @@ int main(int argc, char** argv){ 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; + uint64_t wfr = getQPCFrequency(); + int64_t fr = timer->getBaseFrequency(); + + + uint64_t wt1 = getQPCTicks(); + int64_t t1 = timer->getTimeStamp(); + int64_t t2 = timer->getTimeStamp(); + while ((t2 - t1) < (sleep * fr)) { + t2 = timer->getTimeStamp(); + checks++; + } + //uint64_t fr = timer->getBaseFrequency(); + uint64_t wt2 = getQPCTicks(); + std::cout << "Sleep: " << sleep << "s\n-----------------\nTest 1: TSCTimer within QPC\n" << std::endl; + std::cout << " QPC Momento: \nt1: " << wt1 << " t2: " << wt2 << " fr: " << wfr << std::endl; + std::cout << " restita: " << wt2-wt1 << std::endl; + std::cout << " TSCTimer Momento: \nt1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; + std::cout << " restita: " << t2-t1 << std::endl; + std::cout << " checks: " << checks << "\n-----------------\nTest 2: QPC within TSCTimer\n"<< std::endl; + + checks = 0; + t1 = timer->getTimeStamp(); + wt1 = getQPCTicks(); + wt2 = getQPCTicks(); + while ((wt2 - wt1) < (sleep * wfr)) { + wt2 = getQPCTicks(); + checks++; + } + //uint64_t fr = timer->getBaseFrequency(); + t2 = timer->getTimeStamp(); + std::cout << "QPC Momento: \n t1: " << wt1 << " t2: " << wt2 << " fr: " << wfr << std::endl; + std::cout << "restita: " << wt2-wt1 << std::endl; + std::cout << "TSCTimer Momento: \n t1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; + std::cout << " restita: " << t2-t1 << std::endl; + std::cout << " checks: " << checks << std::endl; + return 0; } diff --git a/src/tmrtsc.cpp b/src/tmrtsc.cpp index bac4398..e940356 100644 --- a/src/tmrtsc.cpp +++ b/src/tmrtsc.cpp @@ -47,7 +47,6 @@ namespace tmr { 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" \ diff --git a/src/tmrtsc.hpp b/src/tmrtsc.hpp index 5eb10b5..6389381 100644 --- a/src/tmrtsc.hpp +++ b/src/tmrtsc.hpp @@ -32,18 +32,18 @@ namespace tmr { #ifdef _WIN64 enum winReturnValues{ - CANT_OPEN_KEY = -1, - CANT_RETRIEVE_KEY_INFO = -2, + CANT_OPEN_KEY = -1, + CANT_RETRIEVE_KEY_INFO = -2, CANT_READ_DATA_FROM_VALUE = -3, - CANT_RETRIEVE_FREQUENCY = -4 + CANT_RETRIEVE_FREQUENCY = -4 }; #endif enum ReturnValues { - OPERATION_SUCCESSFUL = 0, - INVARIANT_TSC_NOT_SUPPORTED = -1, - UNSUPPORTED_CPU = -2, + OPERATION_SUCCESSFUL = 0, + INVARIANT_TSC_NOT_SUPPORTED = -1, + UNSUPPORTED_CPU = -2, CANT_READ_FREQUENCY_FROM_SYSTEM = -3, - ART_NOT_REPORTED = -4 + ART_NOT_REPORTED = -4 }; class LIB_EXPORT TSCTimer { From d1343ff90c5fe1f85feede69173af9efb2a3e631 Mon Sep 17 00:00:00 2001 From: Hane Date: Wed, 17 Jan 2024 23:59:50 +0100 Subject: [PATCH 6/7] modified test and more proto --- buildproto.bat | 2 +- src/proto/proto.cpp | 39 +++++++++++++++++++++++---------------- src/test/test.cpp | 8 ++++---- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/buildproto.bat b/buildproto.bat index db46758..116a7a3 100644 --- a/buildproto.bat +++ b/buildproto.bat @@ -1 +1 @@ -clang++ -DDEBUG src\proto\proto.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -l c++ -l unwind -static --verbose +clang++ -DDEBUG src\proto\proto.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -static-libstdc++ -static --verbose diff --git a/src/proto/proto.cpp b/src/proto/proto.cpp index c5b2e7a..53ba00f 100644 --- a/src/proto/proto.cpp +++ b/src/proto/proto.cpp @@ -1,7 +1,3 @@ -<<<<<<< Updated upstream -======= -//si, bueno, testx ->>>>>>> Stashed changes /* * THREADIN THE LINUS: https://linux.die.net/man/2/sched_setaffinity */ @@ -29,7 +25,7 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B //TSC is incremented by the base multiplier once every reference clock, so on my Xeon E5-2680 (Sandy Bridge EP) this is an increment of 27 every 10 ns - +//https://github.com/jdmccalpin/low-overhead-timers/issues/1 #ifdef _WIN64 //#include @@ -45,7 +41,7 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B #include #include #endif -#ifdef NOMESELDELINUS +#ifdef LOwOnus //hilitos y tal #endif @@ -53,6 +49,17 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B #include #include "../debug.h" +uint64_t checksatr(){ //Generic + uint64_t rcx; + asm volatile (".intel_syntax noprefix\t\n" \ + "mov eax, 0x80000007\t\n" \ + // 080000007h\t\n" + "cpuid\t\n" : "=c" (rcx) ); + //bool iTSC = rcx & (1<<6); + //"and edx, 10000000\n") + return rcx; +} + bool checkInvariantTSC(){ //Generic uint64_t rdx; asm volatile (".intel_syntax noprefix\t\n" \ @@ -96,10 +103,11 @@ EDX Bits 31-00: Reserved = 0. */ -char* AMDMeCagoEnTusPutosMuertos () { +char* AMDTest() { /* * Extended name on AMD systems when using 8000_002-4. 8000_0000 for Extpagequant/vendor. Hijos de puta. * Now parsing 0H for standard brand name + * https://github.com/jdmccalpin/low-overhead-timers/issues/1 */ char* palabritas = (char*)malloc(sizeof(char) * 13); uint8_t siguienteLetra = 0; @@ -119,8 +127,8 @@ char* AMDMeCagoEnTusPutosMuertos () { return palabritas; } -//GMET on??????????? jfc wtf -bool AMDJoderMET(){ +//GMET on??????????? Zenbros... +bool AMDGMET(){ uint64_t rdx; asm volatile ( ".intel_syntax noprefix\t\n" \ "mov eax, 0x8000000A\t\n" \ @@ -248,7 +256,7 @@ uint64_t estimandoFreq(){ valLen = MAX_VALUE_NAME; //data NULL + len NON_NULL to get dataBufLen; //data allocated (NON-NULL) + len NON-NULL with previous value for dataLen - //JFC MS WHY. that why we defaultin to biggis. cos not worky. ewe + //MS WHY. that why we defaultin to biggis. cos not worky. ewe dataLen = sizeof(REG_QWORD) * (longestDataSize); status = RegEnumValueW(key, i, @@ -278,9 +286,7 @@ uint64_t estimandoFreq(){ ) ) { //dataLen = dataLen * 2lu; - /* BROS YO ES QUE ME VOY A CAGAR EN SUS PUTOS MUERTOS - * ASí QUE PIDES DOS VECES, UNA TAMAńO, OTRA A TOPE PRESISO, EH - * PUTA BASURA DE API + /* We do be usin' well designed APIs...... * status = RegEnumValueW(key, * i, * valName, @@ -312,14 +318,15 @@ uint64_t estimandoFreq(){ int main(int argc, char** argv){ //AMD Momento - char* opiniones = AMDMeCagoEnTusPutosMuertos(); - bool w11 = AMDJoderMET(); + char* opiniones = AMDTest(); + bool w11 = AMDGMET(); for (int i = 0; i < 3; i++) { uint64_t isItActually32GHz = estimandoFreq(); log_debugcpp("ayo we found " << isItActually32GHz << " flash knuckle"); } int64_t juas = getFreqFromReg(); - log_debugcpp("JODER " << juas); + log_debugcpp("satr " << checksatr()); + log_debugcpp("Invariant " << checkInvariantTSC()); //iwintewel //Cordura diff --git a/src/test/test.cpp b/src/test/test.cpp index 35b9e1d..8126175 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -53,7 +53,7 @@ int main(int argc, char** argv){ if(timer == nullptr) return -2; uint64_t wfr = getQPCFrequency(); - int64_t fr = timer->getBaseFrequency(); + int64_t fr = 3193999000;//timer->getBaseFrequency(); uint64_t wt1 = getQPCTicks(); @@ -66,9 +66,9 @@ int main(int argc, char** argv){ //uint64_t fr = timer->getBaseFrequency(); uint64_t wt2 = getQPCTicks(); std::cout << "Sleep: " << sleep << "s\n-----------------\nTest 1: TSCTimer within QPC\n" << std::endl; - std::cout << " QPC Momento: \nt1: " << wt1 << " t2: " << wt2 << " fr: " << wfr << std::endl; + std::cout << "QPC Momento: \n t1: " << wt1 << " t2: " << wt2 << " fr: " << wfr << std::endl; std::cout << " restita: " << wt2-wt1 << std::endl; - std::cout << " TSCTimer Momento: \nt1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; + std::cout << "TSCTimer Momento: \n t1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; std::cout << " restita: " << t2-t1 << std::endl; std::cout << " checks: " << checks << "\n-----------------\nTest 2: QPC within TSCTimer\n"<< std::endl; @@ -83,7 +83,7 @@ int main(int argc, char** argv){ //uint64_t fr = timer->getBaseFrequency(); t2 = timer->getTimeStamp(); std::cout << "QPC Momento: \n t1: " << wt1 << " t2: " << wt2 << " fr: " << wfr << std::endl; - std::cout << "restita: " << wt2-wt1 << std::endl; + std::cout << " restita: " << wt2-wt1 << std::endl; std::cout << "TSCTimer Momento: \n t1: " << t1 << " t2: " << t2 << " fr: " << fr << std::endl; std::cout << " restita: " << t2-t1 << std::endl; std::cout << " checks: " << checks << std::endl; From 2035c1e10ec2c0f5167d36e21ee0779c42324a55 Mon Sep 17 00:00:00 2001 From: Hane Date: Thu, 18 Jan 2024 02:06:15 +0100 Subject: [PATCH 7/7] repo cleanup, added actual README --- README.md | 58 ++++++++++++++++++++++++++++++++------------- buildall.bat | 5 ---- builddall.bat | 5 ---- builddlib.bat | 3 --- builddtest.bat | 4 ---- buildlib.bat | 2 -- buildproto.bat | 1 - buildtest.bat | 1 - src/debug.h | 2 +- src/proto/proto.cpp | 6 +++++ src/test/test.cpp | 4 ++-- src/tmrtsc.cpp | 10 ++++++-- src/tmrtsc.hpp | 6 ++--- 13 files changed, 61 insertions(+), 46 deletions(-) delete mode 100644 buildall.bat delete mode 100644 builddall.bat delete mode 100644 builddlib.bat delete mode 100644 builddtest.bat delete mode 100644 buildlib.bat delete mode 100644 buildproto.bat delete mode 100644 buildtest.bat diff --git a/README.md b/README.md index 929252b..1293552 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,44 @@ -# tmr +x86 TSC-based tick timer written in C++ and extended ASM. -no sé si desde dentro del dll/so, desde main, lo puedo forzar a X hilo. Es lo que faltaría para tener esta impl 100% funcional* -[20:59] -no puedo hacerlo bien del todo sin acceso a un procesador intel de 12a o 13a generación (editado) -[21:00] -si pudiese clampear la dll a hilo X desde ella misma cuando ntdll la carga, al menos estaría todo bien hardcodeadito al hilo 0 y funcionaría por el poder de ser un mugroso -[21:00] -va a funcionar igual en el 9X% de casos, porque todos los so intentan sincronizar el tsc de todos los hilos hasta en multisocket -[21:00] -pero eso está técnicamente mal -[21:01] -y bueno, necesito un procesador de intel más reciente para explorar el cálculo del ART, y 12/13 gen para explorar el tsc entre hilos de cpu de distinta uarch -[21:01] -no va a pasar, así que a joderse -[21:02] -intentaré clampear desde dll a un hilo, pondré el Modo Unix™️ y a otra cosa + This timer queries RDTSCP/RDTSC manually on compatible systems and presents a quick and easy-to-use interface to obtain timestamps. On Windows, this is basically what `QueryPerformanceCounter` achieves behind the curtains (and with fallbacks where not applicable, like HPET), but with lower resolution. + While functional on some CPU families (Zen/+ and Haswell have been tested), this library is not ready for use. Linux support is TBD, alongside testing on different CPU families and implementing support for heterogeneous architectures and products (such as Tiger Lake+/Zen4+Zen4c systems). + + Worth noting as well is the fact that [calculating TSC resolution from user-space on an AMD CPU is not possible.](https://github.com/jdmccalpin/low-overhead-timers/issues/1) Precise enough estimations can be calculated, but this artificial limitation adds a non-insignificant level of friction to this project. + + A small console program to test this library and comparing it agains `QueryPerformancecounter` is provided, busywaiting for a second and comparing both. + +# But why? + + During development of the mouse-on-keyboard script, I grew curious about this topic. Win32's `Sleep()` is a reliably unreliable time-skipping measure, subject to the wishes of thread time-slicing and scheduling. High resolution timers in the vein of `QueryPerformanceCounter` are what Win32 offers in this regard, but a spark of interest and curiosity had already grown about this topic. I created this library, this incomplete pet-project, as a means to learn and refresh knowledge about x86 ASM, registry traversal and modification, modern OSes, current x86 hardware features and shared libraries. + +# How to build + +## Build requirements + + - Both test and Developed and tested with `clang` using [**llvm-mingw UCRT 20220906**](https://github.com/mstorsjo/llvm-mingw/releases/tag/20220906). Any `MinGW`-backed `clang` compiler should work, but your mileage may vary. + - This lib has only been compiled and tested as a dynamic lib, but it should work statically linked as well. + +## How to compile + + Add `TMRDEBUG` to print debug information. Currently, it only offers relevant information for ART calculation. + + - Library + + ``` + clang++ -shared src\tmrtsc.cpp -o libtmrtsc.dll -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -Wl,-Bstatic -l c++ --verbose + ``` + + - Test + + ``` + clang++ src\test\test.cpp -o testd.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -L . -Wl,-Bstatic -l c++ -Wl,-Bdynamic -l tmrtsc --verbose + ``` + + # Bonus + + This repo contains this project's prototipe in `.\src\proto`, which can be messed with build very similarly: + + ``` + clang++ src\proto\proto.cpp -o proto.exe -Wall -Wextra -Wpedantic -std=c++11 -L C:\pathtollvmmingw\x86_64-w64-mingw32\lib -static-libstdc++ --verbose + ``` 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 deleted file mode 100644 index 8c6000b..0000000 --- a/buildlib.bat +++ /dev/null @@ -1,2 +0,0 @@ -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 - diff --git a/buildproto.bat b/buildproto.bat deleted file mode 100644 index 116a7a3..0000000 --- a/buildproto.bat +++ /dev/null @@ -1 +0,0 @@ -clang++ -DDEBUG src\proto\proto.cpp -o build\ayo.exe -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -static-libstdc++ -static --verbose diff --git a/buildtest.bat b/buildtest.bat deleted file mode 100644 index 364e361..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 diff --git a/src/debug.h b/src/debug.h index f91232b..7187017 100644 --- a/src/debug.h +++ b/src/debug.h @@ -1,6 +1,6 @@ #pragma once -#if defined (QT_DEBUG) || defined (DEBUG) || defined (_DEBUG) +#ifdef TMRDEBUG #define log_debugcpp(str) do { \ std::cout << "[DEBUG]" << "(" << __FILE__ << ":" << __LINE__ << "): " << str << std::endl; \ diff --git a/src/proto/proto.cpp b/src/proto/proto.cpp index 53ba00f..1bfa729 100644 --- a/src/proto/proto.cpp +++ b/src/proto/proto.cpp @@ -1,3 +1,4 @@ + /* * THREADIN THE LINUS: https://linux.die.net/man/2/sched_setaffinity */ @@ -27,6 +28,11 @@ Intel(R) 64 and IA-32 Architectures Software Developer's Manual Volume 3 (3A, 3B //https://github.com/jdmccalpin/low-overhead-timers/issues/1 +/* + * no sé si desde dentro del dll/so, desde main, lo puedo forzar a X hilo. Es lo que faltaría para tener esta impl 100% funcional* [20:59] no puedo hacerlo bien del todo sin acceso a un procesador intel de 12a o 13a generación (editado) [21:00] si pudiese clampear la dll a hilo X desde ella misma cuando ntdll la carga, al menos estaría todo bien hardcodeadito al hilo 0 y funcionaría por el poder de la dureza [1:00] va a funcionar igual en el 9X% de casos, porque todos los so intentan sincronizar el tsc de todos los hilos hasta en multisocket [21:00] pero eso está técnicamente mal [21:01] y bueno, necesito un procesador de intel más reciente para explorar el cálculo del ART, y 12/13 gen para explorar el tsc entre hilos de cpu de distinta uarch [21:01] no va a pasar, así que a joderse [21:02] intentaré clampear desde dll a un hilo, pondré el Modo Unix™️ y a otra cosa + */ + + #ifdef _WIN64 //#include //#includqe diff --git a/src/test/test.cpp b/src/test/test.cpp index 8126175..942a032 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -2,8 +2,8 @@ #define UNICODE #define WIN32_LEAN_AND_MEAN #define DllImport __declspec( dllimport ) - #define _MT - #define _DLL +// #define _MT +// #define _DLL #include #include //#include diff --git a/src/tmrtsc.cpp b/src/tmrtsc.cpp index e940356..80c1698 100644 --- a/src/tmrtsc.cpp +++ b/src/tmrtsc.cpp @@ -37,11 +37,12 @@ namespace tmr { int byte = 0; for (int reg = 0; reg < 3; reg++, byte = 0){ char* charifiedReg = (char*)®s[reg]; - for(; byte < 4; byte++, siguienteLetra++ ){ + for(; byte < 4; byte++, siguienteLetra++) { palabritas[siguienteLetra] = charifiedReg[byte]; } } palabritas[siguienteLetra] = '\0'; + log_debugcpp(palabritas); return palabritas; } @@ -147,7 +148,7 @@ namespace tmr { #endif - bool TSCTimer::checkRDTSCP(){ //Generic + bool TSCTimer::checkRDTSCP() { //Generic uint64_t rdx; asm volatile (".intel_syntax noprefix\t\n" \ "mov eax, 0x80000001\t\n" \ @@ -179,6 +180,11 @@ namespace tmr { TSCTimer* TSCTimer::getTimer() { if (!checkInvariantTSC()) return nullptr; //TODO debug dis + #if defined TMRDEBUG && defined _WIN64 + //AttachConsole(ATTACH_PARENT_PROCESS ); + log_debugcpp("TSC Timer debug enabled."); + //FreeConsole(); + #endif const char vendorNames[2][13] = { {"AuthenticAMD"}, {"GenuineIntel"} diff --git a/src/tmrtsc.hpp b/src/tmrtsc.hpp index 6389381..9a22094 100644 --- a/src/tmrtsc.hpp +++ b/src/tmrtsc.hpp @@ -8,8 +8,8 @@ #define _WIN32_WINNT _WIN32_WINNT_WIN10 //0x0A00 #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 32767 - #define _MT - #define _DLL +// #define _MT +// #define _DLL #include #include #include @@ -18,12 +18,10 @@ #define LIB_EXPORT #endif - #include #include #include "debug.h" - #if _WIN64 extern "C" { #endif