Mutex in NXC
Mutex in NXC
Been searching the 'net, reading the guides which came with the Bricx Center, etc and I still don't understand mutex.
Does it stop all activity in other tasks while in operation or just prevent the use of any resources used between the two mutex statements?
Advice would be appreciated (preferably in words of half a syllable) or directions to sources of info.
Does it stop all activity in other tasks while in operation or just prevent the use of any resources used between the two mutex statements?
Advice would be appreciated (preferably in words of half a syllable) or directions to sources of info.
A sophistical rhetorician, inebriated with the exuberance of his own verbosity, and gifted with an egotistical imagination that can at all times command an interminable and inconsistent series of arguments to malign an opponent and to glorify himself.
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: Mutex in NXC
Have you heard of the "talking spoon"? It is a general term referring to the method of keeping order (with a spoon), that gets passed around to different individuals. Each person can only talk when they have the spoon. There may be 10 people, but there is only one spoon. In this way, the "talk" will be limited to one person at a time. A mutex was described to me using the same concept. A mutex is a "spoon", and there are (for instance) 10 tasks running. Only the one that "holds" the "spoon" will be able to do anything. To get the "spoon" (mutex), you use the Acquire("mutex"); function ("mutex" is the name of the mutex you want to aquire). To pass the "spoon" to another task, use the Release("mutex"); function.
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: Mutex in NXC
Right, so it stops everything else working - thanks for such a fast response.
A sophistical rhetorician, inebriated with the exuberance of his own verbosity, and gifted with an egotistical imagination that can at all times command an interminable and inconsistent series of arguments to malign an opponent and to glorify himself.
Re: Mutex in NXC
To be exact, it only stops the task when it Acquires for something.
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
-
- Posts: 73
- Joined: 29 Sep 2010, 12:05
Re: Mutex in NXC
To be a little more exact, when one task acquires a mutex, any other tasks that try to acquire the same mutex are blocked until the first task releases the mutex. At that time, one of the blocked tasks will acquire the mutex and proceed. The other blocked tasks remain blocked.
Regards, Morton
Re: Mutex in NXC
Exactly right. However I wanted to point out that Mutexes are largely used behind-the-scenes by the NXC/NBC compiler so that you program does what you intend it to do when multiple tasks access the same resource. In all the NXC programming I have done I have never had to use a Mutex at the user level. Sure, there are likely legitimate reasons it would be needed, but generally it's not something you need to know about.m-goldberg wrote:To be a little more exact, when one task acquires a mutex, any other tasks that try to acquire the same mutex are blocked until the first task releases the mutex. At that time, one of the blocked tasks will acquire the mutex and proceed. The other blocked tasks remain blocked.
Re: Mutex in NXC
m-goldberg wrote:To be a little more exact...
What, level 1.5 exactness not good enough for you?ronmcrae wrote: Exactly right.
Basically, this is how mutexes could be implemented (to give the OP a little more understanding):
Code: Select all
#define mutex bool // so mutex is equivalent to saying bool
//typedef bool mutex; // if you're insane, you could also say this instead of the #define
#define FREE 0
#define USED 1
// Not using safecall, because that would imply recursion... I'll leave the geniuses to figure out that cryptic statement
/*safecall*/ inline void Acquire(mutex &var)
{
// Wait till var == FREE
while(var == USED);
// Claim it for the task that calls this
var = USED;
}
/*safecall*/ inline void Release(mutex &var)
{
var = FREE;
}
Here is how you would use it:
Code: Select all
mutex mMotorA;
task GoForward()
{
while(1)
{
Acquire(mMotorA);
OnFwd(OUT_A, 100);
Wait(1000);
Release(mMotorA);
}
}
task GoBackward()
{
while(1)
{
Acquire(mMotorA);
OnRev(OUT_A, 100);
Wait(1000);
Release(mMotorA);
}
}
task main()
{
// Start tasks
Precedes(GoForward, GoBackward);
}
Last edited by muntoo on 11 Jan 2011, 03:15, edited 1 time in total.
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: Mutex in NXC
Although, in that example, there aren't any wait functions, so it would change direction way too fast to go much of anywhere.muntoo wrote:Here is how you would use it:Code: Select all
mutex mMotorA; task GoForward() { while(1) { Acquire(mMotorA); OnFwd(OUT_A, 100); Release(mMotorA); } } task GoBackward() { while(1) { Acquire(mMotorA); OnRev(OUT_A, 100); Release(mMotorA); } } task main() { // Start tasks Precedes(GoForward, GoBackward); }
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: Mutex in NXC
Did you try running it? Although, I fixed my original code.mattallen37 wrote:Although, in that example, there aren't any wait functions, so it would change direction way too fast to go much of anywhere.
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
-
- Posts: 73
- Joined: 29 Sep 2010, 12:05
Re: Mutex in NXC
What you say here interests me. How would handle this situation?ronmcrae wrote:Exactly right. However I wanted to point out that Mutexes are largely used behind-the-scenes by the NXC/NBC compiler so that you program does what you intend it to do when multiple tasks access the same resource. In all the NXC programming I have done I have never had to use a Mutex at the user level. Sure, there are likely legitimate reasons it would be needed, but generally it's not something you need to know about.
Suppose you were thinking implementing a program that appeared to require the classic producer/consumer design pattern. That is, where two tasks share a global array as a data buffer which one tasked fills and the other task empties. AFAIK, the NXC will not recognize this situation as requiring a mutex, so the programmer would have to declare one and use Acquire and Release to implement the required critical sections.
Are you saying 1) you can always avoid using this design pattern or 2) you can always eliminate the explicit mutex by implementing the buffer sharing in a shared function protected by safecall?
Regards, Morton
Who is online
Users browsing this forum: No registered users and 15 guests