Pumpkin, Inc.

Pumpkin User Forums

Multiple signalling of SEMAPHORES

If you can't make Salvo do what you want it to do, post it here.

Multiple signalling of SEMAPHORES

Postby luben » Thu Nov 22, 2001 9:40 am

Hello,

I didn't know where to put this issue - into "Future requests" or here.

I'm working over a project - graphic thermal printer. And I have a task that receives from SEMAPHORE how many rows to drive the paper motor.

So, if I need 10 rows, I have to signal SEMAPHORE 10 times. IS it some "streigth" way to do this - to increment semaphore directly with 10? Because there is no sense to do signalling 10 times, instead of calling once the function, with add value 10.

Maybe should be good idea to have new function like OSAddSem() which adds a value to the semaphore.

Regards
Luben

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

Re: Multiple signalling of SEMAPHORES

Postby aek » Thu Nov 22, 2001 10:48 am

Hi Luben.

Currently, you would have to signal the semaphore 10 times.

Some ideas:

1) Maintain a global variable rows and use a binary semaphore. The algorithm then looks like this to "signal" the binsem:

code:
disable interrupts;
rows += additional rows;
OSSignalBinSem(BINSEM_P);
enable interrupts;

and it looks like this to "wait" the binsem:

code:
OS_WaitBinSem(BINSEM_P, label);
disable interrupts;
print rows;
rows = 0;
enable interrupts;

A potential problem with this approach is that Salvo does not (on the PIC) save the state of the interrupt enable bit when it disables and re-enables interrupts. Therefore an interrupt can "sneak in" between OS_WaitBinSem() and when you reset rows to 0. Obviously this can only happen if you signal the binsem from an ISR(). HOWEVER, in v2.3.0 (which you now have for the 8051), you use OSProtect() and OSUnprotect() "around" OS_WaitBinSem(), and OSCALL_OSSIGNALEVENT is OSFROM_ANYWHERE, and then you don't have a problem, e.g.:

code:
OSProtect();
OS_WaitBinSem(BINSEM_P, label);
print rows;
rows = 0;
OSUnprotect();

This is all related to the PIC not having a stack to store things on ...

2) You could write your own OSAddSem() using OSSignalSem() as a basis -- that would be pretty easy. One can even add a variable argument list to OSSignalSem(), so that the "add to" parameter is optional ... but that does add to the code size ...

3) You could call OSSignalSem() and then add 9 to the semaphore directly -- look in the source code to see how to access the sem.

Anyway, I hope these ideas help. Signaling a semaphore is typically just one increment at a time, so I have to look into whether other OS's support this idea.

Regards

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

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

Re: Multiple signalling of SEMAPHORES

Postby DHenry » Fri Nov 23, 2001 9:15 am

FWIW, all RTOS's that I'm familiar with use the increment/decrement semaphore model. When there is data flowing as part of intertask communication, they recommend using services related to message passing. This is not to say that there aren't RTOS's that somehow overlay message passing on top of semaphores -- I just haven't run across one.

--Dan Henry

DHenry
 
Posts: 18
Joined: Sat Aug 04, 2001 11:00 pm
Location: Boulder, CO, U.S.A.

Re: Multiple signalling of SEMAPHORES

Postby aek » Fri Nov 23, 2001 9:45 am

Yep, doing more than increment/decrement on semaphores would be rather non-standard.

Luben, something you may want to consider is to create your own "libraries for Salvo" with special functions like LuOSAddSem().

Of course we can't support user functions, and there might be changes from one version of Salvo to the next that would "break" your functions, but overall I suspect that if you wrote your own function LuOSAddSem() for v2.x it would still work in later versions, etc.

That's the beauty of having the source code at your fingertips, eh? :-)

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

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

Re: Multiple signalling of SEMAPHORES

Postby aek » Fri Nov 23, 2001 10:05 am

Hi Luben.

I'm not sure what I was thinking when I originally replied :-), but of course Dan's suggestion to use messages is a good solution.

The message contains the number of (additional) rows to be printed. The message contents are added to the static variable rows, and then rows is decremented each time a row is printed ... something like this:

code:
OS_WaitMsg(MSG_P, &msgP, OSNO_TIMEOUT, label);
localRows = *(unsigned char *) msgP;
rows += localRows;
...
do {
print row;
OS_Yield(label);
} while (--rows);

I suspect the reason why you'd rather use semaphores is that they are an elegant solution to the problem of signaling rows faster than the rows can be printed. With messages, you run into the problem that you may be blocked until a waiting task can read the message. Message queues help a little, but you still run the risk of being blocked. Counting semaphores are much better, because it's unlikely you'll overload the maximum value of the semaphore.

If you look at OSSignalSem(), apart from all the error-handling code, it's really pretty fast for additional signaling once there are no tasks actively waiting the semaphore (after the first signaling, the waiting task is made eligible, and so subsequent signaling s just increment the semaphore). So calling OSSignalSem() multiple times may be a bother, but it avoids all the other problems nicely.

I'd be interested to know if there's a better solution using the available Salvo services...

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

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

Re: Multiple signalling of SEMAPHORES

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

Hi Luben.

That seems like a good approach.

quote:
I'm sure that you have in your mind even more ideas then me and if you try to put them all into SALVO it will explode.

Some of your "Lubenisms" are real gems ... :-)

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

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

Re: Multiple signalling of SEMAPHORES

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

Hello,

I think that using Messages for semaphores is not "SALVO style" solution - of course it will work, but can implement potential problems. And signaling Semaphores 10 times one after other is let's say wasting of time - not "SALVO style" too.

What I can imagine right now and will try in my project is to use EFlags. Thay have everything what we need - you can signal the EFLAG, but the task that gets the flag can reset or can not reset the eflag, depend on the value of some counter.

The code will look like that:

code:

.....
void TASK_A()
{
// user want to move 10 print rows more
counter_rows += 10; // add 10 rows more to the motor move counter
OSSetEflag(EFLAG_MOTOR, _BIT_MOVE);
....
// here would be great to have EFlag options like
// OSNOT_EQUAL or OSZERO_BITS to wait with OS_WaitEflag until taskB free resources


}

void TASK_B() // moves the paper
{
while(TRUE)
{
...
OS_WaitEFlag(EFLAG_MOTOR,BIT_MOTOR,OSALL_BITS,OSNO_TIMEOUT,_Label);

// a request to move motor appeared

while(counter_rows) {
counter_rows--;
.......... moves one row .........
OS_Yield(_Label); // bring some fresh air to other tasks
}
OSClrEflag(EFLAG_MOTOR,BIT_MOTOR); // after all requests proceeded - clear the flag

} // end of the neverending main loop of the task
}


This example shows how "SALVO style" is implemented into waiting of events. No conflict is possible. The value of how many times to move paper is into additional counter. EFlag here is used like BinSem, with the small difference, that it's reset only when counter becomes zero. By the way, SEmaphores works in the same way - you signal the semaphore let's say 3 times one after other, it becomes inactive when it's value is zero.

And yes, I agree that it's dangerous game to make all the time new and new functions. Of course it's convenient to have all of them, but knowing that processors have limitet ROM and RAM you soon give up. By the way I already changed my mind and I think that the right SALVO should have only limited number of basic functions, some set that allows to do any multitasking (somethiungs like AND - OR set in logic), but excluding any "strange" cases, unordinary usage, etc. I received this vision after some times my ROM and RAM finished in medium big projects.
In all cases technic and programming are one compromise between the perfection, price, time, possibilities. If you put the weigth only on the perfection for sure you'll have very expensive target, good for NASA, but not for ordinary life. If you try to make SALVO perfect - this will kill SALVO, making it dinosaurus. I meant - some unperfection will make SALVO perfect :-) The wisdom is what to throw away from SALVO and what to put inside. I'm sure that you have in your mind even more ideas then me and if you try to put them all into SALVO it will explode.

So I don't intend to build my OSLuXXX functions. It's like using of GOTO in C - if you need such operator (I don't speak about special, extarordinary cases), that is indicative of deep structure failures of the program design. Maybe we should extend this with: The wish to use more and more new functions in SALVO is indicative of bad understanding of SALVO. Well, we should add .... This became true after SALVO2.3 pop up in the world....

Anyway, this issue is about how we should keep balance between wish to change things and to keep them permanent. Fine balance.. huh?

Regards
Luben


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

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

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


Return to Coding

Who is online

Users browsing this forum: No registered users and 2 guests

cron