0

So the following code I am using for a hacky production fix due to time constraints. Basically I have a static function that is called from many places, much more than intended and it is causing another section of the application to choke. So I thought I would come up with a quick fix to limit the calls to the overworked function to once every two seconds. This works just fine in x86 using clang or gcc.

#include <chrono>
#include <iostream>
#include <unistd.h>
#include <thread>

static void staticfunction()
{
    static std::mutex mutex;
    static auto t0(std::chrono::high_resolution_clock::now());
    std::unique_lock<std::mutex> lg_mutex(mutex, std::try_to_lock);
    if( lg_mutex.owns_lock())
    {
        auto t1 = std::chrono::high_resolution_clock::now();
        if( 2000 <= std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count() )
        {
            // Make a check in other section of application
            std::cout << "Check true after " << std::dec
                      << std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count()
                      << " ms.\n";
            t0 = std::chrono::high_resolution_clock::now();
        }
    }
}
int main()
{
    while(true) {
    std::thread t1(staticfunction);
    std::thread t2(staticfunction);
    std::thread t3(staticfunction);
    std::thread t4(staticfunction);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
}
return 0;

Prints Check true after 2000 ms. Check true after 2000 ms. Check true after 2002 ms. Check true after 2005 ms. ....

However, for our ARM controller I cross compiled using Linaro 7.1 and now the condition for the if stmt isn't satisfied until 10 seconds has passed. I was curious and compared against 1 second instead of two (duration_cast of ms vs seconds doesn't change anything) and if(1 <= ....count()) was true after half a second.

Is this a bug in the Linaro compiler? Or are clocks for our ARM controller off? Cross compile flags are -mcpu=cortex-a7 -mfloat-abi=hard -marm -march=armv7ve if that makes a difference

EDIT: multithreaded, same output.

JoeManiaci
  • 395
  • 1
  • 12
  • 1
    _"a hacky production fix due to time constraints."_ Notice how that's now causing problems and costing you time. – Lightness Races in Orbit Jan 08 '20 at 15:58
  • 1
    Define "ARM controller". What actually is it? – Lightness Races in Orbit Jan 08 '20 at 15:59
  • 1
    _"the condition for the if stmt isn't satisfied until 10 seconds has passed"_ First time? Every time? – Lightness Races in Orbit Jan 08 '20 at 16:00
  • 2
    Is this your whole testcase? Or do you have other threads doing work? – Lightness Races in Orbit Jan 08 '20 at 16:01
  • 1
    Have you checked how often it's actually getting invoked in the ARM version? Have you examined the actual values of `t0` and `t1`, or the period of the clock on ARM? – Useless Jan 08 '20 at 16:14
  • It's a proprietary controller based on cortex 7, @LightnessRacesBY-SA3.0 Still will be a fraction of the time to look into the 15 areas that call this method. In our logs it's pretty consistently logging it enters the if statement every 10 seconds. This static method is definitely accessed by multiple threads, let me guess, that's going to effect how t1 gets set. Should I use system_clock or steady_clock? – JoeManiaci Jan 08 '20 at 16:22
  • @Useless This static method is getting accessed many times a second when the expectation was for it to be called no more than once every two seconds. Which is why I've gone down this path. There is one main contributor to these calls, but I fear the calls from the other areas will still clobber the function on the receiving end. – JoeManiaci Jan 08 '20 at 16:27
  • @JoeManiaci You're probably going to want to look at all sorts of components of your board in order to hunt this down. If that's proprietary information we may not be able to help. – Lightness Races in Orbit Jan 08 '20 at 16:29
  • So, this _isn't_ the reproducible testcase and the one that is involves threads? We can't diagnose code we can't see. – Lightness Races in Orbit Jan 08 '20 at 16:30
  • @JoeManiaci If the function is called from multiple threads, then there is a data race because the static time point is not atomic. – eerorika Jan 08 '20 at 17:00
  • @eerorika https://stackoverflow.com/questions/8102125/is-local-static-variable-initialization-thread-safe-in-c11 – JoeManiaci Jan 08 '20 at 17:56
  • @JoeManiaci initialisation is different from assignment. Initialisation is atomic; the assignment is not, nor is the reading of the value. – eerorika Jan 08 '20 at 17:57
  • @eerorika What about? https://stackoverflow.com/questions/39127703/c-is-static-variable-initialization-with-atomic – JoeManiaci Jan 08 '20 at 18:11
  • @JoeManiaci Assignment and reading of static are not atomic. That post doesn't imply otherwise. – eerorika Jan 08 '20 at 18:24

0 Answers0