How to completely free a timer(timer_list)? - c

I am working on an application with multiple timers. When the application starts, everything is just runs as standard, except I have some pointers point to the timer.
I will show a piece of sample code to clarify my purpose:
---------------------------init foo---------------------
init_timer(&timer1);//timer1 definition is outside the function, as struct timer_list timer1
timer1.expires = jiffies+SECONDS_TO_JIFFIES(5);
timer1.data = (unsigned long) data;
timer1.function = callback_foo;
timer1_pointer = &timer1;//timer1_pointer definition is outside the function, as struct timer_list *timer1_pointer
------------------the other function after init---------------
add_timer(timer1_pointer);
-------------------deinit---------------------------
del_timer_sync(&timer1);
It works fine in the beginning, however it will always crash at add_timer when the whole flow (deinit->init->the other function->...) runs again.
It makes me feel something is wrong in the deinit. Since delete timer only detach instead of delete. Rerun the flow may mesh up the timer list.
So are there any ways to safely free it? Or if you find any other mistakes I made?

OKļ¼Œsince no one answered, I just post some thoughts and I finally proved it truly the reason that trigger the crash.
It seems that, if the timer are required to be relaunched and deleted sometimes during a long run application, it is necessary to free/clean the timer_list. This del_timer_sync/del_timer not really delete it as I thought. Since the project I am working on is complicated, I guess some dude just make things messy and affect me..I will try to dig it later if I have time.

Related

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.

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

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;
}

Whats a Strong Argument against Variable Redundancy in c code

I work in safety critical application development. Recently as a code reviewer I complained against coding style shown below, but couldn't make a strong case against it. So what would be a good argument against such Variable redundancy/duplication, I am looking for cases where this might lead to problems or test cases which might fail, rather than just coding style.
//global data
// global data
int Block1Var;
int Block2Var;
...
//Block1
{
...
Block1Var = someCondition; // someCondition is an logical expression
...
}
//Block2
{
...
Block2Var = Block1Var; // Block2Var is an unconditional copy of Block1Var
...
}
I think a little more context would be helpful perhaps.
You could argue that the value of Block1Var is not guaranteed to stay the
same across concurrent access/modification. This is only valid if Block1Var
ever changes (ie is not only read). I don't know if you are concerned with
multi-threaded applications or not.
Readability is an important issue as well. Future code maintainers
don't want to have to trace around a bunch of trivial assignments.
Depends on what's done with those variables later, but one argument is that it's not future-proof. If, in the future, you change the code such that it changes the value of Block1Var, but Block2Var is used instead (without the additional change) later on, then this will result in erroneous behavior.
If the shown function context reaches a certain length (I'm assuming a lot of detail has been discarded to create the minimal reproducible example for this question), a good next step could be to create a new (sub-)function out of Block 2. This subfunction then should be started assigning Block1Var (-> actual parameter) to Block2Var (-> formal parameter). If there were no other coupling to the rest of the function, one could cut the rest of Block 2 and drop it as a function definition, and would only have to replace the assignment by the subfunction call.
My answer is fairly speculative, but I have seen many cases where this strategy helped me to mark useful points to split a complex function later during the development. Of course, this interpretation only applies to an intermediate stage of development and not to code that is stated to be "ready for release".

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,

Arrays in PowerBuilder

I have this code
n_userobject inv_userobject[]
For i = 1 to dw_1.Rowcount()
inv_userobject[i] = create n_userobject
.
.
.
NEXT
dw_1.rowcount() returns only 210 rows. Its so odd that in the range of 170 up, the application stop and crashes on inv_userobject[i] = create n_userobject.
My question, is there any limit on array or userobject declaration using arrays?
I already try destroying it after the loop so as to check if that will be a possible solution, but it is still crashing.
Or how can i be able to somehow refresh the userobject?
Or is there anyone out there encounter this?
Thanks for all your help.
First, your memory problem. You're definitely not running into an array limit. If I was to take a guess, one of the instance variables in n_userobject isn't being cleaned up properly (i.e. pointing to a class that isn't being destroyed when the parent class is destroyed) or pointing to a class that similarly doesn't clean itself up. If you've got PB Enterprise, I'd do a profiling trace with a smaller loop and see what is being garbage collected (there's a utility called CDMatch that really helps this process).
Secondly, let's face it, you're just doing this to avoid writing a reset method. Even if you get this functional, it will never be as efficient as writing your own reset method and reusing the same instance over again. Yes, it's another method you'll have to maintain whenever the instance variable list changes or the defaults change, but you'll easily gain that back in performance.
Good luck,
Terry.
I'm assuming the crash you're facing is at the PBVM level, and not a regular PB exception (which you can catch in your code). If I'm wrong, please add the exception details.
A loop of 170-210 iterations really isn't a large one. However, crashes within loops are usually the result of resource exhaustion. What we usually do in long loops is call GarbageCollect() occasionally. How often should it be called depends on what your code does - using it frequently could allow the use of less memory, but it will slow down the run. Read this for more.
If this doesn't help, make sure the error does not come from some non-PB code (imported DLL or so). You can check the stack trace during the crash to see the exception's origin.
Lastly, if you're supported by Sybase (or a local representative), you can send them a crash dump. They can analyze it, and see if it's a bug in PB, and if so, let you know when it was (or will be) fixed.
What I would normally do with a DataWindow is to create an object that processes the data in a row and call it for each row.
the only suggestion i have for this is to remove the rowcount from the for (For i = 1 to dw_1.Rowcount()) this will cause the code to recount the rows every time it uses one. get the count into a variable and then use the variable. it should run a bit better and be far more easy to debug.

Resources