grep the header files (salvo.h, etc.) and you'll find it.
But here's the skinny.
1) Salvo's scheduler follows a simple rule -- always run the highest priority eligible task.
2) There's a not-so-obvious corrollary to this rule (I searched the Salvo User Manual but can't find this explicitly stated -- I'll look into adding it): Namely, that every context switch is unconditional. With OS_Yield() it's obvious. But with OS_WaitXyz() it's not so obvious. Every call to OS_WaitXyz() includes an unconditional context switch whether or not the event is available. I won't go into how this works , but the reason why you want this is to preserve responsiveness in the system. So in your example, it looks like this:
Task1() runs 1st, up to its OS_Yield().
Task2() runs 2nd, and context switches (remember, all OS_'s are unconditional context switches).
Task1() runs 3rd, since Tasks Rask1() and Task2() run at the same priority.
Task2() runs 4th since it has completed its unconditional context switch, this time it waits the event successfully, and goes on its merry way to ultimately wait the event again.
The behavior is a bit simpler if the event is not available -- in that case, it's obvious that a context switch is required.
Why do things this way? Well, consider a case where you are "bombarding" a sem from an ISR via OSSignalSem(). If you wrote OS_WaitXyz() code that only yielded to the scheduler if the event was not available, then in this case you'd be stuck in said event until the sem dropped down to 0 via successful waits. Well, what happens if another, higher-priority task is made eligible during this time? Nada -- the scheduler can't dispatch it because the waiting task never yields. And you blow your whole application. Therefore, in a cooperative scheduling scheme like Salvo's, unconditional context switches are required for proper operation (and they make for excellent responsiveness, too).
Note that in your example, what you are essentially trying to do is handshake between two tasks, yet your signaling is strictly unidirectional (from Task1() to Task2()). In a loosely coupled system, that sort of thinking leads to some assumptions that are (as demonstrated in your initial puzzlement) incorrect. If, instead, you signaled a binSem from Task2() to Task1() and waited it in Task1() until you knew that Task2() had processed the message, then you'd have had exactly the behavior you expected.
The Salvo code handles all of this behavior based on the basic rule of the scheduler. I recommend not thinking about "linear sequencing" when you're considering (interacting) tasks, but rather, think along the lines of "when will this task actually run based on the scheduler's rule?" And the answer for Task2() in your example is "As soon as it's the highest-priority eligible task."
FYI, tasks at the same priority round-robin. So Task1() ran before Task2() only because it was created first.
------------------