minor confusion - task related - VxWorks
This is a discussion on minor confusion - task related - VxWorks ; Consider the pseudo source provided below.
In terms of priority, from highest to lowest we have task2, task3 and
task1. So now:
SEM_ID task1_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
SEM_ID task2_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
SEM_ID task3_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
static int count;
...
-
minor confusion - task related
Consider the pseudo source provided below.
In terms of priority, from highest to lowest we have task2, task3 and
task1. So now:
SEM_ID task1_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
SEM_ID task2_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
SEM_ID task3_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
static int count;
void increment()
{
++count;
}
void task1()
{
while (1)
{
semTake (task1_sema, WAIT_FOREVER);
// do something
}
}
void task2()
{
while (1)
{
semTake (task2_sema, WAIT_FOREVER);
// later
increment();
if ((count%2) == 0)
semGive(task1_sema);
}
}
void task3()
{
while (1)
{
semTake (task3_sema, WAIT_FOREVER);
increment();
if ((count%2) == 0)
semGive(task1_sema);
}
}
The question: Is it possible for task2 and task3 to give task1_sema at
the 'same time'?
Trying to determine if I need an intLock/intUnLock setup around the
call to increment and the semGive(task1_sema):
int lock_key = intLock();
increment();
if ((count%2) == 0)
semGive(task1_sema);
intUnLock(lock_key);
-
Re: minor confusion - task related
Hello forums_mp,
forums_mp@hotmail.com schrieb:
> SEM_ID task1_sema = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
....
> The question: Is it possible for task2 and task3 to give task1_sema at
> the 'same time'?
>
> Trying to determine if I need an intLock/intUnLock setup around the
> call to increment and the semGive(task1_sema):
>
>
> int lock_key = intLock();
>
> increment();
> if ((count%2) == 0)
> semGive(task1_sema);
>
> intUnLock(lock_key);
>
I believe that the semaphore for task1 HAS to be a counting semaphore
and not a binary semaphore. Then the int_lock is not needed.
If you use the int_lock, you also could use Windows to solve your
problem. ;-)
Honestly speaking: You should use all available building blocks to make
the solution to behave RTOS like.
Blocking the int is an emergency design, not a regular one!
Hope it helps.
--
BaSystem Martin Raabe
E: Martin.RaabeB-a-S-y-s-t-e-mde
-
Re: minor confusion - task related
|| I believe that the semaphore for task1 HAS to be a counting
semaphore and not a binary semaphore.
OK!! Excellent point.
Thanks
-
Re: minor confusion - task related
Counting semaphores makes no sense to me - this after perusing the
doucmentation. In my case I want task1 to start if and only if task2
and task3 has performed a semGive (this would be akin to a counter
equaling 2). So for task1 I create a counting semaphore:
semCCreate (SEM_Q_FIFO, 0); initial value zero.
task2 and task3 gives the semaphore. Trouble is task1 executes after
the 'first' give of the semaphore. I'm obviously missing something.
task1 should not execute until both task2 and task3 has _given_ the
semaphore.
It's even more compilicated since according to the documentation
semGive results in an increment of the count. semTake results in
decrementing the count.
So if task2 performs a semGive. The count is presume is 1.
task1 does a semTake so the count is 0;
So if task3 performs a semGive. The count is presume is 1 again.
task1 does a semTake so the count is 0;
Whats the point. I'm obviously missing something from the
documentation. Of course one issue I see with this is the guarantee
that both task2 and task3 gave the semaphore. Meaning the need to
prevent task2 or perhaps task3 from giving the semaphore twice.
-
Re: minor confusion - task related
Hello forums_mp,
forums_mp@hotmail.com schrieb:
> Counting semaphores makes no sense to me - this after perusing the
> doucmentation. In my case I want task1 to start if and only if task2
> and task3 has performed a ...
So the event is the appropriate intertask communication mechanism.
Here you can fire an event from task 2 to task 1 and from task 3 to task 2.
And when both (and) are fired (which means received by task1) task1 can
return from receiving the events and do what ever it needs.
Since I obviously did not get the algorithm you need to implement, I
can't recommend the appropriate mechanisms here, I guess.
So maybe you need to tell us about the algorithm, you want to code, and
I can find what is the right thing do do!?
--
BaSystem Martin Raabe
E: Martin.RaabeB-a-S-y-s-t-e-mde
-
Re: minor confusion - task related
On 25 Oct 2005, forums_mp@hotmail.com wrote:
> Counting semaphores makes no sense to me - this after perusing the
> doucmentation. In my case I want task1 to start if and only if
> task2 and task3 has performed a semGive (this would be akin to a
> counter equaling 2). So for task1 I create a counting semaphore:
[snip]
Well, that is a most helpful description that you could have given in
the first place. It is always a good idea to try and describe *what*
you are trying to achieve before giving the code. As you don't have a
grasp of what it going on, it seems pretty easy for someone to mistake
what you are asking...
It think you will need two semaphores. The task2, task3 semaphore in
your original code are completely irrelevant to what you wish to do...
Martin is very correct in recommending not to use intLock().
I had recommended this to a fellow programmer. He ignored the advice.
The flash library would constantly "pause" the system because he had
locked interrupts. That programmer went on to be a manager; so you
can use intLock() if you are completely incompetent.
I might recommend this pseudo code initially.
#define NUM_ACTIVITIES 2
unsigned int activityCount = 0; // Access count.
SEM_ID semActivity; // Mutual exclusion.
SEM_ID semTask1; // Binary or other...
void task1()
{
while(1)
{
semTake(semTask1, FOREVER);
// Do work...
}
}
void noteActivity(void)
{
// Blocking loop maybe?...
// at least until some criteria is meant...
semTake(semActivity, FOREVER);
activityCount++;
if(activityCount > NUM_ACTIVITIES)
{
semGive(semTask1); // Wake task one (not well described).
activityCount = 0; // Reset count.
}
semGive(semActivity);
}
void task2(/* ??? */)
{
// block... process, etc.
noteActivity();
}
void task3(/* ??? */)
{
// block... process, etc.
noteActivity();
}
There are many different ways to do what you want. You might want to
put things in structures, classes, etc. Things just depend on design
criteria, which you don't state, but many people would complain they
don't get for themselves. Funny that people ask questions on Usenet
and absolutely never give any sort of "formal criteria", but just some
vague question...
If you are concerned about performance, you might consider
sig_atomic_t or some other "tas" semantics. You may eschew the mutual
exclusion for a binary semaphore, etc. Please read the vxWorks users
guide on semaphores, *NOT JUST* the technical documentation. The
users guide tries to explain some design patterns for using
semaphores.
fwiw,
Bill Pringlemeir.
--
Some people are alive because it's against the law to kill them.
vxWorks FAQ, "http://www.xs4all.nl/~borkhuis/vxworks/vxworks.html"
-
Re: minor confusion - task related
|| I had recommended this to a fellow programmer. He ignored the
advice.
|| The flash library would constantly "pause" the system because he had
|| locked interrupts. That programmer went on to be a manager; so you
|| can use intLock() if you are completely incompetent.
OK. I'm unsure if the 'now' manager's use of intLock would make him
incompetent but whatever ..
void noteActivity(void)
{
activityCount++;
if(activityCount > NUM_ACTIVITIES)
{
semGive(semTask1); // Wake task one (not well described).
activityCount = 0; // Reset count.
}
}
I tweaked your source to highlight an approach I had initially. My
concern though: Is it possible for task2 and task3 to execute
noteActivity at the same time?
I also notice you have a semTake at the start of noteActivity but who's
responsible for initiating the semGive? yes, I agree with the idea of
creating a composite type to make things seemless.
|| Things just depend on design criteria, which you don't state, but
many people would complain they don't get for themselves.
For me the concept is simple, so let me try to capitalize on my
'vagueness'. A single board computer with dual processors. So lets
call the processors A and B.
Processor A has two tasks - call them task_A and task_B, where task_A
serves as the high priority task. So task A on processor A dma's data
to processor B on card. Task_A - literally (there's on board IPC
involed here) interrupts 'task2' on processor B. task2 does some
number crunching.
Similarily task_B on processor A dma's data (different offset of
course) to processor B on card. Task_B - here again - literally
interrupts task3 on processor B. task3 on processor B does a similar
number crunching. With respect to task1 and task3 on processor B.
Once both tasks have completed number crunching they'll signal task1
executing on processor B. task1 will collate the data and .. well
the rest is history.
If that's still to 'vague' then you could move on to assist the next
individual.
Thanks for your time.
-
Re: minor confusion - task related
On 25 Oct 2005, forums_mp@hotmail.com wrote:
> void noteActivity(void)
> {
/* important! */ semTake(semActivity, FOREVER);
> activityCount++;
> if(activityCount > NUM_ACTIVITIES)
> {
> activityCount = 0; // Reset count.
> semGive(semTask1); // Wake task one (not well described).
> }
/* important! */ semGive(semActivity);
> }
>
> I tweaked your source to highlight an approach I had initially. My
> concern though: Is it possible for task2 and task3 to execute
> noteActivity at the same time?
>
> I also notice you have a semTake at the start of noteActivity but
> who's responsible for initiating the semGive? yes, I agree with the
> idea of creating a composite type to make things seemless.
The semaphore (semActivity) is initially "full". Either task2 or
task3 can take it. This was my reference to atomic operations as
oppose to a semaphore which is a little heavier... but for two or
three elements, it doesn't matter unless it is executing often. The
semTask1 is initially empty.
You must gaurd this routine with an exclusion semaphore to prevent
both task 2 and task 3 from executing at the same time... of course
this is possible. It might be very unlikely. So, it might seem to
never happen on a system... until it is deployed in the feild and
users report random crashes [two semGives, or maybe no semGive].
[snip]
> If that's still to 'vague' then you could move on to assist the next
> individual.
My point was you seemed to be chastising the counting semaphore
advice. It was not what you wanted, but your description was not
good. How could you expect anything else?
> Thanks for your time.
Your welcome...
--
The birds of leaving call to us. Yet here we stand endowed with the
fear of flight. - Dead can Dance
vxWorks FAQ, "http://www.xs4all.nl/~borkhuis/vxworks/vxworks.html"
-
Re: minor confusion - task related
|| /* important! */ semTake(semActivity, FOREVER);
I see.
So the creation of semActivity is as follows:
semActivity= semBCreate(SEM_Q_FIFO, SEM_FULL);
I suspect I'll need some vxWorks training but I'm unsure of the value
added when the plan is to switch to Linux.
|| You must gaurd this routine with an exclusion semaphore
Now bear with me here. Trying to ensure I'm reading the manual right.
SO now:
SEM_ID semM;
semM = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE); // fifo i
suspect would suffice.
void task2()
{
while (1)
{
if (semTake (abc_sema, WAIT_FOREVER) != OK ) continue;
// later
semTake (semM, WAIT_FOREVER);
noteActivity();
// semGive(semM); (?) perhaps
}
}
void task3()
{
while (1)
{
if (semTake (xyz_sema, WAIT_FOREVER) != OK ) continue;
// later
semTake (semM, WAIT_FOREVER);
noteActivity();
// semGive(semM); (?) perhaps
}
}
Now in order for the semeTake on semM to occur there needs to be a
semGive. But because the semaphore state is initially full (via
exeuction of the function semMCreate) , the call to noteActivity will
occur depending on execution of either task - task2 or task3?
SEM_Q_PRIORITY per the manual is as follows:
SEM_Q_PRIORITY (0x1)
Queue pended tasks on the basis of their priority.
Does this mean that if task3 (the lower priority) is executing and now
'pends' (I suspect) on the semaphore (semM), task3 will have to wait
until the higher priority (task2) takes the semaphore? Put another
way. The call to noteActivity - via task3 will always occur after
task2?
|| My point was you seemed to be chastising the counting semaphore
advice.
Not my intent. I was experimenting with example code and got wrapped
around the axle trying to understand the counting semaphore.
Thanks for the help