Phillip is fundamentally correct. The goal of this standardization effort is
to protect the internal structures of the kernel and make it possible to
safely and reliably make an external call to invoke update. The update
itself may need to take care of safety issues additionally, but that is
really a problem for the end-user to be concerned with (i.e. outside the
scope of the standard).
The one example I like to use is a channel that simply does
sc_event::notify(SC_ZERO_TIME), which is visible only internal to SystemC.
By careful use of handshakes, mutexes, fifo and semaphores, the rest of the
communication problem is managed outside of update(). My example tries to
minimize what I put into update() to minimize issues there. Here is a bit
more detail:
The SystemC simulation and external process have a shared memory object
(lookup up POSIX mmap for a description). There is a bool ownership flag.
The protocol is for whoever owns the shared memory to relinquish ownership
to the other and issue a POSIX signal USR1. The recipient receives the event
and proceeds to use/update the shared memory as it desires until it wishes
to relinquish the memory object. At no point in time will a non-owner use or
modify the shared data.
This example worked because the usage model fit the application. If I needed
more access, I would have used a scoped mutex.
I suppose it would be important to communicate to the reader of this feature
(async_request_update), that they are responsible for managing safety of
their channel's data. This enhancement does not do that for them (nor could
it).
On Mon, Nov 29, 2010 at 5:37 AM, <john.aynsley@doulos.com> wrote:
> Philipp, David,
>
> Yes, we are on the same page. If we do include async_request_update in the
> LRM then I think we need to spell out the recommended usage carefully,
> otherwise users are going to make mistakes. Should we give an example using
> an sc_mutex to protect a member m_new_value, perhaps?
>
> David, what is your take on this?
>
> What about everyone else?
>
> John A
>
>
> From:
> "Philipp A. Hartmann" <philipp.hartmann@offis.de>
> To: john.aynsley@doulos.com Cc: David Black <dcblack@xtreme-eda.com>,
> P1666 Technical WG <systemc-p1666-technical@eda.org> Date: 28/11/2010
> 21:19 Subject: Re: Wording proposal for request_safe_update
>
> ------------------------------
>
>
>
> John,
>
> as said in my original mail on this subject, mixing
> request_update/async_request_update is not the real problem.
>
> To me, async_request_update has a single purpose: protect the kernel's
> internal structures of the update handling, when an update is requested
> from the outside. This covers races between concurrent request_update
> calls to different channels, that are now possible due to the presence
> of external callers.
>
> Anything else is NOT handled by this mechanism. Am I missing some
> magic synchronisation definition in the proposal?
>
> I'll try to explain my point with the following, simple example (untested):
>
> struct async_double_signal
> : virtual sc_signal_inout_if<double>, sc_prim_channel
> {
> double m_cur_val, m_new_val;
>
> void write( double d ){
> async_request_update();
> m_new_val = d;
> }
>
> void update()
> {
> // ...
> m_cur_val = m_new_val;
> }
> };
>
> So let's look at this channel. Is everything fine, if we _only_ call
> 'write' from a single process outside of SystemC? Are we done? No. We
> still have races on the shared data members during update() and write().
> m_new_val might contain a "new" value, an "old" value, or complete
> garbage (if the write 'm_new_val = d' is not atomic).
>
> Additional calls to write() from SystemC processes might of course add
> further races _within_ the write() function. But this again affects the
> internal integrity of the channel, not the interaction with the kernel.
> Even with the above 'write' function, that always calls
> async_request_update, these races can still be an issue. So using
> request_update/async_request_update is the least to worry about, here.
>
> The simple rule could be:
> - use async_request_update in functions, that can be called from
> the outside of SystemC
> - use request_update otherwise
> This requires a safe implementation of the update phase, of course.
>
> We should add a recommendation, that the shared data needs to be
> properly synchronised. But the details are really out of the scope of
> the LRM and very application-specific, I think.
>
> That said, I'm still fine with disallowing both (async_)request_update
> calls from a primitive channel. It just feels to me like barking up
> some rather small tree... ;-)
>
> Greetings from Oldenburg,
> Philipp
>
> On 28/11/10 10:13, john.aynsley@doulos.com wrote:
> > David, Philipp,
> >
> > Wait a minute. Maybe I'm just being slow here. update() has to copy data
> from some memory used by the external thread to some memory used by the
> SystemC kernel. Both areas would typically be members of the primitive
> channel itself, as in sc_signal::m_new_val and sc_signal::m_cur_val. We
> cannot allow SystemC and non-SystemC threads to race each other to write to
> the equivalent of sc_signal::m_new_val. If we allowed both request_update
> and async_request_update, the update() method would typically have to know
> (using an application-defined flag) which was being serviced so it copy data
> from the appropriate domain (or something to that effect).
> >
> > In other words, I think I am agreeing with David that an application
> shall not call both for a given channel. Also, should we give the LRM reader
> some guidelines as the expected usage, i.e. (in the absence of explicit
> application-defined sync mechanisms) update() should copy from members of
> the channel that are only written to by the external thread?
> >
> > John A
> >
> >
> > -----David C Black <dcblack@xtreme-eda.com> wrote: -----
> > To: john.aynsley@doulos.com
> > From: David C Black <dcblack@xtreme-eda.com>
> > Date: 11/25/2010 01:43PM
> > Cc: "Philipp A. Hartmann" <philipp.hartmann@offis.de>,
> systemc-p1666-technical@eda.org
> > Subject: Re: Wording proposal for request_safe_update
> >
> > I personally don't think the idea of a channel calling both request
> mechanisms in the same cycle is a good idea. The idea is to create special
> channels for the async_request_update. The async version will always have a
> performance penalty to ensure safety.
> >
> > When I looked at the code and considered the issue, I realized it would
> be bad if that happened with the implementation I had; however, it was
> easy to make it resilient. I added a separate pointer for the safe vs
> normal sc_prim_channel mechanisms. This adds a small space overhead with
> no performance penalty (unless you count construction time during
> elaboration). So you can call both mechanisms with the net result that
> update will be called twice. Since I think this should be discouraged, I
> don't think it is a bad thing. At least the code is now "safe" from that
> scenario.
> >
> > Of course an sc_prim_channel derived class could have an internal flag
> that it uses to determine which of the two it will use (for its duration).
> >
> > BOTTOM LINE: I suggest adding text to the effect:
> >
> >
> > An sc_prim_channel object shall not call both request_update and
> async_request_update. The results of violating this are undefined.
> >
> > On Thu, Nov 25, 2010 at 4:06 AM, <john.aynsley@doulos.com> wrote:
> > Philipp, David,
> >
> > Philip wrote "I think, we can allow both as long as they result in a
> _single_ call to 'update' in the corresponding update phase as it is for
> multiple, regular 'request_update' calls, too. (although I haven't found any
> explicit wording covering this?)."
> >
> > In my mind I was assuming the regular request_update had this behavior,
> because I remember writing that the update request queue is a "set". I need
> to tweak the LRM to make this unambiguous.
> >
> > Given that, we have two choices:
> >
> > * Allow request_update and aync_request_update to be mixed for the same
> primitive channel instance. This means that the implementation has to be
> able to handle this case.
> >
> > * Disallow it, which may simplify the implementation a little in the
> sense that async_request_update can assume there are no regular update
> requests in the queue for that primitive channel.
> >
> > What does the current implementation do, David? Which way should we go?
> >
> > John A
> >
> >
> >
> > From: "Philipp A. Hartmann" <philipp.hartmann@offis.de> To:
> David C Black <dcblack@xtreme-eda.com>, john.aynsley@doulos.com Cc:
> systemc-p1666-technical@eda.org Date: 24/11/2010 16:09 Subject: Re:
> Wording proposal for request_safe_update
> >
> >
> >
> >
> > John, David,
> >
> > simultaneous calls to '(async_)request_thread_safe_update' and
> > 'request_update' and are not really the key issue.
> >
> > I think, we can allow both as long as they result in a _single_ call
> > to 'update' in the corresponding update phase as it is for multiple,
> > regular 'request_update' calls, too. (although I haven't found any
> > explicit wording covering this?).
> >
> > The real issue is here, that the user can't arbitrarily access the
> > state of the current channel that actually provides this asynchronous
> > access (and therefore calls request_thread_safe_update internally).
> > Such concurrent accesses from inside the SystemC model and from other
> > parts of the application might need to be protected by additional,
> > application defined locking techniques. But this is out of the scope of
> > the standard. It could warrant a note, though.
> >
> > Greetings from Oldenburg,
> > Philipp
> >
> > On 24/11/10 15:08, David C Black wrote:
> > >
> > > On Wed, Nov 24, 2010 at 4:31 AM, <john.aynsley@doulos.com> wrote:
> > [snip]
> > >> 2nd question: Are there any dependencies or interactions between
> > >> request_update and request_thread_safe_update? Can you have both for
> the
> > >> same primitive channel instance? What happens?
> > >
> > > Good point, I think it should be stated that it is undefined if both
> are
> > > called. Choose one or the other.
>
>
> --
> Philipp A. Hartmann
> Hardware/Software Design Methodology Group
>
> OFFIS Institute for Information Technology
> R&D Division Transportation · FuE-Bereich Verkehr
> Escherweg 2 · 26121 Oldenburg · Germany · http://www.offis.de/
> Phone/Fax: +49-441-9722-420/282 · PGP: 0x9161A5C0 · Skype: phi.har
>
>
>
>
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Mon Nov 29 07:36:17 2010
This archive was generated by hypermail 2.1.8 : Mon Nov 29 2010 - 07:36:21 PST