Re: my action item for explaining semantics of notify callbacks in SCE-MI pipes

From: John Stickley <john_stickley_at_.....>
Date: Wed Apr 18 2007 - 08:06:48 PDT
Shabtay,

Shabtay Matalon wrote:
> Hi John,
> 
> Yes, I now understand your distinction between when the callbacks are
> called and when the callee yields (control) to the other side.
> 
> So the callee will yield control only when blocking call is not
> satisfied or if the callee is the producer when it calls flush.
> 
> Correct so far? 

johnS:
By 'callee' do you mean the callback ?

Then, no, this is not where control is yielded - simply a notify
(such as an sc_event post) is performed.

It is up to the infrastructure to decide when to yield control
from the HDL side.

And as far as the C-side, you will presumably have waits
in your blocking calls that naturally yields (remember, blocking calls
are "thread-aware").

So for example lets take the case of a C-side producer
doing a blocking send. Inside, it repeatedly attempts
try_send()'s until it sends all the requested elements.
At some point, the pipe files and the try_send() indicates
that it that no elements were sent.

At that point, the blocking send does
not return, but rather does a "wait()" which naturally yields.
(see example in 5.7.4.1.1 of the spec).

Subsequently, at some point, meanwhile, the HDL consumer finally
has an opportunity to remove some elements from the pipe and does so
during a try_receive() call that returns a non-zero number of elements.
Because the number is non-zero, it changed the state of
the pipe so a notify callback (back to the producer) is required.
So the infrastructure calls the "OK to send" notify callback.

Bear in mind the producer thread is still asleep at this point
because no yield has, as yet, been done - just a notify

Finally the next time the C-side threads are yielded to,
low and behold, the wait condition in the producer is satisfied
and it resumes execution and attempts to send more elements.


> 
> So what benefit do you see in the callback being called BEFORE the
> callee yields control? Why not call the callback WHEN the callee yields
> control as this condition already entails that number of elements in the
> pipe has changed (as otherwise why the callee was blocked)?

johnS:
Not sure how to answer this since I don't understand your terminology.
What's the difference between a callee and a callback ?

> 
> Also,
> 
> What benefit you see in these callbacks called in succession? For
> example, in your 2 try_receive() operations, if the callback will not
> cause any elements to be added so why not call the callbacks only once
> when the callee will yield control? 

johnS:
I think in this case there's no harm in calling it twice.

If the yield between the first and 2nd try_receive resulted
in no elements being added, one can argue "that's not the
consumer's problem".

I.e. the first notification in this scenario was ignored
by the producer when it was yielded to. If this condition
persists, it is obviously an application induced deadlock.

> 
> Note: I yet assume that the callbacks could send new elements as long as
> the new elements are sent from the callback and not from a different
> thread being notified. Do you agree? 

johnS:
I agree that an application can decide to add elements directly
in a callback or in a thread that was subsequently woken up
as a result of a notification that occurred in a callback.

I don't think the specification should dictate one or the other.

Think of the callback merely an opportunity to tell the
producer (in the case of an input pipe) that some room
was made in the pipe and more elements can be added.

But let's be careful here. Recall the original intent of
the thread-neutral notify interface was to provide the proper
hooks to allow the implementation of "thread-aware" blocking
functions. The example in the specification (5.7.4.1.1)
of the blocking send implementation shows how the thread-neutral
notify mechanism was intended to be used by a thread-aware
blocking send implementation. In that example the implied
threading system was SystemC. But similar logic would need to
be followed for what ever threading system is being used with
SCE-MI 2.

We were careful to design SCE-MI 2 so it could be implemented
on any C-side threading system and to make clear what
part of the interface was "thread-neutral" and what part
"thread-aware".

Now that said, I can see simple C applications that do not
use a threading system still being able to use SCE-MI 2
by using the thread-neutral portion of the interface.
In this case, it is conceivable that the callbacks themselves
would replenish input pipes (or drain output pipes).

-- johnS
<eom>

> 
> 
> Note that I am not yet establishing an opinion, but rather trying to
> understand better your proposal.
> 
> Thanks,
> 
> Shabtay
> 
> 
> 
>>-----Original Message-----
>>From: John Stickley [mailto:john_stickley@mentor.com]
>>Sent: Tuesday, April 17, 2007 8:47 AM
>>To: Shabtay Matalon
>>Cc: itc@eda.org
>>Subject: Re: my action item for explaining semantics of notify
> 
> callbacks in
> 
>>SCE-MI pipes
>>
>>Shabtay,
>>
>>See comments ...
>>
>>Shabtay Matalon wrote:
>>
>>>Hi John,
>>>
>>>
>>>
>>>I have pulled the sections you changed into this email. Please
> 
> confirm
> 
>>>that these are indeed all sections changed. I'd like to suggest that
> 
> we
> 
>>>first resolve all proposed changes by email before Brian moves the
>>>changes into the new draft.
>>>
>>>
>>>
>>>First section:
>>>
>>>
>>>
>>>The (*scemi_pipe_c_notify_ok_to_send)() and
>>>(*scemi_pipe_c_notify_ok_to_receive)() functions are programmable
>>>callbacks that are denoted here as function pointers rather than
> 
> actual
> 
>>>functions. They are called from within the infrastructure to notify
> 
> the
> 
>>>C-side application that the number of elements in the pipe has
> 
> changed
> 
>>>as a result of a recent send or receive operation.
>>>
>>>For example, if a C-side consumer attempts to receive some number of
>>>elements from a pipe that are not all available, it may wish to go to
>>>sleep but be notified when one or more elements are sent by the
> 
> producer
> 
>>>at the other end. In this case the infrastructure would notify the
>>>consumer via the /OK to receive/ callback.
>>>
>>>Conversely, if a C-side producer attempts to send some number of
>>>elements to a pipe that does not have enough room for all of them, it
>>>may wish to go to sleep but be notified when one or more elements are
>>>received by the consumer at the other end. In this case the
>>>infrastructure would notify the producer via the /OK to send/
> 
> callback.
> 
>>>See section 5.7.4.1.3 for specific semantics governing when the
>>>infrastructure would call the notify functions.
>>>
>>>These functions typically get registered by the C-side application at
>>>initialization time although they can be registered at any time.
>>>Additionally, previously registered notify function pointer can, at
> 
> any
> 
>>>time, be replaced with another.
>>>
>>>Second section:
>>>
>>>
>>>
>>>The infrastructure shall call the notify callbacks specifically under
>>>the following circumstances:
>>>
>>>A send() or try_send() operation has been performed on an output pipe
>>>that adds to the number of elements previously in it. In this case,
> 
> the
> 
>>>/OK to receive/ callback on the C-side will be called exactly once in
>>>any interval of execution during which the infrastructure has control
> 
> of
> 
>>>the thread in which the pipe is being updated - regardless of how
> 
> many
> 
>>>elements were added during interval of control.
>>>
>>>[Shabtay] "in any interval of execution during which the
> 
> infrastructure
> 
>>>has control of the thread in which the pipe is being updated" is not
>>>clear to me. Isn't "each time the infrastructure is called it has
>>>control of the thread" implementation specific? One possible way to
> 
> look
> 
>>>at this is that each time the infrastructure is called it can control
> 
> of
> 
>>>the thread. Another way is that each time infrastructure is called
> 
> _and
> 
>>>the call is not satisfied_, the infrastructure has control of the
> 
> thread.
> 
>>>
>>>
>>>Which of the above interpretations you intended to convey (unless
> 
> there
> 
>>>is a third one)?
>>
>>johnS:
>>Basically it is at a sequence of execution where updates to the
>>pipe buffer are being made but before the particular thread
>>on which that is happening yields to others.
>>
>>See my response to your 2nd question below to see if this makes
>>more sense ...
>>
>>
>>>
>>>
>>>A receive() or try_receive() operation has been performed on an input
>>>pipe that reduces the number of elements previously in it. In this
> 
> case,
> 
>>>the /OK to send/ callback on the C-side will be called exactly once
> 
> in
> 
>>>any interval of execution during which the infrastructure has control
> 
> of
> 
>>>the thread in in which the pipe is being updated - regardless of how
>>>many elements were removed during that interval of control.
>>>
>>>
>>>
>>>
>>>
>>>For example suppose a blocking receive() operation needs to perform
> 
> the
> 
>>>equivalent of 2 try_receive() operations in order to remove all the
>>>requested elements from an input pipe, since the first try_receive()
>>>could only partially fill the request. Between the two operations it
>>>would, by definition, need to suspend its thread (to yield to the
> 
> other
> 
>>>end of the pipe to send more elements). Assuming each of the 2
>>>try_receive() operations altered the number of elements in the pipe,
>>>this would result in exactly 2 notify /OK to send/ callbacks to the C
>>>side - one during each try_receive() operation.
>>>
>>>[Shabtay]From your example, I deduct that both blocking calls and non
>>>blocking calls can suspend the HW side (aka block) and call the /OK
> 
> to
> 
>>>send/ callback. Your example shows that try_receive() actually caused
>>>the producer to add more elements to the pipe. If callbacks are
> 
> allowed
> 
>>>in this case, I assume these take place if try_receive() does not
> 
> have
> 
>>>enough elements in the buffer by your proposal and thus try_receive()
>>>will never fail.
>>>
>>>
>>>
>>>Is this correct?
>>>
>>
>>johnS:
>>No. Just because you call the notify callback does not mean you yield.
>>In fact, recall that whole purpose of the non-blocking part of
>>the API was to remain thread neutral.
>>
>>So all that happens is that the callback is called. There's
>>really no way for the non-blocking try_send/receive() to yield since
>>they are thread unaware.
>>
>>Typically in the callback, the user would place a notify operation but
>>not necessarily a yield. In fact, it is in the blocking
>>call where the yield takes place.
>>
>>So, try_receive notifies the producer via the callback
>>but does not cause it to add more elements at the point
>>of notification.
>>
>>Does this make sense ?
>>
>>-- johnS
>><eom>
>>
>>>
>>>* *
>>>
>>>
>>>
>>>
>>>>-----Original Message-----
>>>
>>>>From: owner-itc@eda.org [mailto:owner-itc@eda.org] On Behalf Of John
>>>
>>>>Stickley
>>>
>>>>Sent: Thursday, April 12, 2007 12:28 PM
>>>
>>>>To: 'itc@eda.org'
>>>
>>>>Subject: my action item for explaining semantics of notify callbacks
> 
> in
> 
>>>>SCE-MI pipes
>>>
>>>>Greetings ITC Techies,
>>>
>>>>As per my AI, I've created a modified version of the spec
>>>
>>>>that explains the specific semantics of notify callback
>>>
>>>>in SCE-MI pipes.
>>>
>>>>I've reset change bars from the MainBody_v3_070125-johnS-3.doc
>>>
>>>>so that only these updates are highlighted.
>>>
>>>>That way, if it looks acceptable, it should be easy for Brian to
>>>
>>>>merge into the new draft.
>>>
>>>>Per reflector limitations, I'll send it as a separate attachment
> 
> called
> 
>>>>    MainBody_v3_070125-johnS-4.doc
>>>
>>>>in another e-mail.
>>>
>>>>-- johnS
>>>
>>>>______________________________/\/            \     \
>>>
>>>>John Stickley                   \             \     \
>>>
>>>>Mgr., Acceleration Methodologies \             \________________
>>>
>>>>Mentor Graphics - MED             \_
>>>
>>>>________________________________________________________________
>>>
>>>>--
>>>
>>>>This message has been scanned for viruses and
>>>
>>>>dangerous content by MailScanner, and is
>>>
>>>>believed to be clean.
>>>
>>>
>>>
>>
>>--
>>
>>This email may contain material that is confidential, privileged
>>and/or attorney work product for the sole use of the intended
>>recipient.  Any review, reliance or distribution by others or
>>forwarding without express permission        /\
>>is strictly prohibited. If you are     /\   |  \
>>not the intended recipient please     |  \ /   |
>>contact the sender and delete        /    \     \
>>all copies.                      /\_/  K2  \_    \_
>>______________________________/\/            \     \
>>John Stickley                   \             \     \
>>Mgr., Acceleration Methodologies \             \________________
>>Mentor Graphics - MED             \_
>>17 E. Cedar Place                   \   john_stickley@mentor.com
>>Ramsey, NJ  07446                    \     Phone: (201) 818-2585
>>________________________________________________________________
> 
> 
> 
> 


-- 

This email may contain material that is confidential, privileged
and/or attorney work product for the sole use of the intended
recipient.  Any review, reliance or distribution by others or
forwarding without express permission        /\
is strictly prohibited. If you are     /\   |  \
not the intended recipient please     |  \ /   |
contact the sender and delete        /    \     \
all copies.                      /\_/  K2  \_    \_
______________________________/\/            \     \
John Stickley                   \             \     \
Mgr., Acceleration Methodologies \             \________________
Mentor Graphics - MED             \_
17 E. Cedar Place                   \   john_stickley@mentor.com
Ramsey, NJ  07446                    \     Phone: (201) 818-2585
________________________________________________________________


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Wed Apr 18 07:07:25 2007

This archive was generated by hypermail 2.1.8 : Wed Apr 18 2007 - 07:07:35 PDT