Subject: Re: [sv-ec] disabling of single threads
From: Arturo Salz (Arturo.Salz@synopsys.com)
Date: Wed Mar 26 2003 - 22:35:41 PST
Peter,
What you propose is a very straightforward mechanism for a process
to obtain its own process handle, and I believe that feature must be
supported regardless of any other mechanism. The idea is a very
good one (and I believe a requirement).
The problem with using $process as the only mechanism to retrieve
process handles is that it depends on the execution order of the
sub-processes, therefore, other processes cannot reliably access that
information (in particular the parent process in a fork..join_none).
The key idea of my proposal was to provide an atomic mechanism
to make the process-handles of all the forked processes available to
every other process in a reliable manner.
Arturo
----- Original Message -----
From: "Peter Flake" <flake@synopsys.COM>
To: "Arturo Salz" <Arturo.Salz@synopsys.COM>
Cc: <sv-ec@eda.org>
Sent: Wednesday, March 26, 2003 10:27 AM
Subject: Re: [sv-ec] disabling of single threads
Arturo,
Why not have
process p[1:3];
fork
begin p[1] = $process; ....end
begin p[2] = $process; ....end
begin p[3] = $process; ....end
join
If multiple instances are needed, the index could be a variable expression.
Peter.
At 08:43 25/03/2003 -0800, Arturo Salz wrote:
>Kevin,
>
>The problem with using a label is that it is a syntactical mechanism,
>and hence static. All processes created by the same piece of code
>are indistinguishable, and that's not the fine grain process control
>that you and other people were asking for. You already have the
>ability to do that today using disable (at least to kill the processes).
>
> Arturo
>
>----- Original Message -----
>From: "Kevin Cameron" <sv-xx@grfx.com>
>To: <sv-ec@eda.org>
>Cc: <simon@his-home.demon.co.uk>
>Sent: Tuesday, March 25, 2003 12:21 AM
>Subject: Re: [sv-ec] disabling of single threads
>
>
> > From: Simon Davidmann <simon@his-home.demon.co.uk>
> >
> > Arturo,
> >
> > begin :-)
> >
> > I note your new idea below and have a question: where does this fit with
> > the spirit of Verilog?:
> >
> > --- insert --
> > pids = fork
> > p1();
> > p2();
> > p3();
> > join any
> > --- end insert --
> >
> > I cannot recall this language procedural style in any existing Verilog
> > construct.
>
>Got to agree with that. What was wrong with using a method off the fork
>label to get the pids or perform other functions ? - at least it would be
>consistent with other new syntax. E.g.:
>
> fork : f1
> p1();
> p2();
> p3();
> join any
> ...
> disable f1.processes(); // kill dangling processes
>
> > Value returning statements were thrown out with Verilog (we had them in
> > HILO, but Phil left them out of Verilog saying you always need a function
> > call) - next we will have the return of the dreaded valcase... eg
> > a = valcase (i)
> > j: 3;
> > k: 2;
> > endcase
> > i.e. if i == j then a = 3, etc
> >
> > if you want to add this processid stuff, then you need to change the fork
> > to be more like it, ie something like this:
> > pids = fork (any)
> > p1 ();
> > p2 ();
> > p3 ();
> > join
> >
> > and then there are also several other things we should change to make them
> > into this new syntax style - but in fact it is not a nice style:
> >
> > for example could I have
> > val = begin
> > if (a) return (1); else return (0);
> > end
> > i.e. a begin block as well that returns a value? - would make sense right?
> >
> > and then we could have
> > if (begin if (a) return (1); else return (0); end) $display
> > ("returns 0); else $display ("returns 0");
> >
> > and then because the begin end only is one statement we could do without
> > it, etc, like this:
> > if (if (a) return (1); else return (0);) $display... - and it can get
> > quite messy
> >
> > of course we could just say that process assignment from a fork join block
> > is an exception - and we dig a bigger hole - as then whole language just
> > becomes a collection of strange constructs that are only allowed in
> certain
> > conditions in certain places... and we end up with a bad language
> >
> > I recommend not adding new styles away from the spirit of Verilog - unless
> > you overhaul many things properly - adding new styles for each new type of
> > operation just makes the language more and more complex and more and more
> > difficult as a user can never remember exactly how the syntax and
> semantics
> > of each construct or grouping of constructs works.
> >
> > end :-)
>
>BTW, gcc allows you to nest statements in expressions e.g.:
>
> int c = ({int a = x, b = z ; a+b;})
>
>- the last statement of sequence is the result - it's a logical extension of
>the syntax for expressions which lets you do this:
>
> if ((c = 0, b0()) ||
> (c = 1, b1()) ||
> (c = 2, b2())) {
> switch (c) {
> case 0: ... ; // b0 true
> case 1: ... ; // b1 true
> case 2: ... ; // b2 true
> }
>
>- it's actually very useful.
>
>BCPL (a precursor of C) had a similar mechanism for using begin/end blocks
>in expressions.
>
>Kev.
>
> > Simon
> >
> > At 03:15 AM 3/25/2003, Arturo Salz wrote:
> > >Michael,
> > >
> > >My proposal for thread control is attached. Unfortunately, it didn't
> get in
> > >this version.
> > >Your comments are welcome.
> > >
> > > Arturo
> > >
> > >----- Original Message -----
> > >From: "Michael Burns" <Michael.Burns@motorola.com>
> > >To: <sv-ec@eda.org>
> > >Cc: <rob.slater@motorola.com>
> > >Sent: Monday, March 24, 2003 3:24 PM
> > >Subject: [sv-ec] disabling of single threads
> > >
> > >
> > >
> > >Hi folks,
> > >
> > >I have a question about disabling/terminating threads. There does not
> > >appear to be a syntax for terminating a specific thread; you can only
> > >terminate all child threads of the current thread, or terminate all
> > >threads from a named block. Does anyone know of a handy way to start
> > >a bunch of threads, then terminate specific ones under various
> > >conditions? There are folks here in Motorola who are very intereseted
> > >in having this ability - does anyone else have opinions on the
> > >desireability or lack thereof for this feature? If there's a "thread"
> > >on the reflector about this, feel free to just point me there.
> > >
> > >Thanks,
> > >Mike
> > >
> > >From: "Arturo Salz" <salz@synopsys.com>
> > >To: <sv-ec@eda.org>
> > >References: <5.1.0.14.0.20030124102321.029e0000@orange.he.net>
> > >Subject: Re: [sv-ec] Comments on Chapter 9
> > >Date: Mon, 27 Jan 2003 11:02:45 -0800
> > >MIME-Version: 1.0
> > >Content-Type: multipart/alternative;
> > > boundary="----=_NextPart_000_18B9_01C2C5F3.9F1910A0"
> > >X-Priority: 3
> > >X-MSMail-Priority: Normal
> > >X-Mailer: Microsoft Outlook Express 5.50.4807.1700
> > >X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700
> > >
> > >I believe that Kevin and Stefen have brought up very good points. If we
> > >need to provide fine granularity control for SystemVerilog processes then
> > >these mechanisms need to be intuitive, general, and robust.
> > >After reviewing Kevin's proposal I came up with the following proposal.
> > >
> > >Process Control
> > >
> > >Use the process keyword to denote a new built-in class. This way,
> users can
> > >declare objects of type process and safely pass them around through
> tasks or
> > >incorporate them into other objects.
> > >
> > >Objects of type process include several built-in methods:
> > > task terminate - Terminates the process
> > > function int status - Returns process status (0 dead, 1 ready, -1
> > > created, 2 waiting...).
> > > (A cleaner way might be an enum but that would add top-level
> > > identifiers)
> > > task suspend - Suspend execution of the process (process is still
> ready)
> > > task wait - Wait until process terminates
> > >
> > >The key to the process class is that (a) it's an object and therefore
> > >subject to
> > >the same type-checking rules as other objects, (b) it can be garbage
> collected
> > >like any other object, and (c) it's a built-in class, and only the
> > >fork..join construct
> > >creates these types of objects. The statement "process e = new()"
> could be
> > >disallowed altogether, or it could be used to retrieve a handle to the
> > >calling process.
> > >
> > >Also required is an atomic mechanism for assigning all process'es
> created by a
> > >fork..join. Atomic means a mechanism whereby all processes are
> > >initialized before
> > >the calling process or any of the sub-processes has had a chance to
> > >execute and
> > >perhaps terminate. One way to provide for this would be to modify the
> > >grammar of
> > >the fork construct to accomplish this:
> > >
> > >process pids[*];
> > >
> > >pids = fork
> > > p1();
> > > p2();
> > > p3();
> > >join any
> > >
> > >// user implementation of fork ... join
> > >// and terminate all remaining processes.
> > >// Like a priority fork .. join
> > >
> > >for( int i = 0; i < pids.size; i++ ) begin
> > > if( pids[i].status != 0 )
> > > pids[i].terminate();
> > >end
> > >The example shows using a dynamic array to receive the process objects,
> > >but one
> > >could also use a fixed-size array (i.e., pids[1:3]). The basic
> concept is
> > >that the pids
> > >array is initialized by fork before any of the sub-processes begin
> > >executing. This way
> > >the parent process, or any of the sub-processes has access to all the
> > >process objects
> > >and avoids a situation where a process executes and terminates before one
> > >has had a
> > >chance to monitor the process externally.
> > >
> > >Also, by making this an explicit part of the fork..join, the compiler can
> > >decide if all the
> > >process objects are needed and optimize accordingly.
> > >
> > > Arturo
> > >
> > >
This archive was generated by hypermail 2b28 : Wed Mar 26 2003 - 22:33:35 PST