diff --git a/qa_interfaces/IBenchmark.h b/qa_interfaces/IBenchmark.h new file mode 100644 index 00000000..9b58bf8c --- /dev/null +++ b/qa_interfaces/IBenchmark.h @@ -0,0 +1,71 @@ +#pragma once + +#include "Module.h" + +// @stubgen:include + +namespace Thunder { +namespace QualityAssurance { + + // @json 1.0.0 @text:legacy_lowercase + struct EXTERNAL IBenchmark : virtual public Core::IUnknown { + enum { ID = ID_BENCHMARK }; + + ~IBenchmark() override = default; + + struct RoundTripStats { + uint64_t minNs; + uint64_t avgNs; + uint64_t maxNs; + uint64_t stddevNs; + }; + + struct MemoryStats { + uint64_t residentBefore; // RSS in bytes before benchmark + uint64_t residentAfter; // RSS in bytes after benchmark + uint64_t allocatedBefore; // Allocated in bytes before benchmark + uint64_t allocatedAfter; // Allocated in bytes after benchmark + }; + + + struct BenchmarkResult { + string apiName; + uint32_t iterations; + + RoundTripStats roundTrip; + MemoryStats memory; + + bool passed; // true if within configured thresholds + string failureReason; // empty if passed, describes which threshold was exceeded + }; + + typedef RPC::IIteratorType IBenchmarkResultIterator; + + // @brief Run the benchmark + // @param iterations: Denotes the number of iterations the benchmark should run + // @param success: True if the benchmark completed successfully + virtual Core::hresult Trigger(const uint32_t iterations, bool& success /* @out */) = 0; + + virtual Core::hresult CollectData(IBenchmarkResultIterator*& report /* @out */) const = 0; + + // @brief Set pass/fail thresholds for benchmark results + // @param maxLatencyDeviationPct: Maximum allowed % deviation in avg latency compared to first-run baseline (0 = no latency check) + // @param maxMemoryGrowthBytes: Maximum allowed RSS growth in bytes per method (0 = no memory check) + // @param success: True if thresholds were set + virtual Core::hresult SetThreshold(const float maxLatencyDeviationPct, const uint64_t maxMemoryGrowthBytes, bool& success /* @out */) = 0; + + // @event + struct EXTERNAL INotification : virtual public Core::IUnknown { + enum { ID = ID_BENCHMARK_NOTIFICATION }; + + ~INotification() override = default; + + virtual void PerformanceCheckCompleted() = 0; + }; + + virtual Core::hresult Register(const IBenchmark::INotification* sink) = 0; + virtual Core::hresult Unregister(const IBenchmark::INotification* sink) = 0; + }; + +} +} \ No newline at end of file diff --git a/qa_interfaces/IBenchmarkPayloadCOMRPC.h b/qa_interfaces/IBenchmarkPayloadCOMRPC.h new file mode 100644 index 00000000..8ed45d21 --- /dev/null +++ b/qa_interfaces/IBenchmarkPayloadCOMRPC.h @@ -0,0 +1,76 @@ +#pragma once +#include "Module.h" + +// @stubgen:include + +namespace Thunder { + namespace QualityAssurance { + + + struct SampleData + { + uint32_t id; + uint32_t value; + string name; + }; + + struct EXTERNAL IBenchmarkPayload : virtual public Core::IUnknown + { + enum { ID = ID_BENCHMARK_PAYLOAD }; + + enum PayloadType : uint8_t + { + PAYLOAD_UNKNOWN, + PAYLOAD_SMALL, + PAYLOAD_MEDIUM, + PAYLOAD_LARGE + }; + + typedef RPC::IIteratorType IPayloadTypeIterator; + + virtual uint32_t GetPayloadTypes(IPayloadTypeIterator*& types /* @out */) const = 0; + + virtual uint32_t SendUint16(const uint16_t value) = 0; + + virtual uint32_t SendUint32(const uint32_t value) = 0; + + virtual uint32_t SendUint64(const uint64_t value) = 0; + + virtual uint32_t SendBool(const bool value) = 0; + + virtual uint32_t SendFloat(const float value) = 0; + + virtual uint32_t SendDouble(const double value) = 0; + + virtual uint32_t SendString(const string& value) = 0; + + virtual uint32_t SendSampleData(const SampleData& data) = 0; + + virtual uint32_t SendWithNoParameters() = 0; + + virtual uint32_t SendBuffer(const uint16_t bufferSize, const uint8_t buffer[] /* @length:bufferSize @in */) = 0; + + virtual uint32_t SendReceiveUint16(const uint16_t input, uint16_t &output /* @out */) const = 0; + + virtual uint32_t SendReceiveUint32(const uint32_t input, uint32_t &output /* @out */) const = 0; + + virtual uint32_t SendReceiveUint64(const uint64_t input, uint64_t &output /* @out */) const = 0; + + virtual uint32_t SendReceiveBool(const bool input, bool &output /* @out */) const = 0; + + virtual uint32_t SendReceiveFloat(const float input, float &output /* @out */) const = 0; + + virtual uint32_t SendReceiveDouble(const double input, double &output /* @out */) const = 0; + + virtual uint32_t SendReceiveString(const string &input, string &output /* @out */) const = 0; + + virtual uint32_t SendReceiveSampleData(const SampleData &input, SampleData &output /* @out */) const = 0; + + virtual uint32_t SendReceiveBuffer(uint16_t& bufferSize /* @inout */, uint8_t buffer[] /* @length:bufferSize @inout */) const = 0; + + virtual uint32_t Add(const uint32_t a, const uint32_t b, uint32_t &result /* @out */) const = 0; + + ~IBenchmarkPayload() override = default; + }; +} +} \ No newline at end of file diff --git a/qa_interfaces/QAIds.h b/qa_interfaces/QAIds.h index 08173dc0..403ad713 100644 --- a/qa_interfaces/QAIds.h +++ b/qa_interfaces/QAIds.h @@ -74,8 +74,14 @@ namespace QualityAssurance { ID_TESTKEEP = ID_TESTTEXTOPTIONS + 4, ID_TESTKEEP_NOTIFICATION = ID_TESTTEXTOPTIONS + 5, ID_TESTCUSTOM = ID_TESTTEXTOPTIONS + 6, - ID_TESTCUSTOM_NOTIFICATION = ID_TESTTEXTOPTIONS + 7 + ID_TESTCUSTOM_NOTIFICATION = ID_TESTTEXTOPTIONS + 7, + ID_BENCHMARK = RPC::IDS::ID_EXTERNAL_QA_INTERFACE_OFFSET + 0x040, + ID_BENCHMARK_NOTIFICATION = ID_BENCHMARK + 1, + ID_BENCHMARK_RESULT_ITERATOR = ID_BENCHMARK + 2, + + ID_BENCHMARK_PAYLOAD = RPC::IDS::ID_EXTERNAL_QA_INTERFACE_OFFSET + 0x050, + ID_PAYLOADTYPE_ITERATOR = ID_BENCHMARK_PAYLOAD + 1, }; } }