View unanswered posts | View active topics It is currently Mon Oct 21, 2019 7:22 pm






Reply to topic  [ 11 posts ] 
Multitasking and parameterized functions 
Author Message
Rookie

Joined: Mon Jan 04, 2010 10:51 am
Posts: 15
Location: Portugal
Post Multitasking and parameterized functions
Hi all

If I have a parameterized function and I call that function simultaneously from two different tasks, the parameters are (or may be) corrupted by the different calls.

For example, consider the following code:

Code:
void EnterWaitLoop()
{
  while ( true )
    wait1Msec( 500 );
}
int ReturnTheSameAfterAWhile( int iAux)
{
  wait1Msec( 500 );
  return iAux;
}
task task1()
{
  int iShouldBeOne = ReturnTheSameAfterAWhile ( 1 );
  nxtDisplayTextLine ( 0 , "should be 1: %d" , iShouldBeOne );
  EnterWaitLoop();
}
task task2()
{
  wait1Msec( 100 );
  int iShouldBeTwo = ReturnTheSameAfterAWhile ( 2 );
  nxtDisplayTextLine ( 4 , "should be 2: %d" , iShouldBeTwo );
  EnterWaitLoop();
}
task main () {
  StartTask ( task1);
  StartTask ( task2);
  EnterWaitLoop();
}




The values I get are:
Should be 1: 2
Should be 2: 2

Because the second call corrupted the value that the first call had passed.

Is this a bug, or by design? What I wanted was to have four different tasks monitoring the four sensor port simultaneously. However this implies calling parameterized functions at the same time, so am I going on the wrong direction?

Miguelb


Mon Jan 11, 2010 8:53 pm
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Multitasking and parameterized functions
Functions in ROBOTC are not reentrant. You will need to make sure no other task calls this function when another is already at it. You can wrap sensitive code inside a HogCPU() and releaseCPU() calls. That will make the current calling task claim the CPU all for its self, so no other task will be able to get access to it. If your function is very short, then this will not pose a significant issue. Semaphores and mutex operations are coming to ROBOTC, soon.

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 12, 2010 2:40 am
Profile WWW
Rookie

Joined: Sun Jan 11, 2009 3:40 am
Posts: 4
Location: Taiwan
Post Re: Multitasking and parameterized functions
You would get the following warning message after compiled:
*Warning*:Use 'inline' to avoid possible simultaneous variable memory access conflicts for
subroutine 'ReturnTheSameAfterAWhile' called from multiple tasks 'task1' and 'task2'?

Simply make the function INLINE:
inline int ReturnTheSameAfterAWhile( int iAux)
{
wait1Msec( 500 );
return iAux;
}

It will copy the function code for each call, i.e., separated memory spaces.


Tue Jan 12, 2010 6:55 am
Profile
Rookie

Joined: Mon Jan 04, 2010 10:51 am
Posts: 15
Location: Portugal
Post Re: Multitasking and parameterized functions
Aleon - Thanks - the inline suggestion is just what the kind of solution i was looking for.
However, my real problem is in calling writeI2C function that resides in common.h. This function is not marked as inline and so will have this problem. Should I rewrite the function inside my code, marked as inline? If so, do I also need to rewrite all the functions that are called by this function and are not marked inline? Is there a better way to do that?

Xander - In my scenario i can't HogCPU, because what I want is preciselly to allow to call a function ( writeI2C) in different ports simultaneously, so that readings in different ports can be taken (almost) simultaneously, and not in sequence

Miguelb


Tue Jan 12, 2010 9:13 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Multitasking and parameterized functions
common.h is part of the 3rd party driver suite and they are not thread safe (I should know, I am the author). If you sequence the calls from a single thread to poll all the sensors and store these values in a few variables, you will have the same effect. You don't really gain anything by doing these requests in parallel.

What sensors are you using?

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 12, 2010 9:33 am
Profile WWW
Rookie

Joined: Mon Jan 04, 2010 10:51 am
Posts: 15
Location: Portugal
Post Re: Multitasking and parameterized functions
I've been testing a bit with the hi-technic compass sensor, and it takes on average 7ms to call the write2IC method. In the worst case scenario I may have 4 I2C sensors connected to the nxt (I am not considering muxes). Assuming that they all have the same 7ms (a leap of faith, for now) this means I have around 21ms between first and last readings - and that the whole reading cycle takes around 28ms.

Right now I am only studying the maximum polling frequency I can get using RobotC, and so I tried going on to multitasking, thinking that the time to get the I2C bus ready should be independent between different ports (is it?), and so maybe the multitasking could allow me to have a reading cycle of around only 7ms, eventually using timers and waits to synchronize the different tasks and to read all the sensors "simultaneously".

Anyway, even if it is not possible to do this parallel polling for me this really paid off because now I understand better what happens in an environment with global allocations instead of a stack and I can better adapt my coding to this reality within robotc, besides preventing possible bugs when I eventually start using multitasking.


Just a curiosity (it's not allways that we have the privilege to debate this kind of issues with the real authors of the code - I apologize if this is not the correct forum to debate this):
why didn't you made the 3rd party drivers suite thread safe? Is there any negative impact on using inline functions instead of "normal" functions? Or am I simply completelly off on this idea? As it is now isn't there a risk that someone inadvertently calls some of the functions from different tasks and gets mixed up results? For what I see there are a few "waits" inside those functions that may easilly allow preemption to happen and to ruin the "call stack" on a multitasking environment...


Tue Jan 12, 2010 11:02 am
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Multitasking and parameterized functions
Quote:
Assuming that they all have the same 7ms (a leap of faith, for now) this means I have around 21ms between first and last readings - and that the whole reading cycle takes around 28ms.

7ms is about right. Under normal circumstances I can do about 133 I2C calls per second, that's a request + reply. More info regarding the I2C speeds ROBOTC is capable of can be found here: [LINK] and here: [LINK].

When ROBOTC starts getting things like mutexes and other operators, I can start working on making some of the functions more thread safe. I also have plans to make at least a selection of the sensor drivers auto-polled. No dead line on either of those.

Quote:
why didn't you made the 3rd party drivers suite thread safe? Is there any negative impact on using inline functions instead of "normal" functions? Or am I simply completelly off on this idea? As it is now isn't there a risk that someone inadvertently calls some of the functions from different tasks and gets mixed up results? For what I see there are a few "waits" inside those functions that may easilly allow preemption to happen and to ruin the "call stack" on a multitasking environment...

From what I understand, ROBOTC does not have local variables that are uniquely instanced each time you call a function. That makes it hard to make a function that is thread safe, unless you inline it, which is really horrible for program space. Inlining functions can also lead to other weird compiler issues. I've been meaning to write a tutorial about my drivers, but I just haven't gotten around to it.

Some other things of note:
  • Although most HiTechnic sensors will work perfectly fine at higher speeds, they're not certified for anything over sensorLowSpeed. Using a higher clock speed will drastically cut down on the transaction time, though (see previously linked articles) and you could poll more frequently. sensorI2CCustomFastSkipStates uses a 30Khz clock speed instead of 10Khz. If you experience issues with your sensors, just revert to sensorLowSpeed. Don't bother with sensorI2CCustomFast. The Ultrasound sensor will not work at the higher speeds either, only with the built-in one.
  • Instead of using a wait statement, you can also opt to use EndTimeSlice(); I am going to start changing my code where this is possible.

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 12, 2010 12:22 pm
Profile WWW
Rookie

Joined: Mon Jan 04, 2010 10:51 am
Posts: 15
Location: Portugal
Post Re: Multitasking and parameterized functions
OK

What about mindstorm IR distance sensors - can they handle higher frequencies? Is it dangerous for me to try out different values - can I damage the sensors, or will they simply fail if they can't handle the clock frequency?

Does someone have an idea when multitask sync primitives will be part of Robotc? (Next week/month/year?)


Tue Jan 12, 2010 3:21 pm
Profile
Site Admin
Site Admin
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Post Re: Multitasking and parameterized functions
Quote:
What about mindstorm IR distance sensors - can they handle higher frequencies? Is it dangerous for me to try out different values - can I damage the sensors, or will they simply fail if they can't handle the clock frequency?

You will not damage your sensors. The only possible problems you might get is a weird reading or none at all (bus error). The only thing you're changing is the bus speed, nothing else. Note that most sensors will work just fine at the higher speeds. HiTechnic doesn't forbid it, they just don't support it :) Mindsensors sensors should work just fine as well.

Quote:
Does someone have an idea when multitask sync primitives will be part of Robotc? (Next week/month/year?)

Real Soon Now(tm). I believe parts of it have already been implemented but it's not ready for main stream consumption. There is no set date :)

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Tue Jan 12, 2010 3:30 pm
Profile WWW
Rookie
User avatar

Joined: Thu Jun 26, 2008 11:27 am
Posts: 22
Location: Johannesburg, South Africa
Post Re: Multitasking and parameterized functions
Hi and Happy New Year

Using inline would be fine except it doesn't work anymore - at least not for functions that return a value.

Try:

inline bool result (int x)
{
return x == 1;
}
task main()
{
bool y = result(2);
}
Won't even compile. Get an error:
'Empty 'no-void' function not allowed. 'return' statement is required

(can't seem to copy error messages either)


Wed Jan 13, 2010 4:25 pm
Profile WWW
Rookie

Joined: Mon Jan 04, 2010 10:51 am
Posts: 15
Location: Portugal
Post Re: Multitasking and parameterized functions
**ugh** - back to square one.

Luckily Xander's suggestion payed off and now I can read I2C sensors in 2ms, so my bottleneck should be somewhere else and for now I don't need to go to multitask. In case I really need multitask polling i'm thinking on either waiting for Xander's multithread library, of if I need it before it is ready, i'll try and use normal functions passing all required variables by reference, allocating them at the beggining of each task. Should be a pain to develop and read that kind of code, though...


Sat Jan 16, 2010 5:54 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 11 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.