Problems with single thread serialization

Because of single thread serialization, something unexpected for the programmer happens.

1) You expect TaskA to be independent from TaskB, but it isn't. If you think it is a problem of resources of the computer, change the activity frequency of 1 of the two tasks.

Suggestion: A) let the programmer choose if single thread serialization is used or not. B) keep 1 thread for 1 activity policy for default. It will help less experienced user to avoid common errors. Experienced user can decide to "unleash" the power of STS if they want to.

2) after the "block" for 0.5 seconds, the "lost cycles" are executed all at once. In other words, updateHook is called 5 times in a row. This may have very umpredictable results. It could be desirable for some applications (filter with data buffer) or catastrophic in other applications (motion control loop).

Suggestion: C) let the user decide if the "lost cycles" or the PeriodicActivity need to be executed later or are defenitively lost.

using namespace std;
using namespace RTT;
using namespace Orocos;
 
TimeService::ticks _timestamp;
double getTime() { return TimeService::Instance()->getSeconds(_timestamp); }
 
class TaskA
    : public TaskContext
{
protected:
     PeriodicActivity act1;
public:
 
    TaskA(std::string name)
    : TaskContext(name),
      act1(1, 0.10, this->engine() )
    {
     //Start the component's activity:
    this->start();
    }  
    void updateHook()
    {
    printf("TaskA  [%.2f] Loop\n", getTime());
    }
};
 
class TaskB
    : public TaskContext
{
protected:
    int num_cycles;
    PeriodicActivity act2;
public:
     TaskB(std::string name)
    : TaskContext(name),
      act2(2, 0.10, this->engine() )
    {
    num_cycles = 0;            
    //Start the component's activity:
    this->start();
    }   
    void updateHook()
    {
    num_cycles++;
    printf("TaskB  [%.2f] Loop\n", getTime());
 
    // once every 20 cycles (2 seconds), a long calculation is done
    if(num_cycles%20 == 0)
    {
        printf("TaskB  [%.2f] before calling long calculation\n", getTime());
 
        // calculation takes longer than expected (0.5 seconds). 
        // it could be something "unexpected", desired or even a bug... 
        // it would not be relevant for this example.
        for(int i=0; i<500; i++) usleep(1000);
 
        printf("TaskB  [%.2f] after calling long calculation\n", getTime());
    }
    }
};
 
int ORO_main(int argc, char** argv)
{
    TaskA    tA("TaskA");
    TaskB    tB("TaskB");
 
    // notice: the task has not been connected. there isn't any relationship between them.
    // In the mind of the programmer, any of them is independent, because they have their own activity.
 
    // if one of the two frequency of the PeriodicActivities is changed, there isn't any problem, since they go on 2 separate threads.  
    getchar();
    return 0;
}