42 lines
1.3 KiB
C++
42 lines
1.3 KiB
C++
/**
|
|
* @file efilib2.cpp
|
|
*
|
|
* @date Apr 14, 2014
|
|
* @author Andrey Belomutskiy, (c) 2012-2014
|
|
*/
|
|
|
|
#include "efilib2.h"
|
|
|
|
/**
|
|
* The main use-case of this class is to keep track of a 64-bit global number of CPU ticks from reset.
|
|
*
|
|
* stm32f4 hardware has a 32-bit Cycle Count Register (CYCCNT), which is incremented with every CPU cycle.
|
|
* With 32 bits and 168MHz speed this counter overflows every 4B/168M = 23 seconds. The job of this class is to
|
|
* keep track of the current CYCCNT value, detect these overflows, and provide a nice,
|
|
* clean 64 bit global cycle counter.
|
|
*
|
|
* In order for this to function, it's your responsibility to invoke offer() method at least once a second.
|
|
*/
|
|
Overflow64Counter::Overflow64Counter() {
|
|
currentBase = 0;
|
|
currentValue = 0;
|
|
}
|
|
|
|
uint64_t Overflow64Counter::get(uint32_t value, int isPrimaryThread) {
|
|
// this method is lock-free, only one thread is allowed to commit state
|
|
// these are local copies for thread-safery
|
|
// todo: this is still not atomic, so technically not thread safe.
|
|
uint32_t localValue = currentValue;
|
|
uint64_t localBase = currentBase;
|
|
if (value < localValue) {
|
|
// new value less than previous value means there was an overflow in that 32 bit counter
|
|
localBase += 0x100000000LL;
|
|
}
|
|
if (isPrimaryThread) {
|
|
currentValue = value;
|
|
currentBase = localBase;
|
|
}
|
|
|
|
return localBase + value;
|
|
}
|