From 9bc32fda3274593223341b5eaf31ef71ed656b6a Mon Sep 17 00:00:00 2001 From: rusefi Date: Thu, 8 Jun 2017 23:05:05 -0400 Subject: [PATCH] micro-optimization: in-lining from C++ back to C #441 --- firmware/controllers/engine_controller.cpp | 53 ++++++++++++++++++++- firmware/util/efilib2.cpp | 55 ---------------------- 2 files changed, 52 insertions(+), 56 deletions(-) diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 90e1255479..23c4c363fd 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -134,7 +134,58 @@ efitimeus_t getTimeNowUs(void) { //todo: macro to save method invocation efitick_t getTimeNowNt(void) { - return halTime.get(); +#if EFI_PROD_CODE + bool alreadyLocked = lockAnyContext(); + efitime_t localH = halTime.state.highBits; + uint32_t localLow = halTime.state.lowBits; + + uint32_t value = GET_TIMESTAMP(); + + if (value < localLow) { + // new value less than previous value means there was an overflow in that 32 bit counter + localH += 0x100000000LL; + } + + efitime_t result = localH + value; + + if (!alreadyLocked) { + unlockAnyContext(); + } + return result; +#else +// todo: why is this implementation not used? + /** + * this method is lock-free and thread-safe, that's because the 'update' method + * is atomic with a critical zone requirement. + * + * http://stackoverflow.com/questions/5162673/how-to-read-two-32bit-counters-as-a-64bit-integer-without-race-condition + */ + efitime_t localH; + efitime_t localH2; + uint32_t localLow; + int counter = 0; + do { + localH = halTime.state.highBits; + localLow = halTime.state.lowBits; + localH2 = halTime.state.highBits; +#if EFI_PROD_CODE || defined(__DOXYGEN__) + if (counter++ == 10000) + chDbgPanic("lock-free frozen"); +#endif /* EFI_PROD_CODE */ + } while (localH != localH2); + /** + * We need to take current counter after making a local 64 bit snapshot + */ + uint32_t value = GET_TIMESTAMP(); + + if (value < localLow) { + // new value less than previous value means there was an overflow in that 32 bit counter + localH += 0x100000000LL; + } + + return localH + value; +#endif + } /** diff --git a/firmware/util/efilib2.cpp b/firmware/util/efilib2.cpp index 46fecad763..0ef4ac7fb0 100644 --- a/firmware/util/efilib2.cpp +++ b/firmware/util/efilib2.cpp @@ -39,58 +39,3 @@ efitime_t Overflow64Counter::update(uint32_t value) { return state.highBits + state.lowBits; } #endif - -// todo: make this a macro? always inline? -efitime_t Overflow64Counter::get() { -#if EFI_PROD_CODE - bool alreadyLocked = lockAnyContext(); - efitime_t localH = state.highBits; - uint32_t localLow = state.lowBits; - - uint32_t value = GET_TIMESTAMP(); - - if (value < localLow) { - // new value less than previous value means there was an overflow in that 32 bit counter - localH += 0x100000000LL; - } - - efitime_t result = localH + value; - - if (!alreadyLocked) { - unlockAnyContext(); - } - return result; -#else - - /** - * this method is lock-free and thread-safe, that's because the 'update' method - * is atomic with a critical zone requirement. - * - * http://stackoverflow.com/questions/5162673/how-to-read-two-32bit-counters-as-a-64bit-integer-without-race-condition - */ - efitime_t localH; - efitime_t localH2; - uint32_t localLow; - int counter = 0; - do { - localH = state.highBits; - localLow = state.lowBits; - localH2 = state.highBits; -#if EFI_PROD_CODE || defined(__DOXYGEN__) - if (counter++ == 10000) - chDbgPanic("lock-free frozen"); -#endif /* EFI_PROD_CODE */ - } while (localH != localH2); - /** - * We need to take current counter after making a local 64 bit snapshot - */ - uint32_t value = GET_TIMESTAMP(); - - if (value < localLow) { - // new value less than previous value means there was an overflow in that 32 bit counter - localH += 0x100000000LL; - } - - return localH + value; -#endif -}