<Do you mean use CDS because there is an address and a count? I don't see>
<why I need a count, If I set the forward of the 1st element pushed on the>
<queue to 0 to signify the end of the queue?>

I can relate to your PLO headache. Part of the problem is the way POpS
documented this instruction and part is that it's just very complex.

I believe you said that you did have multiple tasks adding to the queue and
one task removing them. This is how the problem can occur.

In a nutshell: It is necessary to guarantee that even though the value in
the anchor address hasn't changed (if it has, CS will so indicate), that the
element to which the anchor is pointing has the same "next" pointer as it
did when you first looked at the anchor prior to CS.

Oh dear, I've confused you more. Think about the case when one task loads
the anchor address and then that task is not dispatched for a long time (in
computer time). Another task is dispatched and it adds a new entry onto the
queue AND the task processing the queue takes this entry off. The anchor is
updated by both these operations and is now looking exactly the way it did
when the first task loaded it. But things have changed..... If the first
task now tries the CS it works but the chains can be all messed up.

Solution is to add 1 to the fullword counter which you place in your common
area just ahead of the anchor address. Changing this value each time the
anchor is changed is enough to cause task A (which is now using a CDS) to
notice that there has been a change (return code from CDS) and to loop back
and do the CDS again. You must add to this counter and replace the new value
both when you add an element to the queue and when you take the elements
off. This number just reflects the fact that something has changed and that
the anchor address should be re-loaded and that the next pointer of the new
entry should be updated.

<"If an ECB is reused, bits 0 and 1 must be set to zero before a WAIT,>
<EVENTS ECB= or POST macro can be specified.">

This statement is correct except that it should say AFTER a WAIT, Events
ECB= can be specified. And it should say that the ECB should NEVER be
touched by the task that is issuing the POST. Start with an ECB of binary
zeros when you program starts and you'll be fine if you follow my hints
below:

POST and WAIT: When you issue POST against an ECB the value in R0 is stored
in the low order bytes of the ECB and usually is a return code. Let's say
you POST the waiting task with a code that says there is work to be done.
Well and good. If before the subtask sees this code (because it is not
dispatched in time) and if the maintask then posts the ECB again (which is
OK) with the code to say go to end of job, the work that the subtask should
have performed won't be done or the end of job indication won't be acted
upon.

Do not ever simply test the ECB and branch if X'40' is on. You can see the
discussion in POpS about "bypassing WAIT" if you want to save some cycles
but this isn't necessary.

You do not have to worry about whether or not the subtask is waiting on the
ECB or not when you POST it. If it is waiting it will be woken up. If it is
not waiting the system will see the X'40000000' when WAIT is issued and
control will return immediately and won't wait.

X'80xxxxxx' indicates that the task is waiting. Your question about when it
is safe to clear the ECB is answered: Only by the waiting task immediately
when it comes out of the WAIT. At this time it should clear the X'40' from
the ECB before continuing.

The low order bytes of the ECB should not (as I indicated above) be used to
pass commands to the subtask because multiple POSTS will cause commands to
be overlaid or not placed into the ECB.

When your subtask comes out of the WAIT, it should immediately turn off the
X'40' bit and then remove ALL the entries that it finds on the queue and it
should process each and every one of them. The removal process will take all
the entries off because your queue is a LIFO queue (only one that can be
handled with CDS). So with one CDS you will cause the queue to look empty to
the other tasks. Your subtask must process all the entries before releases
their storage.

The rule is whenever an element is on the LIFO queue it cannot be altered.
The subtask will remove all the elements from the queue with CDS and now
these entries are free to be used by the subtask any way it wishes. Once the
maintask has put an entry onto the queue it can't touch than entry again.

No problem if while the subtask is processing the queue, new entries arrive.
All that will happen is that when the subtask issues the WAIT (and notice
that it must NOT touch the ECB again between the time that it removes all
the queue entries and the time it next issues WAIT. It can turn the X'40'
off after exiting WAIT but BEFORE removing the queued entries and this is
the only time it can do so.

If there is an end of job request it should be so indicated in a regular
queue entry as an operation code. Hence when you reorder the queue to be in
time sequence you will process all the normal data entries before the
subtasks closes its file and goes to end of job.

I'm afraid I've written both too much and too little.

Andy Coburn




-----Original Message-----
From: IBM Mainframe Assembler List [mailto:[email protected]]
On Behalf Of Joe Owens
Sent: Friday, April 15, 2011 10:28 AM
To: [email protected]
Subject: Re: Subtasking program

Thanks to everyone for the response to this, your insight will definately
save me time, and I'll end up with something better than I would have on
my own.

I read up on the PLO instruction and got a headache, same type I get when
I read how DAT translation works :) I will probably stick with CDS or CS.

I have a few more questions, you will not be suprised to know.

Regarding using CDS VS CS

"don't fall into the trap of trying to do it with a Compare Single and Swap
(CS). Take the POpS advice and use Compare Double and Swap (CDS). The flaw
of using CS will occur and you will end up changing to CDS in time. This I
promise."

Do you mean use CDS because there is an address and a count? I don't see
why I need a count, If I set the forward of the 1st element pushed on the
queue to 0 to signify the end of the queue?

Using WAIT/POST. Apologies for the simplicity of this question, but I
don't get an aspect of it. If a subtask has a wait ECB, I'd like to use 2
completion codes, 1 to indicate new work, and 1 to indicate termination.
Suppose when the mother decides to terminate, the subtask is not waiting
at that time. The manual says

"If an ECB is reused, bits 0 and 1 must be set to zero before a WAIT,
EVENTS ECB= or POST macro can be specified."

I have read somewhere about prepost, but I don't understand when the ECB
can be cleared safely without the possibilty of 'missing' a prepost as
there is no interlock between the clearing of the ECB and the setting of
the POST bit.

I could use 2 separate ECBs for the work wait and the termination wait,
but I'd like to understand if this is a necessary approach.

Thanks, Joe

Reply via email to