The interpreter also has a "last executed" variable, which contains the|
serial number of the latest command to finish executing.
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.
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.