Or the programmer ensures only 1 task uses these singular resources at a time.
BTW This was accepted as a limitation way back when tasks were added.
Sure, then along came HUBEXEC and complete code swapping... with libraries in the mix, and larger more dynamic code.
Will programers really know only one task is using a mathop ? They can hope so...
I don't follow. You can use these instructions as before on the polling task. My proposal does not change a single line(character) of code in either Bills or your examples. They would work the same as before. And both would work instead of just one of them.
NOTE! I changed the "<>" to "==" in my post above!
Can you give a code example of one line polling on == or <> ?
Bill was using JNZ polling, and I was using JB31 polling, in the polling side.
@jmg
Are we talking apples and oranges? I think you have to reread the context of my reply to Chip. I'm not talking about software on the polling side of a scheduler. I'm talking about the logic of the TPAUSE/TYIELD/THOLD instruction. If changed it will allow both your and Bills implementation to work. And the SW designer can choose either pattern.
JB31 polling? Is that a new instruction suggestion?
A substitute for:
TESTB taskreg1,#31 WZ
IF_NZ JMP @somewhere
There has been 2 suggestions, test for zero, or test for bit31.
Chips has implemented TCHECK (the old TPAUSE) that sets D with a value, and then waits for D to be reset to zero. TRESUME is no longer required.
Ahle2 has suggested that TCHECK also internally store the D value, and then compare this with the new D value looking for not equal before resuming automatically.
There has been 2 suggestions, test for zero, or test for bit31.
Chips has implemented TCHECK (the old TPAUSE) that sets D with a value, and then waits for D to be reset to zero. TRESUME is no longer required.
Ahle2 has suggested that TCHECK also internally store the D value, and then compare this with the new D value looking for not equal before resuming automatically.
Yes, I'm up to speed with those changes and suggestions.
My question was based on code referenced a few pages back. See here
Edit: Got it...JB31 is a new two operand instruction suggestion.
If we implement it in sw then Parallax doesn't get stuck with USB ORG licenses for every prop sold, plus a lot of other costs. Sw is the wtg, with some hw support.
If we go with <> or == for the test on the task flag being passed back and forth doesn't that cause issues for the supervisor side?
The client task with TCHECK can sit and spin and wait for it to go to zero, get a bit31 set or change in value, that's fine and can be done with varying degrees of complexity. It's all atomic and within that instruction that remembers the initial state and recognizes the exit state. The client has no way to sit and spin and wait for a register to change...nor do we want a supervisor locked up inside an instruction, so it needs to compare and jump based on the compare.
The supervisor side, can very easily put zero in the register and go on it's way until it needs to poll again at that point, it knows it had put a zero in there and any change indicates a task did a TCHECK. If you go with a non-zero value and just look for a change, then the supervisor needs to retain that value in a register and perform 2 instructions (CMP and a jump) to see if has work to do.
If you go with bit 31 signaling, you need either another new instruction JB31...if we go this route, can't we just use positive and negative? If the register is negative, then the supervisor was the last to put something in and it doesn't need to do anything, if it's positive then the task was the last to put something in and it needs to do something. so the supervisor doesn't need a place to retain state of the last thing it sent to the client task.
Which now makes me wonder why (except for the extra instruction) the client task can't just
mov flag, <positive number> ' would be replaced by TCHECK to give single instruction for this
jp flag,#$
and the supervisor just:
jn flag,#checkedtask ' if it's still negative, last message was from supervisor to client
.
.
do stuff to handle task
.
.
jmptask <someplace for task to go next> ' only if you need to redirect
mov flag,<some negative value back to task> 'make it negative so client can resume at $+1 if no jmptask
.
.
checkedtask
.
do other supervisor stuff
.
I must be missing some feature/benefit because it seems too simple.
If we implement it in sw then Parallax doesn't get stuck with USB ORG licenses for every prop sold, plus a lot of other costs. Sw is the wtg, with some hw support.
As far as I know, SD has royalties per device, USB doesn't.
Cluso99, You talk as if Parallax doesn't need licenses at all. How many $$$$ they have invested in Altera Stratix boards (just for their Quartus license)?. And how many $$$$$ (five $ right?) they have spent for layout software?. Do you think that they make layout with open source software (magic or electric)?. They are already stuck with licenses, everywhere.
USB has a $4000 (or $5000) annual member license fee. And with this fee you get a usb VENDOR ID. I wonder what will be the VENDOR ID we will use in our P2 in case we finally have the SW USB protocol working. There is no point at all to make a SW USB implementation if later we cannot effectively use USB in our products just because we don't have a VENDOR ID. If we still need to use another IC for USB (FT232, CP2102, PL2303, HX2LP, AT90USB162 ... ), please skip USB, and go directly to next step (was it serdes or preemptive multitasking?).
How much money have been invested in P2? US $5,000,000 ? Nobody thinks that It is crazy that the last five hundred messages of this forum (that already has 6,000 messages and more than 3 years) are related to some features that can be found in workstation CPUs rather than a microcontroller? BTW, a microcontroller with 256 KB of memory, that will need to be clocked at 192MHz to handle a 16 year old 12mbps USB protocol.
- breakpoints should not take two longs
- system calls & waiting will happen a lot in hubexec code, so we save a lot of memory by using a 1 long instruction
TCHECK D,S/# 'Write S/# into D and jump to self. On subsequent iterations, don't write D, but jump to self if D <> 0.
This gets rid of the need for TRESUME. It takes one bit of state storage to track TCHECK now, so that we know if it's on its first or a subsequent iteration. On the first iteration, it writes S/# into D and jumps to itself. On subsequent iterations, it doesn't write D, but jumps to itself if D <> 0.
So, task A does a TCHECK to write a non-zero value into some register. Task B notices the non-0 value and can do whatever it wants about it, but can write 0 to the register to release Task A.
- breakpoints should not take two longs
- system calls & waiting will happen a lot in hubexec code, so we save a lot of memory by using a 1 long instruction
That's why I had the comment that the two instruction client sequence gets replaced by a TCHECK. If we use the TCHECK, the what am I missing by just using positive/negative?
Not arguing, "macths nichts" to me, just trying to understand implications.
Sorry, I am still drinking my first coffee... I thought you were wondering why not to use the two instruction sequence.
As far as I know, there is no single instruction "TEST reg and jump if negative" for the scheduler, also it would not allow returning a 32 bit value to the calling task.
That's why I had the comment that the two instruction client sequence gets replaced by a TCHECK. If we use the TCHECK, the what am I missing by just using positive/negative?
Actually having a "TEST reg and jump if negative" as Bill called it, might have some nice usage outside of the tasking scheme, the biggest issue may be the availability of an opcode for such an instruction.
Bill, if we used jmg's scheme you could still return a 32 bit value using a separate register like you do in your scheme.
- needs an additional instruction
- a bit more logic
- is not as straightforward to understand
My original proposal uses the existing TJNZ instruction, and writing zero, is easier to grasp for people not familiar with single bit flags.
It also nicely separates the request from the result, and has 32 bit (not 31 bit returns).
The only positive to his version is that it will save one long per client task in the scheduler/debugger task.
Regarding a possible test reg and jump if negative instruction... it uses up one more two-operand op code, which are becoming as scarce as hen's teeth, for a low frequency of use instruction.
Actually having a "TEST reg and jump if negative" as Bill called it, might have some nice usage outside of the tasking scheme, the biggest issue may be the availability of an opcode for such an instruction.
Bill, if we used jmg's scheme you could still return a 32 bit value using a separate register like you do in your scheme.
If jmg's solution gets further exploration, I do think we might consider flipping the flag so the it is cleared by a TPAUSE and then set by the scheduler to release the TPAUSE.
The scheduler is waiting to see the flag be low, so we would want "TEST reg and jump if positive" instead of "TEST reg and jump if negative".
Here is why:
One of the things the scheduler, debugger, etc. may need to do is check various values of the lower order 9 bits of the value set by the TPAUSE.
If bit 31 was high we would need to make a copy that has bit31 cleared in order to allow simple immediate comparisons. We cannot just clear bit 31 in the original register because that would release the TPAUSE prematurely.
By have bit 31 be low as the active TPAUSE state we can directly do immediate compares against the original register.
If you go with bit 31 signaling, you need either another new instruction JB31...if we go this route, can't we just use positive and negative?
I must be missing some feature/benefit because it seems too simple.
You can just use positive and negative, but I think that is also a new opcode.
The Boolean signaling saves TWO longs per usage, one in code and one in data. = Smaller and faster.
It also gives symmetric signaling each way, of 512 values, with an atomic #immediate load.
There are also other SW areas where signaling is useful.
It go from 512 to 2^:31 values with an extended load (same register), and if someone really does have a design that needs one more bit, simply use another register. As Bill originally said, the #512 is fine for common usage.
If jmg's solution gets further exploration, I do think we might consider flipping the flag so the it is cleared by a TPAUSE and then set by the scheduler to release the TPAUSE.
...
By have bit 31 be low as the active TPAUSE state we can directly do immediate compares against the original register.
Polarity can be either way, but remember an immediate load of #512 clears bit 31 at the same time.
The Boolean signaling saves TWO longs per usage, one in code and one in data. = Smaller and faster.
That is what needs verified in a real use case.
On additional thought the flag polarity change I mentioned in #6141 doesn't really help when you look at the whole picture.
I think the savings you mention end up going away in a real case as well.
In the polarity case you have to either deal with bit31 in either the scheduler or client, a savings in one ends up as a cost in the other.
What I mean by 'deal with' is you cannot do an immediate compare against the register holding the TPAUSE value when bit31 is set.
You will need to make a copy AND clear bit31 in the copy before doing immediate compares, or do compares against registers holding 32 bit values, either way any register savings has been lost.
Depending on the polarity chosen you will need to do this in the scheduler or client.
The original polarity for the flag, 1 being set by the TPAUSE has the benefit that the scheduler can release the TPAUSE by doing an immediate load, like you mentioned in #6146.
In summary:
- Ignore my post #6141, it just swaps the side on which bit 31 being set is a complication for CMP operations and prevents returning from a TPAUSE with a simple immediate load.
- I think when we look at the other activity that will likely accompany TPAUSE, i.e. Interpreting the value sent/received, then having them separate is probably the way to go.
IMHO I've looked at both and tried to see the benefits of each and it seems like Bill's is the way to go.
- needs an additional instruction
- a bit more logic
- is not as straightforward to understand
My original proposal uses the existing TJNZ instruction, and writing zero, is easier to grasp for people not familiar with single bit flags.
It also nicely separates the request from the result, and has 32 bit (not 31 bit returns).
The only positive to his version is that it will save one long per client task in the scheduler/debugger task.
Regarding a possible test reg and jump if negative instruction... it uses up one more two-operand op code, which are becoming as scarce as hen's teeth, for a low frequency of use instruction.
Actually Bill, JN (jump negative) will likely require more than 1 dual opcode...
#abs, @rel, Delayed.
And these are the rarest opcodes and we are most likely going to ask for some with SERDES.
The original prop philosophy was to use 2 instructions (compare/test followed by a conditional instruction, often a jmp or call).
I love the JZ & JNZ (+delayed versions) and while I would love a JNEG and JPOS (or JB31P and JB31N) I think we no longer have sufficient instruction space for these.
Eat the cake and have it too?! A combination of the benefits of both Jmgs and Bills proposals with just a slight modification to the TYIELD logic: Loop to self until reg != originalReg
(The statement above is not completely true I know!. But still, quite close)
[B]Client task[/B]
tyield task1Semaphore, #SOMENONZEROVALUE (loops to self until task1Semaphore != originalTask1Semaphore)
interpret task1Semaphore and do something accordingly
...
...
[B]Server task[/B]
scheduler
tjnz task1Semaphore, #task1Handler
tjnz task.........., #task..
...
jmp #scheduler
taskHandler
mov task1Semaphore, #SOMERETURNVALUE
jmp #scheduler
Of course the value must be changed by the server in order for this to work and that is a problem if the signal from the server happens to be the same.
But then, the modification to TYIELD doesn't change how Bills proposed code will work at all. It is a win if you want to do this "the non Bill way".
Of course the value must be changed by the server in order for this to work and that is a problem if the signal from the server happens to be the same.
Looks good to me. It does give symmetric messaging, and saves code and data. (at some added Logic cost)
To manage a shared message area you can have some agreed split of message values, so each signal is unique.
For most use cases, this will be fine.
Ahle2,
As I said earlier, I like your solution - best of both worlds. Just waiting for Chip to comment if he thinks the little extra silicon is worth it, and there are no timing issues either.
Comments
Sure, then along came HUBEXEC and complete code swapping... with libraries in the mix, and larger more dynamic code.
Will programers really know only one task is using a mathop ? They can hope so...
Can you give a code example of one line polling on == or <> ?
Bill was using JNZ polling, and I was using JB31 polling, in the polling side.
Are we talking apples and oranges? I think you have to reread the context of my reply to Chip. I'm not talking about software on the polling side of a scheduler. I'm talking about the logic of the TPAUSE/TYIELD/THOLD instruction. If changed it will allow both your and Bills implementation to work. And the SW designer can choose either pattern.
/Johannes
JB31 polling? Is that a new instruction suggestion?
A substitute for:
Chips has implemented TCHECK (the old TPAUSE) that sets D with a value, and then waits for D to be reset to zero. TRESUME is no longer required.
Ahle2 has suggested that TCHECK also internally store the D value, and then compare this with the new D value looking for not equal before resuming automatically.
I don't have the VHDL code, but I know who has the code:
http://www.usb.org/developers/whitepapers/siewp.pdf
http://www.ijcst.com/vol24/3/asutosh.pdf
http://www.pcisig.com/reflector/msg00051.html
Yes, I'm up to speed with those changes and suggestions.
My question was based on code referenced a few pages back.
See here
Edit: Got it...JB31 is a new two operand instruction suggestion.
I think I cowered most of things that need be added to SERDES fo simple USB.
It is one more solution I work on -- But it can be even made by SETB both pins to 0
The client task with TCHECK can sit and spin and wait for it to go to zero, get a bit31 set or change in value, that's fine and can be done with varying degrees of complexity. It's all atomic and within that instruction that remembers the initial state and recognizes the exit state. The client has no way to sit and spin and wait for a register to change...nor do we want a supervisor locked up inside an instruction, so it needs to compare and jump based on the compare.
The supervisor side, can very easily put zero in the register and go on it's way until it needs to poll again at that point, it knows it had put a zero in there and any change indicates a task did a TCHECK. If you go with a non-zero value and just look for a change, then the supervisor needs to retain that value in a register and perform 2 instructions (CMP and a jump) to see if has work to do.
If you go with bit 31 signaling, you need either another new instruction JB31...if we go this route, can't we just use positive and negative? If the register is negative, then the supervisor was the last to put something in and it doesn't need to do anything, if it's positive then the task was the last to put something in and it needs to do something. so the supervisor doesn't need a place to retain state of the last thing it sent to the client task.
Which now makes me wonder why (except for the extra instruction) the client task can't just
and the supervisor just:
I must be missing some feature/benefit because it seems too simple.
As far as I know, SD has royalties per device, USB doesn't.
Cluso99, You talk as if Parallax doesn't need licenses at all. How many $$$$ they have invested in Altera Stratix boards (just for their Quartus license)?. And how many $$$$$ (five $ right?) they have spent for layout software?. Do you think that they make layout with open source software (magic or electric)?. They are already stuck with licenses, everywhere.
USB has a $4000 (or $5000) annual member license fee. And with this fee you get a usb VENDOR ID. I wonder what will be the VENDOR ID we will use in our P2 in case we finally have the SW USB protocol working. There is no point at all to make a SW USB implementation if later we cannot effectively use USB in our products just because we don't have a VENDOR ID. If we still need to use another IC for USB (FT232, CP2102, PL2303, HX2LP, AT90USB162 ... ), please skip USB, and go directly to next step (was it serdes or preemptive multitasking?).
How much money have been invested in P2? US $5,000,000 ? Nobody thinks that It is crazy that the last five hundred messages of this forum (that already has 6,000 messages and more than 3 years) are related to some features that can be found in workstation CPUs rather than a microcontroller? BTW, a microcontroller with 256 KB of memory, that will need to be clocked at 192MHz to handle a 16 year old 12mbps USB protocol.
- breakpoints should not take two longs
- system calls & waiting will happen a lot in hubexec code, so we save a lot of memory by using a 1 long instruction
That's why I had the comment that the two instruction client sequence gets replaced by a TCHECK. If we use the TCHECK, the what am I missing by just using positive/negative?
Not arguing, "macths nichts" to me, just trying to understand implications.
As far as I know, there is no single instruction "TEST reg and jump if negative" for the scheduler, also it would not allow returning a 32 bit value to the calling task.
Bill, if we used jmg's scheme you could still return a 32 bit value using a separate register like you do in your scheme.
C.W.
- needs an additional instruction
- a bit more logic
- is not as straightforward to understand
My original proposal uses the existing TJNZ instruction, and writing zero, is easier to grasp for people not familiar with single bit flags.
It also nicely separates the request from the result, and has 32 bit (not 31 bit returns).
The only positive to his version is that it will save one long per client task in the scheduler/debugger task.
Regarding a possible test reg and jump if negative instruction... it uses up one more two-operand op code, which are becoming as scarce as hen's teeth, for a low frequency of use instruction.
The scheduler is waiting to see the flag be low, so we would want "TEST reg and jump if positive" instead of "TEST reg and jump if negative".
Here is why:
One of the things the scheduler, debugger, etc. may need to do is check various values of the lower order 9 bits of the value set by the TPAUSE.
If bit 31 was high we would need to make a copy that has bit31 cleared in order to allow simple immediate comparisons. We cannot just clear bit 31 in the original register because that would release the TPAUSE prematurely.
By have bit 31 be low as the active TPAUSE state we can directly do immediate compares against the original register.
C.W.
Bill's solution, what Chip has implemented, is the simplest and most straight forward given the current instruction set.
Since we are very low on opcodes for new dual operand instructions it is likely the way it will stay.
Since Chip doesn't get caught up in the discussions I don't see any harm in fully fleshing out jmg's approach.
C.W.
Need some extra eyes to look if I have any logical error in this Circuity
With only one instruction that change MODES on nOEI, SUSPEND, SOE.
It can directly send/receive D_p, D_n from SERDES
.
You can just use positive and negative, but I think that is also a new opcode.
The Boolean signaling saves TWO longs per usage, one in code and one in data. = Smaller and faster.
It also gives symmetric signaling each way, of 512 values, with an atomic #immediate load.
There are also other SW areas where signaling is useful.
It go from 512 to 2^:31 values with an extended load (same register), and if someone really does have a design that needs one more bit, simply use another register. As Bill originally said, the #512 is fine for common usage.
Polarity can be either way, but remember an immediate load of #512 clears bit 31 at the same time.
That is what needs verified in a real use case.
On additional thought the flag polarity change I mentioned in #6141 doesn't really help when you look at the whole picture.
I think the savings you mention end up going away in a real case as well.
In the polarity case you have to either deal with bit31 in either the scheduler or client, a savings in one ends up as a cost in the other.
What I mean by 'deal with' is you cannot do an immediate compare against the register holding the TPAUSE value when bit31 is set.
You will need to make a copy AND clear bit31 in the copy before doing immediate compares, or do compares against registers holding 32 bit values, either way any register savings has been lost.
Depending on the polarity chosen you will need to do this in the scheduler or client.
The original polarity for the flag, 1 being set by the TPAUSE has the benefit that the scheduler can release the TPAUSE by doing an immediate load, like you mentioned in #6146.
In summary:
- Ignore my post #6141, it just swaps the side on which bit 31 being set is a complication for CMP operations and prevents returning from a TPAUSE with a simple immediate load.
- I think when we look at the other activity that will likely accompany TPAUSE, i.e. Interpreting the value sent/received, then having them separate is probably the way to go.
IMHO I've looked at both and tried to see the benefits of each and it seems like Bill's is the way to go.
C.W.
#abs, @rel, Delayed.
And these are the rarest opcodes and we are most likely going to ask for some with SERDES.
The original prop philosophy was to use 2 instructions (compare/test followed by a conditional instruction, often a jmp or call).
I love the JZ & JNZ (+delayed versions) and while I would love a JNEG and JPOS (or JB31P and JB31N) I think we no longer have sufficient instruction space for these.
(The statement above is not completely true I know!. But still, quite close)
Of course the value must be changed by the server in order for this to work and that is a problem if the signal from the server happens to be the same.
But then, the modification to TYIELD doesn't change how Bills proposed code will work at all. It is a win if you want to do this "the non Bill way".
/Johannes
Looks good to me. It does give symmetric messaging, and saves code and data. (at some added Logic cost)
To manage a shared message area you can have some agreed split of message values, so each signal is unique.
For most use cases, this will be fine.
As I said earlier, I like your solution - best of both worlds. Just waiting for Chip to comment if he thinks the little extra silicon is worth it, and there are no timing issues either.