Issue with task system - tasks will run exactly twice (re-post once) - c

I've attempted to write a simple task system for my AVR. The code for this is here. (Sadly, this is also the MWE.)
The basic idea behind the system is that a periodic timer interrupt sets a flag, which the main application loop then checks in order to run a task. The task processing function is re-entrant, so will be executed exactly once per iteration for each pending task:
while (1) {
if (flTask) {
flTask = task_process_next();
}
// Do other awesome stuff in the loop
}
In order to keep the design simple, a task which wants to run periodically is required to re-post itself.
So a simple heartbeat task might be added like this:
task_add(heartbeat_task, 0);
And its code might look like this:
void heartbeat_task(void)
{
task_add(heartbeat_task, 10000); // Re-post task
led_toggle(LEDGreen);
xbee_send_heartbeat(BASE_STATION_ID);
}
My problem is this: each periodic task will run exactly twice.
I have confirmed through toggling pins (as you can see in the code I linked to) that during each task's first and repeat execution the task_add method is called.
However, despite apparently adding the task the second time, it never runs.
I have further tried simplifying the code in task_process_next considerably (including by adding a loop to process all tasks in one call, and by changing the run condition to ignore overflow). Neither of these modifications proved successful.
My question is this: have I messed up some detail of my linked-list implementation which could cause re-posted tasks to be ignored?
In particular, have I accidentally made it so that nodes in the list can be skipped over without being evaluated or run?
I understand that it is difficult to debug this sort of problem without running on the hardware, but I'm hoping that another set of eyes will see what I've missed.
I'm happy to provide any additional information / do any tests which are necessary.

The queue was being corrupted when a task at its end was removed:
if (prev) {
prev->next = task->next;
} else {
tasks.head = task->next;
}
// Adding these lines fixed the problem
if (task == tasks.tail) {
tasks.tail = prev;
}

Related

Why is my synchronous code executing asynchronously?

I'm trying to run some synchronous function which should wait for a certain time and then return control. But for some reason, it keeps executing asynchronously, or at least that's how it looks.
This is the code:
function pause(ms) {
var dt = new Date();
while (new Date() - dt <= ms) {
/* Do nothing */
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
this immediately shows the following in the console:
start calculation..
calculation finished!
There is no delay at all, as if the pause function is executed asynchronously.
I've tried 3 different versions of the pause function, it doesn't make any difference.
You can see this in the sandbox I put the code in.
(you must go to preferences - sandbox.config.json and turn of "Infinite loop protection" for it to work)
Why isn't the code running synchronously, first showing the "start calculation..." message, and then the second message after a 3 second delay?
Is there a better way to simulate running a time-expensive synchronous function?
Since my question has only been partially answered, I will provide the solution myself, in case other people have similar issues:
First of all, this code now works as intended in the console of Chrome, Chromium and Firefox. It didn't before, so perhaps there's been an upgrade to the javascript engine in this regard.
When running the code in the provided CodeSandbox though, it still logs the two lines simultaneously, after a 3 seconds delay.
As people have pointed out, 2 things could possibly be the cause of this:
the compiler removing empty loops
the console messages not refreshing as long as the loop is running
This code will fix both issues:
function pause(ms, start=new Date()) {
while (new Date() - start <= ms) {
setTimeout(()=>pause(ms,start))
}
}
console.log("start calculation..");
pause(3000);
console.log("calculation finished!");
Calling a SetTimeout (even with a 0 ms delay) will cause the rest of the code execution (a recursive function call) to be thrown back on the event loop for later processing, after allowing for the execution of event callbacks first. This ensures other events - such as logging of the console - will not be blocked.
It also puts some actual code inside the loop, so that the loop will not be removed by any compiler code optimisation.

Swift threading issue in Array

In my project, have a data provider, which provides data in every 2 milli seconds. Following is the delegate method in which the data is getting.
func measurementUpdated(_ measurement: Double) {
measurements.append(measurement)
guard measurements.count >= 300 else { return }
ecgView.measurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.setNeedsDisplay()
}
guard measurements.count >= 50000 else { return }
let olderMeasurementsPrefix = measurements.count - 50000
measurements = Array(measurements.dropFirst(olderMeasurementsPrefix))
print("Measurement Count : \(measurements.count)")
}
What I am trying to do is that when the array has more than 50000 elements, to delete the older measurement in the first n index of Array, for which I am using the dropFirst method of Array.
But, I am getting a crash with the following message:
Fatal error: Can't form Range with upperBound < lowerBound
I think the issue due to threading, both appending and deletion might happen at the same time, since the delegate is firing in a time interval of 2 millisecond. Can you suggest me an optimized way to resolve this issue?
So to really fix this, we need to first address two of your claims:
1) You said, in effect, that measurementUpdated() would be called on the main thread (for you said both append and dropFirst would be called on main thread. You also said several times that measurementUpdated() would be called every 2ms. You do not want to be calling a method every 2ms on the main thread. You'll pile up quite a lot of them very quickly, and get many delays in their updating, as the main thread is going to have UI stuff to be doing, and that always eats up time.
So first rule: measurementUpdated() should always be called on another thread. Keep it the same thread, though.
Second rule: The entire code path from whatever collects the data to when measurementUpdated() is called must also be on a non-main thread. It can be on the thread that measurementUpdated(), but doesn't have to be.
Third rule: You do not need your UI graph to update every 2ms. The human eye cannot perceive UI change that's faster than about 150ms. Also, the device's main thread will get totally bogged down trying to re-render as frequently as every 2ms. I bet your graph UI can't even render a single pass at 2ms! So let's give your main thread a break, by only updating the graph every, say, 150ms. Measure the current time in MS and compare against the last time you updated the graph from this routine.
Fourth rule: don't change any array (or any object) in two different threads without doing a mutex lock, as they'll sometimes collide (one thread will be trying to do an operation on it while another is too). An excellent article that covers all the current swift ways of doing mutex locks is Matt Gallagher's Mutexes and closure capture in Swift. It's a great read, and has both simple and advanced solutions and their tradeoffs.
One other suggestion: You're allocating or reallocating a few arrays every 2ms. It's unnecessary, and adds undue stress on the memory pools under the hood, I'd think. I suggest not doing append and dropsFirst calls. Try rewriting such that you have a single array that holds 50,000 doubles, and never changes size. Simply change values in the array, and keep 2 indexes so that you always know where the "start" and the "end" of the data set is within the array. i.e. pretend the next array element after the last is the first array element (pretend the array loops around to the front). Then you're not churning memory at all, and it'll operate much quicker too. You can surely find Array extensions people have written to make this trivial to use. Every 150ms you can copy the data into a second pre-allocated array in the correct order for your graph UI to consume, or just pass the two indexes to your graph UI if you own your graph UI and can adjust it to accommodate.
I don't have time right now to write a code example that covers all of this (maybe someone else does), but I'll try to revisit this tomorrow. It'd actually be a lot better for you if you made a renewed stab at it yourself, and then ask us a new question (on a new StackOverflow) if you get stuck.
Update As #Smartcat correctly pointed this solution has the potential of causing memory issues if the main thread is not fast enough to consume the arrays in the same pace the worker thread produces them.
The problem seems to be caused by ecgView's measurements property: you are writing to it on the thread receiving the data, while the view tries to read from it on the main thread, and simultaneous accesses to the same data from multiple thread is (unfortunately) likely to generate race conditions.
In conclusion, you need to make sure that both reads and writes happen on the same thread, and can easily be achieved my moving the setter call within the async dispatch:
let ecgViewMeasurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.measurements = ecgViewMeasurements
self.ecgView.setNeedsDisplay()
}
According to what you say, I will assume the delegate is calling the measuramentUpdate method from a concurrent thread.
If that's the case, and the problem is really related to threading, this should fix your problem:
func measurementUpdated(_ measurement: Double) {
DispatchQueue(label: "MySerialQueue").async {
measurements.append(measurement)
guard measurements.count >= 300 else { return }
ecgView.measurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.setNeedsDisplay()
}
guard measurements.count >= 50000 else { return }
let olderMeasurementsPrefix = measurements.count - 50000
measurements = Array(measurements.dropFirst(olderMeasurementsPrefix))
print("Measurement Count : \(measurements.count)")
}
}
This will put the code in an serial queue. This way you can ensure that this block of code will run only one at a time.

How to determine the (real) cycle time of an AUTOSAR Runnable

I have seen quite a lot of code that uses the cycle time of the Runnable for implementing some timer/timeout. The problem is that if someone decides to change the cycle time of this Runnable, the timer will be incorrect.
Example:
#define FOO_TIMER_100MS_REACHED (10U)
FUNC(void, FOO_CODE) FOO_Cycle_10ms( void )
{
static uint8 t = 0;
if( t < FOO_TIMER_100MS_REACHED )
{
t++;
}
else
{
; /* 100ms elapsed - do whatever is necessary */
}
}
So, how can I determine the cycle time of periodically triggered function FOO_Cycle_10ms from inside this Runnable?
In respect to the example above I'm looking for something like:
#define FOO_TIMER_100MS_REACHED ((uint8)(100U / CYCLE_TIME_FOO_Cycle_10ms))
The problem is that if someone decides to change the cycle time of this Runnable, the timer will be incorrect.
But can that actually happen? The software component description (SWCD) is always strongly coupled with the implementation. If somebody would change e.g. the runnable name in the SWCD or remove an access point, the code wouldn't compile too.
Other parameters like the runnable to task mapping can be changed by the integrator in a later development stage, but the period is part of the SWCD and thus also coupled with the implementation.
So, IMHO the described issue should not occour. If this does't answer your question, please provide more information about the actual use case.
Well, the SWCD is actually your contract, that should be discussed on changes with the responsible of the SWCD and the developer. If not, then your process is flawed.
On the other side, there are some ways:
Maybe you can create an Constant value from your SWCD Timing Event period
Create a ClientServer Interface to the TimeService (Tm) Module and let it setup. The Tm allows some handy SW timers backed by some GPT Predef Timers
Create a ClientServer interface with StbM-ServiceNeeds to your SWCD.
Then you should be able to access the Synchronized Time Base.
I had the same discussion ones, because this actually happened for a hot-fix.
We saw a potential solution in feeding Os_Service, see SWS_Os_00560, into the components measuring time, but never really tried it.
The Stbm solution we saw also, because we did not have the module in the respective project.

threadpools - boss/worker vs peer (workcrew) models

I'm aiming to use a threadpool with pthreads and am trying to choose between these two models of threading and it seems to me that the peer model is more suitable when working with fixed input, whereas the boss/worker model is better for dynamically changing work items. However, I'm a little unsure of how exactly to get the peer model to work with a threadpool.
I have a number of tasks that all need to be performed on the same data set. Here's some simple psuedocode for how I would look at tackling this:
data = [0 ... 999]
data_index = 0
data_size = 1000
tasks = [0 ... 99]
task_index = 0
threads = [0 ... 31]
thread_function()
{
while (true)
{
index = data_index++ (using atomics)
if index > data_size
{
sync
if thread_index == 0
{
data_index = 0
task_index++
sync
}
else
{
sync
}
continue
}
tasks[task_index](data[index])
}
}
(Firstly, it seems like there should be a way of making this use just one synchronisation point, but I'm not sure whether that's possible?)
The above code seems like it will work well for the case where the the tasks are known in advance, though I guess a threadpool is unnecessary for this particular problem. However even if the data items are still predefined across all tasks, if the tasks are not known in advance, it seems like the boss/worker model is better suited? Is it possible to use the boss/worker model but still allow the tasks to be picked up by the threads themselves (as above), where the boss essentially suspends itself until all tasks are complete? (Maybe this is still termed the peer model?)
Final question is regarding the synchronisation, barrier or condition variable and why?
If anyone can make any suggestions as to how better to approach this problem or even to poke holes in any of my assumptions, that would be great? Unfortunately I'm restricted from using a more higher-level library such as tbb for tackling this.
Edit: I should point out in case this isn't clear, each task needs to be completed in it's entirety before moving onto the next.
I'm a bit confused by your description here, hope the below is relevant.
I always looked at this pattern and found it very useful: The "boss" is responsible for detecting work and dispatching it to a worker pool based on some algorithm, from that time on, the worker is independent.
In this scenario, the worker is always waiting for work, not aware of any other instance, process requests and when it finishes, may trigger a notification of completion.
This has the advantage of good separation between the work itself and the algorithm that balance between the threads.
The other option is for the "boss" to maintain a pool of work items, and the workers to always pick them up as soon as they are free. But I guess this is more complex to implement and requires a larger amount of synchronization. I do not see the benefit of this second approach over the previous one.
Control logic and worker state is maintained by the "boss" in both scenarios.
As the paralleled work is done on a task, the "boss" "object" is handling a task, in a simple implementation, this "boss" blocks until a task is finished, allowing to call the next "boss" in line.
Regarding the Sync, unless I'm missing here something, you only need to sync once for all the workers to finish and this sync is done at the "boss" where the workers just send notifications that they finished.

Create a non-blocking timer to erase data

Someone can show me how to create a non-blocking timer to delete data of a struct?
I've this struct:
struct info{
char buf;
int expire;
};
Now, at the end of the expire's value, I need to delete data into my struct. the fact is that in the same time, my program is doing something else. so how can I create this? even avoiding use of signals.
It won't work. The time it takes to delete the structure is most likely much less than the time it would take to arrange for the structure to be deleted later. The reason is that in order to delete the structure later, some structure has to be created to hold the information needed to find the structure later when we get around to deleting it. And then that structure itself will eventually need to be freed. For a task so small, it's not worth the overhead of dispatching.
In a difference case, where the deletion is really complicated, it may be worth it. For example, if the structure contains lists or maps that contain numerous sub-elements that must be traverse to destroy each one, then it might be worth dispatching a thread to do the deletion.
The details vary depending on what platform and threading standard you're using. But the basic idea is that somewhere you have a function that causes a thread to be tasked with running a particular chunk of code.
Update: Hmm, wait, a timer? If code is not going to access it, why not delete it now? And if code is going to access it, why are you setting the timer now? Something's fishy with your question. Don't even think of arranging to have anything deleted until everything is 100% finished with it.
If you don't want to use signals, you're going to need threads of some kind. Any more specific answer will depend on what operating system and toolchain you're using.
I think the motto is to have a timer and if it expires as in case of Client Server logic. You need to delete those entries for which the time is expired. And when a timer expires, you need to delete that data.
If it is yes: Then it can be implemented in couple of ways.
a) Single threaded : You create a sorted queue based on the difference of (interval - now ) logic. So that the shortest span should receive the callback first. You can implement the timer queue using map in C++. Now when your work is over just call the timer function to check if any expired request is there in your queue. If yes, then it would delete that data. So the prototype might look like set_timer( void (pf)(void)); add_timer(void * context, long time_to_expire); to add the timer.
b) Multi-threaded : add_timer logic will be same. It will access the global map and add it after taking lock. This thread will sleep(using conditional variable) for the shortest time in the map. Meanwhile if there is any addition to the timer queue, it will get a notification from the thread which adds the data. Why it needs to sleep on conditional variable, because, it might get a timer which is having lesser interval than the minimum existing already.
So suppose first call was for 5 secs from now
and the second timer is 3 secs from now.
So if the timer thread only sleeps and not on conditional variable, then it will wake up after 5 secs whereas it is expected to wake up after 3 secs.
Hope this clarifies your question.
Cheers,

Resources