Pumpkin, Inc.

Pumpkin User Forums

OS_WaitSignalXYZ() new function?

Have an idea on how to make Salvo better? Post it here!

OS_WaitSignalXYZ() new function?

Postby aek » Sat Nov 24, 2001 8:41 am

Hi Luben.

This (at first glance) would be pretty difficult, because there is no mechanism inside of Salvo to treat the successful signaling of an event as an event itself.

Here are a few ways to do it within the exisiting set of services:

1) In your parent task you could create a child task whose sole purpose is to signal the event. Then, the parent task waits a binsem. After the child task successfully signals the event, it signals the binsem that the parent task is waiting for.

code:
TaskParent ( void )
{
for (;;) {
...
OSCreateTask(TaskChild, TASK_CHILD_P, 14);
OSCreateBinsem(BINSEM_P, 0);
OS_WaitBinSem(BINSEM_P, OSNO_TIMEOUT, label);
/* event signaled successfully */
...
}
}

TaskChild ( void )
{
while ( OSSignalXyz() )
OS_Yield(label1);
OSSignalBinSem(BINSEM_P);
OS_Destroy(label2);
}


TaskChild() is a neat example of a task that does not have an infinite loop as its structure -- it's a "one-shot" task that has an indefinite number of context switches.

2) Similar to 1), but you do this in the main loop, i.e. before OSSched(). This would use fewer resources, as all you'd have to do is check a single bit (i.e. flag:b0 means "signal event #0 and the signal binsem #a if successful", flag:b1 means "signal event #1 and the signal binsem #b if successful", etc.). This has much lower overhead (just a few instructions per iteration).

code:
TaskParent ( void )
{
for (;;) {
...
flag.b0 = 1;
OS_WaitBinSem(BINSEM_P, OSNO_TIMEOUT, label);
/* event signaled successfully */
...
}
}

main( )
{
...
for (;;) {
if ( flag.b0 ) {
if ( OSSignalXyz() == OSNOERR ) {
flag.b0 = 0;
OSSignalBinSem(BINSEM_P);
}
}
OSSched();
}
}


3) Like 2, but have the action inside the OSIdleTaskHook() (v2.2.0) or inside the OSIdlingHook() (v2.3.0). But you must be sure that the system idles every once in a while ...

4) Use just one task, but force its priority to the lowest while it repeatedly attempts to signal the event.

code:
TaskParent ( void )
{
...
while ( OSSignalXyz() ) {
OSSetPrio(low_priority);
OS_Yield(label);
}
OSSetPrio(normal_priority);
...
}

The only thing to look out for in 4) is that the task will still be running at the low priority if it (ever) had to lower its priority and context-switch. That's because a change in priority takes effect after the context switch that follows it.

5) Delay the task if it's unsuccessful in signaling the event. Since a delay timing out is a sort of (event-driven) event, this will use fewer processor resources over the long term.

code:
while ( OSSignalXyz() )
OS_Delay(50, label);

I hope this gives you some ideas ...

[This message has been edited by aek (edited November 24, 2001).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitSignalXYZ() new function?

Postby aek » Sat Nov 24, 2001 8:53 am

Hi Luben.

quote:
But imagine that the task will accept the event let's say after 1 day - you can calculate how million times you have to do the "while" loop - it's not "SALVO style".

That's the beauty of having priority-based execution -- so what if you've done it a million times?

As long as more important things (i.e. tasks) are able to run when they need to, then it's OK to let the unimportant things happen when the system is idling ... it's pretty unlikely that you won't have some idle cycles available in your application.

Obviously we all prefer Salvo's event-driven approach that avoids polling, etc., and any sort of polling will reduce overall performance, but if you can move it to the idling part of the system, then it really doesn't matter much.

------------------

[This message has been edited by aek (edited November 24, 2001).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitSignalXYZ() new function?

Postby aek » Sat Nov 24, 2001 9:13 am

Hi Luben.

quote:
Other approach is to make BINSEM that shows the task is free. So the example will look like

That sort of handshaking is of course the best way to do it, and it's event-driven, which means no time wasted polling, etc.

The behavior of that system is that the signaling task is blocked until the waiting task runs.

N.B. This is not the same as the signaling task is blocked until the event is successfully signaled.

This difference is mainly due to the way Salvo works with minimal memory -- if (RAM) memory were unlimited, then things would be different.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: OS_WaitSignalXYZ() new function?

Postby luben » Sat Nov 24, 2001 12:02 pm

Hello,

I just wandered is it possible to make such function like

OS_WaitSignalXYZ().... it will wait until event is signalled sucessfully. It could be used with any of the events.

In many cases it's important for the task to wait the sucessfull signaling of the event. It could be made with

code:

while (OSSignalXYZ())
OS(Yield();

But imagine that the task will accept the event let's say after 1 day - you can calculate how million times you have to do the "while" loop - it's not "SALVO style".

Other approach is to make BINSEM that shows the task is free. So the example will look like

code:

OS_WaitBinSem(BINSEM_action_FREE,OSNO_TIMEOUT,Label);
// BINSEM_action_FREE is signalled after destination task gets previous BINSEM_action
// and processed it completely
OSSignalXYZ( BINSEM_action);

it's perfect, except that one extra BINSEM is created.

Because there is well known way to solve such problems without OS_WaitSignalXXX I don't insist for such function, but will be sin if we don't add such function on the cost of 5 -10 extra ROM bytes. Because you're the captain of SALVO ship you know better is it reasonable to continue speaking about OS_WaitSignalXYZ or to throw it away of the board to the sharks....

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria


Return to Feature Requests

Who is online

Users browsing this forum: No registered users and 1 guest

cron