With new parameters for the model, I was able to reproduce and confirm this behaviour, indeed on errors a thread who changed the cluster (T1) is preempted by a thread changing it to the opposite cluster (T2), T2 will succeed and T1 will fail as the current frequency is not the expected target.
Solving it with the use of counters works fine for above scenario, but might fail, with same T1 and T2 as the expected_count (local variable) and switch_count (static variable) is incremented for every thread, this means:
Thread 1: Preempted
* expected_count = 1, switch_count = 1
Thread 2: switch to little on CPU1
* expected_count = 2, switch_count = 2
* all CPUs move to little
Thread 1: switch to big on CPU0
* all CPUs move to big
Thread 1: check that CPU0 is big -> PASS
* No need to check that expected_count = 1, switch_count = 2
Thread 2: check that CPU1 is little -> FAIL
* expected_count = 2, switch_count = 2
So, T2 has no idea that another thread switched the cluster after itself and the counters don't reflect that it was the case.
AFAICS, affected_cpus doesn't reflect the non/dependency between cpu clusters but it seems that related_cpus does, so I could use that to tell the agitator to expect its changes to affect other cpus and make the thread transitions sequential through mutexes.
However, I don't see much gain from a sequential thread execution to the non-threaded option (that sequentially changes all CPUs). Perhaps I could add a warn print that the threaded option is not supported on the reference switcher, does anybody object?
With new parameters for the model, I was able to reproduce and confirm this behaviour, indeed on errors a thread who changed the cluster (T1) is preempted by a thread changing it to the opposite cluster (T2), T2 will succeed and T1 will fail as the current frequency is not the expected target.
Solving it with the use of counters works fine for above scenario, but might fail, with same T1 and T2 as the expected_count (local variable) and switch_count (static variable) is incremented for every thread, this means:
Thread 1: Preempted
* expected_count = 1, switch_count = 1
Thread 2: switch to little on CPU1
* expected_count = 2, switch_count = 2
* all CPUs move to little
Thread 1: switch to big on CPU0
* all CPUs move to big
Thread 1: check that CPU0 is big -> PASS
* No need to check that expected_count = 1, switch_count = 2
Thread 2: check that CPU1 is little -> FAIL
* expected_count = 2, switch_count = 2
So, T2 has no idea that another thread switched the cluster after itself and the counters don't reflect that it was the case.
AFAICS, affected_cpus doesn't reflect the non/dependency between cpu clusters but it seems that related_cpus does, so I could use that to tell the agitator to expect its changes to affect other cpus and make the thread transitions sequential through mutexes.
However, I don't see much gain from a sequential thread execution to the non-threaded option (that sequentially changes all CPUs). Perhaps I could add a warn print that the threaded option is not supported on the reference switcher, does anybody object?