5

I am looking for a solution that is fast and still readable. I have to do this in C but the code will be static in the end, which mean I could use any tool to generate it.

I have a task which runs cyclically and calls different functions also cyclically

Main functions cycle is 1.

Function a has also cycle 1. So the main function calls it every time

Function b has cycle 2. Main function calls it every second cycle.

Function c has cycle 2.

Function d has cycle 4.

Function e has cycle 4.

Function f has cycle 4.

Function g has cycle 4.

... many more ....

Function X has cycle 500.

If we have many functions that run in the same cycle we try to distribute them.
So for function b we would call it in one cycle and c in the other. Distributing the load evenly.
Similar for d to g. Each one gets called in a different cycle.

My current implementation is very bad.
Every developer who had to add their task to main function calculates their on modulo and calls when needed. This leads to a very unreadable code.

I was thinking of doing something like:

uint32 mod4 = timer % 4;
bool fourth_1 = mod4 == 0;
bool fourth_2 = mod4 == 1;
bool fourth_3 = mod4 == 2;
bool fourth_4 = mod4 == 3;
bool second_1 = fourth_1 || fourth_3;
bool second_2 = fourth_2 || fourth_4;
/* and so on*/

But this seems cumbersome and too error prone specially as the highest cycle time is too high.

How to approach this kind of problem?

-Edit-

As asked i have compiled some information about the number of functions that i have:

  • 32 functions cycle 1
  • 9 functions cycle 2
  • 14 functions cycle 4
  • 3 functions cycle 8
  • 3 functions cycle 32
  • 3 functions cycle 40
  • 2 functions cycle 200
  • 2 functions cycle 400
  • Do you have a cut-off point, above which there are so few infrequently running tasks that their distribution doesn't really affect the overall load any more? – Bart van Ingen Schenau Aug 7 '14 at 9:54
  • @BartvanIngenSchenau I have added some more information. – RedX Aug 7 '14 at 10:21
2

The starting point for solving this problem is a data structure. The elements of the structure are nodes (structs) containing:

  • how to call one of the functions: a function pointer, any arguments, any other information
  • when to call a function: the 'cycle' as you put it.

You can use a flat list created at compile time, but then the entire list will have to be searched at least once for each cycle, and that may not be good for performance. A better approach is to add each node to a data structure designed to minimise searching. I would suggest a list for each cycle modulo, so 8 lists for the data given.

  • At initialisation time add each function node to the list(s) on which it should be called.
  • On each cycle simply go down the list(s) that are applicable, calling each function in turn.

Simple, testable, maintainable, extensible.

1

I may have your definition of "cycle" wrong. If "Cycle N" means that a method should be called when "timer" modulo N is 0, why not put pointers to those functions into a list or array of structure instances, and include in each structure, the "N" you want to modulo? Then after you increment "timer", check each structure to see if modulo N is 0. If so, invoke the function pointer.

After reading the problem description, I see that "Cycle N" has the additional restriction that only one function can run at once for a given N. To satisfy this requirement, keep an additional flag, "last run", in the structure mentioned above. Put each structure for a given N value in a separate list or array. This way you can mark the last run function, then unmark that one, run the next one, mark it, and so on, each time through.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.