[Home]Introspection

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org

Difference (from prior major revision) (no other diffs)

Added: 21a22,24
The interpreter also has a "last executed" variable, which contains the
serial number of the latest command to finish executing.


Changed: 25,26c28,30
those parameters are zero, the operation would proceed. If a non-zero
value is found, the interpreter would sleep and retry that field later.
those parameters are equal or less than "last executed", the interp knows
that the parameters are up to date, and the operation would proceed.
If not, the interpreter would sleep and retry that field later.

Changed: 34,67c38,46
would look at each parameter on its "params to write" list. If the
"latest writer" number matches the operation's serial number, it updates
the parameter, then sets "latest writer" to zero, to indicate that the
parameter is up to date. If the "latest writer" field is non-zero but
doesn't match the serial number of the current operation, it updates the
parameter but doesn't touch "latest writer". Some subsequent queued
operation will also be writing to that parameter, and it shouldn't be
marked as current until that operation finishes. (If an intermediate
operation needed the result of the current operation, the interpreter
would have stopped at that point and "latest writer" would contain the
serial number of the current operation.)

A complication occurs if the user aborts the program. If queued
commands are discarded, the parameters that those params would have
written to will still have non-zero "latest writer" values, which will
not get cleared. Any subsequent command that needs to read one of those
parameters would hang.

A possible solution would be to keep a "last completed" serial number in
the interpreter. Whenever a command finishes, it would update "last
completed". Commands would still write their own serial numbers into
the "latest writer" field of parameters that they intend to write when
they start, but they would NOT examine or zero the field when they
finish. The test for allowing an operation to be executed or queued
would be 'all params to read have "latest writer" fields less than or
equal to "last completed" ', instead of 'all params to read have "latest
writer" fields set to zero'. With this arrangement, the only thing
needed when aborting or flushing the queue is to set "last completed" to
the current serial number, then increment the current number.

The second arrangement is better in a number of ways - the command
finishing code (which is probably realtime) doesn't need access to the
"latest writer" fields of the entire parameter list, it only needs to be
able to set "last completed".
would update the interpreter's "last executed" variable. This is where I get
a little fuzzy. Suppose operation 10 is queued, and operations 11 thru 20
are not (simple math expressions). If 11 thru 18 do not depend on anything
that is written by 10, they can (and should) execute _before_ 10 finishes.
If 19 does depend on something that 10 writes, it will have to wait until
10 completes. In particular, it will wait until "last executed" is greater
or equal to 10. But if we allow 11 thru 18 to update "last executed" before
10 finishes, we have a problem. I know this can be solved, I just don't have
a nice O(1) solution at the moment.

Introspection

If we want probe results (for example) to be available in parameters, we need a way to ensure that the interpreter doesn't read ahead and use the parameter value before the probe move finishes.

Here is one possible solution to that:

Every canonical command has two lists associated with it, a list of parameters that it wants to read, and a list of parameters it wants to write. G-code lines of the form #100 = [#100+#101*2] also have lists, which are created on the fly when the expression is parsed - in this case it reads parameters 100 and 101, and writes parameter 100.

Every canonical command issued, as well as every expression executed, is given a serial number, a 64 bit integer. That is large enough to ensure that the numbers will be monotonically increasing during any run.

Each parameter has associated with it a "latest writer" field, which accepts a serial number.

The interpreter also has a "last executed" variable, which contains the serial number of the latest command to finish executing.

In the interpreter, when it is time to evaluate an expression, or to execute a canonical, the code would loop through the list of "params to be read" for that operation. If the "latest writer" fields for each of those parameters are equal or less than "last executed", the interp knows that the parameters are up to date, and the operation would proceed. If not, the interpreter would sleep and retry that field later.

Once the operation is allowed to start, it would write its own serial number into the "latest writer" fields of every parameter on its "params to write" list. That would force subsequent operations that want to read those parameters to wait.

Once an operation finishes (which may be much later due to queuing), it would update the interpreter's "last executed" variable. This is where I get a little fuzzy. Suppose operation 10 is queued, and operations 11 thru 20 are not (simple math expressions). If 11 thru 18 do not depend on anything that is written by 10, they can (and should) execute _before_ 10 finishes. If 19 does depend on something that 10 writes, it will have to wait until 10 completes. In particular, it will wait until "last executed" is greater or equal to 10. But if we allow 11 thru 18 to update "last executed" before 10 finishes, we have a problem. I know this can be solved, I just don't have a nice O(1) solution at the moment.

I just realized that assignments don't need "params to write", since they are executed entirely in the interpreter. The need "params to read" to ensure that they are using up-to-date input values, but their outputs are guaranteed to be written to the parameters before the next statement starts. Only queued items need to mark their "params to write" with their serial numbers.

Another thought - this could be used to implement pre- and post-conditions. If we dedicate a parameter to each possible condition, then operations that need to have a condition satisified simply list that parameter under their "params to read". Likewise, operations that make a condition true would list that parameter under "params to write".


LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org
This page is read-only. Follow the BasicSteps to edit pages. | View other revisions
Last edited May 26, 2008 6:06 pm by Jmkasunich (diff)
Search:
Published under a Creative Commons License