Similar comments:  this extra information seems to be aimed at 'developers',
not users.   A user seeing the proposed output would have no idea what it
means or what it's about.  It's astonishing, in every sense.

To me this seems absolutely contrary to the Rexx principles.   If developers
need this kind of information, cannot this be achieved by other, less
visible and less ugly, means?
 
Mike

Some comments:  


1) the T and A columns are a bit redundant. We really only need a single
identifier for the thread, having two is just extra clutter. 
2) The term activity is introduced here without explanation. It doesn't
really appear any other place in the documentation and is really more of an
internal concept than part of the language. If it is used here, then this
needs to be used consistently in all other places that concurrency is
discussed. 
3) The variable pool term is a bit misleading. The thing that gets locked is
the object's variable pool for a particular scope, not all of the variables
for the object. For example, two different threads might have the GUARD lock
on the same object at different scope levels. Knowing the scope would be a
very useful piece of information. 
4) I don't like the use of the term "lock" here. At least refer to them as a
GUARD lock, since that is the concept that is used in other places. 
5) I still don't like the M prefix. I think things would just be simpler if
multi-thread mode is used any time there are multiple active threads. 

Rick  

On Sat, Feb 11, 2023 at 12:02 PM Rony G. Flatscher <rony.flatsc...@wu.ac.at>
wrote:


Ad documentation: here a draft, meant for rexxref.pdf, chapter "12.
Concurrency", suggesting of adding a section at the end (activity, variable
pool, locks already explained in that chapter):

--------------



12.5 Tracing Concurrent Execution



Each invoked routine and method routine will execute on a proper activity.
If a

method runs for different objects each such invocation will execute on a
proper

activity. Activities may run on different threads if sending messages

concurrently or using the reply keyword instruction.



Upon entry of a method routine access to the variable pool of the object
(its

object variables, attributes) gets secured by reserving exclusive access by

default.  If a concurrent message to the same object gets sent from a

concurrently executing part of the program, then the method routine attempts
to

get the lock on the variable pool and will be blocked as long as the the
owning

method routine for that object does not release it, either by returning from

the method invocation or by issuing "guard off" in its routine.



If a method routine's activity owns the variable pool lock it may invoke
other

method routines by sending the message to "self" without getting blocked.



In order to help understand and debug concurrently executing programs the
TRACE

keyword instruction and the TRACE() built-in function allow for supplying

additional trace output information by adding five columns to the begin of
the

trace output:



- the Rexx instance column: the letter 'R' plus a unique number denoting a

proper Rexx interpreter instance.  This is a counter that starts out with 1.

If ooRexx gets instrumentated by applications it may be possible that
different

Rexx programs may execute concurrently on different Rexx interpreter
instances

(cf. rexxapi.pdf, 1.1.1 RexxCreateInterpreter).



- the operating system thread column: the letter 'T' plus a unique number
per

operating system thread in the process.  This is a counter that starts out
with

1.



- the activity column: the letter 'A' plus a unique number per activity

currently used for executing a specific routine or method routine for a
specific

object.  This is a counter that starts out with 1.  Please note: upon return

from a routine its activity will get returned to the interpreter and will
get

reused for future routine or method routine invocations.



- the variable pool column: the letter 'V' plus a unique number which
indicates

the attributes (object variables) of a specific object for which a method

routine gets executed on an activity.  This is a counter that starts out
with 1.



- the lock column: empty, if no lock issued yet (maybe blocked), or a

number that indicates how many locks there are for the variable pool.  If

a number is shown, then a trailing asterisk (*) indicates which activity

owns the lock, i.e.  the object's variable pool.  If the trailing asterisk

is missing, than that activity is currently blocked.



--------------------------------------- trace example 1 (begin)
-------------------

Tracing Example 1: Asynchroneously sending the same message to two

different objects of the same class (no blocking takes place)





        /* Example of using a message object */

        object1 = .example~new

        object2 = .example~new

        a = object1~start("REPEAT",3,"Object 1 running")

        b = object2~start("REPEAT",3,"Object 2 running")

        say "a:" a~result

        say "b:" b~result

        say "Main ended."



        ::class example

        ::method repeat

           use arg reps,msg

           do reps

              say msg

           end

           return "Repeated" msg"," reps "times."



        ::options trace a



Trace output:





        R1   T1   A1                    2 *-* object1 = .example~new

        R1   T1   A1                    3 *-* object2 = .example~new

        R1   T1   A1                    4 *-* a =
object1~start("REPEAT",3,"Object 1 running")

        R1   T1   A1                    5 *-* b =
object2~start("REPEAT",3,"Object 2 running")

        R1   T1   A1                    6 *-* say "a:" a~result

        R1   T2   A2    V1                >I> Method "REPEAT" with scope
"EXAMPLE" in package "G:\oorexx.tmp\concurrencyTrace\example_12_3.rex".

        R1   T2   A2    V1      1*     12 *-* use arg reps,msg

        R1   T3   A3    V2                >I> Method "REPEAT" with scope
"EXAMPLE" in package "G:\oorexx.tmp\concurrencyTrace\example_12_3.rex".

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T3   A3    V2      1*     12 *-* use arg reps,msg

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 2 running

        R1   T3   A3    V2      1*     13 *-* do reps

        R1   T2   A2    V1      1*     15 *-* end

        R1   T3   A3    V2      1*     14 *-*   say msg

        Object 1 running

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T3   A3    V2      1*     15 *-* end

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 2 running

        R1   T3   A3    V2      1*     13 *-* do reps

        R1   T2   A2    V1      1*     15 *-* end

        R1   T3   A3    V2      1*     14 *-*   say msg

        Object 1 running

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T3   A3    V2      1*     15 *-* end

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 2 running

        R1   T3   A3    V2      1*     13 *-* do reps

        R1   T2   A2    V1      1*     15 *-* end

        R1   T3   A3    V2      1*     14 *-*   say msg

        Object 1 running

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T3   A3    V2      1*     15 *-* end

        R1   T2   A2    V1      1*     16 *-* return "Repeated" msg"," reps
"times."

        R1   T3   A3    V2      1*     13 *-* do reps

        R1   T3   A3    V2      1*     16 *-* return "Repeated" msg"," reps
"times."

        a: Repeated Object 1 running, 3 times.

        R1   T1   A1                    7 *-* say "b:" b~result

        b: Repeated Object 2 running, 3 times.

        R1   T1   A1                    8 *-* say "Main ended."

        Main ended.



--------------------------------------- trace example 1 (end)
-------------------







--------------------------------------- trace example 2 (begin)
-------------------



Tracing Example 2: Asynchroneously sending the same message to the same

object of the same class (blocking takes place)



        /* Example of methods with the same scope not running concurrently*/

        object1 = .example~new



        a = object1~start("REPEAT",3,"Object 1 running call 1")

        b = object1~start("REPEAT",3,"Object 1 running call 2")

        say "a:" a~result

        say "b:" b~result

        say "Main ended." /* concurrently. */



        ::class example

        ::method repeat

           use arg reps,msg

           do reps

              say msg

           end

           return "Repeated" msg"," reps "times."



        ::options trace a



Trace output:



        R1   T1   A1                    2 *-* object1 = .example~new

        R1   T1   A1                    4 *-* a =
object1~start("REPEAT",3,"Object 1 running call 1")

        R1   T1   A1                    5 *-* b =
object1~start("REPEAT",3,"Object 1 running call 2")

        R1   T1   A1                    6 *-* say "a:" a~result

        R1   T2   A2    V1                >I> Method "REPEAT" with scope
"EXAMPLE" in package "G:\oorexx.tmp\concurrencyTrace\example_12_4.rex".

        R1   T3   A3    V1                >I> Method "REPEAT" with scope
"EXAMPLE" in package "G:\oorexx.tmp\concurrencyTrace\example_12_4.rex".

        R1   T2   A2    V1      1*     12 *-* use arg reps,msg

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 1 running call 2

        R1   T2   A2    V1      1*     15 *-* end

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 1 running call 2

        R1   T2   A2    V1      1*     15 *-* end

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T2   A2    V1      1*     14 *-*   say msg

        Object 1 running call 2

        R1   T2   A2    V1      1*     15 *-* end

        R1   T2   A2    V1      1*     13 *-* do reps

        R1   T2   A2    V1      1*     16 *-* return "Repeated" msg"," reps
"times."

        R1   T3   A3    V1      1*     12 *-* use arg reps,msg

        R1   T3   A3    V1      1*     13 *-* do reps

        R1   T3   A3    V1      1*     14 *-*   say msg

        Object 1 running call 1

        R1   T3   A3    V1      1*     15 *-* end

        R1   T3   A3    V1      1*     13 *-* do reps

        R1   T3   A3    V1      1*     14 *-*   say msg

        Object 1 running call 1

        R1   T3   A3    V1      1*     15 *-* end

        R1   T3   A3    V1      1*     13 *-* do reps

        R1   T3   A3    V1      1*     14 *-*   say msg

        Object 1 running call 1

        R1   T3   A3    V1      1*     15 *-* end

        R1   T3   A3    V1      1*     13 *-* do reps

        R1   T3   A3    V1      1*     16 *-* return "Repeated" msg"," reps
"times."

        a: Repeated Object 1 running call 1, 3 times.

        R1   T1   A1                    7 *-* say "b:" b~result

        b: Repeated Object 1 running call 2, 3 times.

        R1   T1   A1                    8 *-* say "Main ended." /*
concurrently. */

        Main ended.



--------------------------------------- trace example 2 (end)
-------------------



---rony





On 09.02.2023 13:27, Rick McGuire wrote:


This is one of those features where I think I need to see the complete
documentation written first before any code is checked in. In particular, I
have some reservations on how this explicitly introduces activities and
reservation counts concepts to the language without them ever appearing
elsewhere in the language reference. I'm also not willing to accept the
format with which the additional information is added without some
additional discussion. Also the concept of giving the activities a unique
identifier. Since activities are pooled and reused, it needs to be defined
how that all plays out. This feature, while useful, needs a lot more
discussion before it is put in place.  

Rick

On Thu, Feb 9, 2023 at 7:21 AM Rony G. Flatscher <rony.flatsc...@wu.ac.at>
wrote:


Thanks for the feedback. Probably putting M as the trailing letter after the
alphabetic letter as Mike suggests is the best option. Omitting the trailing
M would switch back to the simple form. Would that be acceptable for
everyone?


---rony




On 08.02.2023 21:24, Rick McGuire wrote:


The special symbol characters "." and "_" are also available as indicators.
I'm a definite -1 to using environment variables and Erich has also voiced
his displeasure about that.  

Another option might be to allow a second keyword following the trace type
that indicates using the expanded form. It should also allow explicit
specification of the simple form too. 


Rick

On Wed, Feb 8, 2023 at 2:46 PM Mike Cowlishaw <m...@speleotrove.com> wrote:


I would have put the M after the other letter because it's really a
subsidiary option.  If it's first it rather 'M'asks the main option?
 
Mike


  _____  

From: Rony G. Flatscher [mailto:rony.flatsc...@wu.ac.at] 
Sent: 08 February 2023 14:16
To: oorexx-devel@lists.sourceforge.net
Subject: [Oorexx-devel] Planning to add multithreaded (concurrent) tracing
(Re: RFC for feature request "794 Concurrency request"



Coming back to this RFE from 17 months ago which I would like to add to
trunk. Without it one can hardly use TRACE for debugging multithreaded
programs in a Rexx-like, i.e. easy manner.


Currently having tried to incorporate the feedback about too many
whitespaces between the new columns (Rexx interpreter instance number,
Thread number, Activity number, reserved object pool).


There was another idea about making this concurrency/multihreaded trace
available without a need to define an environment variable
RXTRACE_CONCURRENCY before starting a Rexx program. This post is about ideas
of how to activate and deactivate concurrent tracing at runtime (either via
the TRACE keyword instruction or the TRACE()-BIF) in a manner that is
intuitive and easy to remember.


One possibility would be to introduce new alphabetic options, this time with
two letters by prepending the letter 'M' (for multithreaded as the letter c
is already used for tracing commands and may therefore be irritating) to the
existing alphabetic characters, hence defining the following semantics:



Trace
        Option, turn off MT
        Option, turn on MT
        
All
        A
        MA
        
Command
        C
        MC
        
Error
        E
        ME
        
Failure
        F
        MF
        
Intermediates
        I
        MI
        
Labels
        L
        ML
        
Normal
        N
        MN
        
Off
        O
        -
        
Results
        R
        MR
        

        
        
        

This would have the benefit that anytime it becomes possible to turn on and
to turn off multithreaded/concurrent tracing at runtime.


What do you think?

---rony

P.S.: The "fallback" would be to just add it as is, i.e. using the
environment variable RXTRACE_CONCURRENCY, making the
multithreaded/concurrent tracing a global option that needs to be set before
running a Rexx program. 





On 05.09.2021 14:12, Rony G. Flatscher wrote:


Almost a week ago Jean Louis Faucher registered feature request "794
Concurrency request", cf.

 <https://sourceforge.net/p/oorexx/feature-requests/794/>
<https://sourceforge.net/p/oorexx/feature-requests/794/> together with a
patch that implements the

feature request. So far there have been no comments, hence "requesting for
comments (RFC)" here as

it may be the case that the RFE has been overlooked.



---



IMHO this RFE is incredible helpful for debugging multi-threaded Rexx
programs and for understanding

how ooRexx dispatches multithreaded code.



The way Jean Louis devised the implementation has practically no impact on
the interpreter (unless

one defines an environment variable "RXTRACE_CONCURRENCY=on" modelled after
the existing

"RXTRACE=ON" environment variable in which case helpful information gets
generated for prefixing

each trace output statement) makes it easy even for beginners (= students)
to get insight and

understand how ooRexx executes multithreaded programs. Some problems rooted
in multithreaded Rexx

code can be quickly located, understood and resolved with this feature.



Having tested this concurrency trace feature with the most challenging
JavaFX ooRexx programs I have

been really impressed with the results. Using the ooRexx program
"samples/tracer.rex" (included in

the patch) to render the massive concurrency trace output of some JavaFX
ooRexx programs to csv and

importing the concurrency trace into a spreadsheet (e.g. Excel) makes it
possible to analyze such

massive concurrency traces in every possible detail using the spreadsheet
features (e.g. filtering

for a specific ooRexx interpreter instance or specific threads, pivots and
the like). Therefore I

uploaded one such test to this RFE such that one can directly get at the
massive concurrency trace,

the csv file created by "tracer.rex" from it and an Excel spreadsheet which
was used to import the

generated csv file. (I wished this feature had been available when devising
some of the BSF4ooRexx

JavaFX samples, which would have saved me literally weeks of debugging!)



The patch implementing RFE 794 makes it really easy for ooRexx programmers
to understand and to

debug multithreaded ooRexx programs, saving them a *lot* of time trying to
understand what happens,

how concurrent statements get executed by the interpreter(s) and locating
coding errors!



---rony


_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel


_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to