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\concu*rrencyTrace\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

Reply via email to