Subject:
|
Sharing variables and using expressions (was Re: NQC 2.0 and some math questions
|
Newsgroups:
|
lugnet.robotics.rcx.nqc
|
Date:
|
Tue, 19 Oct 1999 20:00:22 GMT
|
Viewed:
|
2450 times
|
| |
| |
I have discovered a somewhat non-intuitive feature of NQC (in my version, at
least, which is pre-2.0)
The statement:
var = (20 * var) / 21;
gets compiled into the following:
MUL var, 20 ; var = var * 20
DIV var, 21 ; var = var / 21
rather than the more standard:
SET tmp, var ; tmp = var
MUL tmp, 20 ; tmp = tmp * 20
DIV tmp, 21 ; tmp = tmp / 21
SET var, tmp ; var = tmp
The reason this matters is that the value of "var" might be read by another
task. The traditional rules for inter-process communication via shared
variables allow simple (non-mutex) variable sharing as long as there is at most
one task that writes to the variable. (If there is more than one writing task,
semaphores must be used).
However, this simple rule relies on some more fundamental (and implied) rules
known mainly to compiler writers, namely:
- each occurrance of a variable in a RHS (right-hand-side) context generates
at most one (atomic) read access, and
- each occurrance of a variable in an LHS (left-hand-side) context generates
at most one (atomic) write access.
Usually implementation of these rules is easy because there is a stack, some
registers, and/or some other type of storage that is saved and restored on each
task context switch. NQC failure to comply is understandable in view of the
restrictions of the firmware.
The good news is that programmers using NQC can avoid this problem (if they
wish) by explicitly breaking their expressions up into pieces that compile into
a single firmware opcode, thereby preventing NQC from second-guessing. Such a
programmer would explicitly rewrite my example as:
tmp = var;
tmp *= 20;
tmp /= 21;
var = tmp;
There are additional inter-task issues with temp variables, which I assume NQC
avoids. For example, a seperate pool of temp variables must be allocated for
each task, lest two tasks interfere with one another by sharing the same temp
variable. If you are concerned about such issues, you could rewrite all of your
expressions as single operations and allocate all your temp variables
explicitly. Of course, you need to follow the same rules, and make sure to give
each task its own set of temp variables.
In lugnet.robotics.rcx.nqc, Dave Baum writes:
> In article <37f16547.6612368@lugnet.com>, marcob@equalis.it wrote:
>
> > x = y % z
> >
> > is equivalent to (where w is an temporary integer):
> >
> > w = y / z;
> > x = y - z * w;
>
>
> That's exaclty what I was thinking of doing. Originally, the compiler had
> no way of allocating temp variables which is why code for % couldn't be
> emitted. The temp allocator is now pretty good, so I could emit the above
> sequence, but it just didn't occur to me until a few days ago.
>
> There is one subtle problem. The operations above won't happen
> atomically, so there are some concurrency issues. To be completely safe,
> I'd have to latch both y and z into temps as well. Without this, some
> truly weird stuff can happen. For example, lets say that intially y is a
> multiple of z, and then you decrement y in-between the computation of w
> and x. The result will be that x is negative. This is a result that is
> inconsistient with the decrement happening either before or after the
> entire mod calculation.
>
> My personal feeling on this, however, is that if you're running around
> changing y amd z in one task while calculating with them in another,
> you're just asking for trouble.
- Robert Munafo http://www.mrob.com/
LEGO: TC+++(8480) SW++ #+ S-- LS++ Hsp M+ A@ LM++ YB64m IC13
|
|
Message has 1 Reply:
Message is in Reply To:
| | Re: NQC 2.0 and some math questions
|
| (...) That's exaclty what I was thinking of doing. Originally, the compiler had no way of allocating temp variables which is why code for % couldn't be emitted. The temp allocator is now pretty good, so I could emit the above sequence, but it just (...) (25 years ago, 30-Sep-99, to lugnet.robotics.rcx.nqc)
|
16 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
This Message and its Replies on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|