Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-12 Thread P. O. Jonsson
Just like Jon I see myself as a user not a developer (of ooRexx) but in rare cases I would appreciate a trace for multiple threads. We have number of test cases that work when executed as-is but that hang or fail when run in the test framework. I have no opinion on what form it should have but if Ricks proposal of a unique identifier of each thread in the normal trace is sufficient that would be less invasive but per definition a trace is “Ugly” in the sense that it is proof of a failure  Von meinem iPhone gesendetAm 12.02.2023 um 18:48 schrieb Sahananda Sahananda :I don't know if it is helpful for me to say this, but just in case.  When creating ooDialog scripts (I think of myself principally as a USER of ooRexx and ooDialog though I also have my users who don't code) I have sometimes had a great need for this kind of trace.Things can hang, and it often isn't clear where they are or the journey they have taken to get there, as you are handling (perhaps simultaneously) messages from Windows GUI.In the past I have had to resort (with Mark Miesfeld or Rick's help) to the C++ tools to get a chance of understanding what is going on - and for a mere user like me - that is far more difficult.I can understand how users could go through life, and never be in a position where they need to look at multiple threads, and I'm glad for them, but should they prevent these tools being available when they are needed.hope that helpsJonOn Sun, 12 Feb 2023 at 14:41, Rony G. Flatscher  wrote:
  

  
  
On 11.02.2023 20:11, Mike Cowlishaw
  wrote:


  
  
  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.
  

Not sure what you mean when writing "developers" or "users" in
  this context. 
Just to be clear about the meanings in this e-mail context:
  "developer" means the "developer of an ooRexx program" and "user"
  means "user of an ooRexx program (probably not a programmer)".
This is about the TRACE instruction that gets usually used for
  debugging when developing programs, users of programs usually do
  not get to see TRACE output (with the single exception that a
  command causing a failure will be traced by default).


  
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?

There may be a misunderstanding here.

Multithreaded tracing is meant to help the *developers* of an
  ooRexx program to trace ooRexx programs that execute in different
  threads for debugging purposes (there is no need for this in
  classic Rexx). The next context is that the execution environment
  are method routines, i.e. method routines usually defined in
  classes and being executed on behalf of an ooRexx object (as
  classic Rexx has no classes/methods there is no reason to trace
  them).
The ooRexx reference, rexxref.pdf, documents concurrency in
  ooRexx in chapter "12. Concurrency" such that one can expect that
  there are ooRexx programmers who will apply/exploit it.
---

The ooRexx TRACE is modeled after the classic Rexx trace and
  currently does unfortunately not have the ability to gain insight
  of what happens when ooRexx programs execute in a mulithreaded
  fashion.
Take a look at this ooRexx program taking advantage of ooRexx'
  concurrency:

  c1 = .c~new
call syssleep 0.5
c1~m2 -- wake-up m1
say "done"

::class C
::method init
expose s
s = 0
reply

self~m1

::method m1
expose s
s = 1
guard off
say "before guard" -- here, no lock
guard on when s <> 1 -- but here, is locked while waiting...
say "after guard"

::method m2
expose s
s = 2

-- ::options trace a



If you run this program it will hang (run into a deadlock), here
  the output thanks to some say-statements for debugging:

  G:\test\orx\trace>jlf_dl1.rex
before guard


The program just hangs, one must CTL-C to break the running
  program. 

So where is the problem? The current TRACE does not help to shed
  any light on the (concurrent) ooRexx context.
This is where the MT tracing enhancement comes into play,
  following the "Rexx principles" to make the programmers better
  understand what happens and how the Rexx program gets executed.
  After all, this is the motivation that you came up with TRACE,
  right?
So in the post-classic Rexx, ooRexx, allowing for exploiting OO,
  concurrency, messaging etc., TRACE needs to be enhanced
  accordingly to help and ease 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-12 Thread Sahananda Sahananda
I don't know if it is helpful for me to say this, but just in case.

When creating ooDialog scripts (I think of myself principally as a USER of
ooRexx and ooDialog though I also have my users who don't code) I have
sometimes had a great need for this kind of trace.

Things can hang, and it often isn't clear where they are or the journey
they have taken to get there, as you are handling (perhaps simultaneously)
messages from Windows GUI.

In the past I have had to resort (with Mark Miesfeld or Rick's help) to the
C++ tools to get a chance of understanding what is going on - and for a
mere user like me - that is far more difficult.

I can understand how users could go through life, and never be in a
position where they need to look at multiple threads, and I'm glad for
them, but should they prevent these tools being available when they are
needed.

hope that helps

Jon

On Sun, 12 Feb 2023 at 14:41, Rony G. Flatscher 
wrote:

> On 11.02.2023 20:11, Mike Cowlishaw wrote:
>
> 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.
>
> Not sure what you mean when writing "developers" or "users" in this
> context.
>
> Just to be clear about the meanings in this e-mail context: "developer"
> means the "developer of an ooRexx program" and "user" means "user of an
> ooRexx program (probably not a programmer)".
>
> This is about the TRACE instruction that gets usually used for debugging
> when developing programs, users of programs usually do not get to see TRACE
> output (with the single exception that a command causing a failure will be
> traced by default).
>
>
> 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?
>
> There may be a misunderstanding here.
>
> Multithreaded tracing is meant to help the *developers* of an ooRexx
> program to trace ooRexx programs that execute in different threads for
> debugging purposes (there is no need for this in classic Rexx). The next
> context is that the execution environment are method routines, i.e. method
> routines usually defined in classes and being executed on behalf of an
> ooRexx object (as classic Rexx has no classes/methods there is no reason to
> trace them).
>
> The ooRexx reference, rexxref.pdf, documents concurrency in ooRexx in
> chapter "12. Concurrency" such that one can expect that there are ooRexx
> programmers who will apply/exploit it.
>
> ---
>
> The ooRexx TRACE is modeled after the classic Rexx trace and currently
> does unfortunately not have the ability to gain insight of what happens
> when ooRexx programs execute in a mulithreaded fashion.
>
> Take a look at this ooRexx program taking advantage of ooRexx' concurrency:
>
> c1 = .c~new
> call syssleep 0.5
> c1~m2 -- wake-up m1
> say "done"
>
> ::class C
> ::method init
> expose s
> s = 0
> reply
>
> self~m1
>
> ::method m1
> expose s
> s = 1
> guard off
> say "before guard" -- here, no lock
> guard on when s <> 1 -- but here, is locked while waiting...
> say "after guard"
>
> ::method m2
> expose s
> s = 2
>
> -- ::options trace a
>
>
> If you run this program it will hang (run into a deadlock), here the
> output thanks to some say-statements for debugging:
>
> G:\test\orx\trace>jlf_dl1.rex
> before guard
>
> The program just hangs, one must CTL-C to break the running program.
>
> So where is the problem? The current TRACE does not help to shed any light
> on the (concurrent) ooRexx context.
>
> This is where the MT tracing enhancement comes into play, following the
> "Rexx principles" to make the programmers better understand what happens
> and how the Rexx program gets executed. After all, this is the motivation
> that you came up with TRACE, right?
>
> So in the post-classic Rexx, ooRexx, allowing for exploiting OO,
> concurrency, messaging etc., TRACE needs to be enhanced accordingly to help
> and ease the ooRexx program developer with his work when hitting problems
> because of the complex environment concurrently executing ooRexx programs
> have to relate to. It is about making debugging in this application area
> easier than is currently possible.
>
> To illustrate, firstly here a TRACE A in "classic Rexx style" as currently
> implemented in ooRexx 5.0 (by uncommenting the options directive at the end
> of the above program which will set TRACE A for the entire package, i.e.
> for all routines in that program):
>
> G:\test\orx\trace>jlf_dl1.rex
>  1 *-* c1 = .c~new
>>I> Method "INIT" with scope "C" in package 
> "G:\test\orx\trace\jlf_dl1.rex".
>  8 *-* expose s
>  9 *-* s = 0
> 10 *-* reply
>  2 *-* call syssleep 0.5
>>I> Method "INIT" with scope "C" in package 
> "G:\test\orx\trace\jlf_dl1.rex".
> 12 *-* self~m1
> 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-12 Thread Rony G. Flatscher

On 11.02.2023 20:11, Mike Cowlishaw wrote:
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.


Not sure what you mean when writing "developers" or "users" in this context.

Just to be clear about the meanings in this e-mail context: "developer" means the "developer of an 
ooRexx program" and "user" means "user of an ooRexx program (probably not a programmer)".


This is about the TRACE instruction that gets usually used for debugging when developing programs, 
users of programs usually do not get to see TRACE output (with the single exception that a command 
causing a failure will be traced by default).




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?


There may be a misunderstanding here.

Multithreaded tracing is meant to help the *developers* of an ooRexx program to trace ooRexx 
programs that execute in different threads for debugging purposes (there is no need for this in 
classic Rexx). The next context is that the execution environment are method routines, i.e. method 
routines usually defined in classes and being executed on behalf of an ooRexx object (as classic 
Rexx has no classes/methods there is no reason to trace them).


The ooRexx reference, rexxref.pdf, documents concurrency in ooRexx in chapter "12. Concurrency" such 
that one can expect that there are ooRexx programmers who will apply/exploit it.


---

The ooRexx TRACE is modeled after the classic Rexx trace and currently does unfortunately not have 
the ability to gain insight of what happens when ooRexx programs execute in a mulithreaded fashion.


Take a look at this ooRexx program taking advantage of ooRexx' concurrency:

   c1 = .c~new
   call syssleep 0.5
   c1~m2 -- wake-up m1
   say "done"

   ::class C
   ::method init
expose s
s = 0
reply

self~m1


   ::method m1
expose s
s = 1
guard off
say "before guard" -- here, no lock
guard on when s <> 1 -- but here, is locked while waiting...
say "after guard"

   ::method m2
expose s
s = 2

   -- ::options trace a

If you run this program it will hang (run into a deadlock), here the output thanks to some 
say-statements for debugging:


   G:\test\orx\trace>jlf_dl1.rex
   before guard

The program just hangs, one must CTL-C to break the running program.

So where is the problem? The current TRACE does not help to shed any light on the (concurrent) 
ooRexx context.


This is where the MT tracing enhancement comes into play, following the "Rexx principles" to make 
the programmers better understand what happens and how the Rexx program gets executed. After all, 
this is the motivation that you came up with TRACE, right?


So in the post-classic Rexx, ooRexx, allowing for exploiting OO, concurrency, messaging etc., TRACE 
needs to be enhanced accordingly to help and ease the ooRexx program developer with his work when 
hitting problems because of the complex environment concurrently executing ooRexx programs have to 
relate to. It is about making debugging in this application area easier than is currently possible.


To illustrate, firstly here a TRACE A in "classic Rexx style" as currently implemented in ooRexx 5.0 
(by uncommenting the options directive at the end of the above program which will set TRACE A for 
the entire package, i.e. for all routines in that program):


   G:\test\orx\trace>jlf_dl1.rex
 1 *-* c1 = .c~new
   >I> Method "INIT" with scope "C" in package 
"G:\test\orx\trace\jlf_dl1.rex".
 8 *-* expose s
 9 *-* s = 0
10 *-* reply
 2 *-* call syssleep 0.5
   >I> Method "INIT" with scope "C" in package 
"G:\test\orx\trace\jlf_dl1.rex".
12 *-* self~m1
   >I> Method "M1" with scope "C" in package 
"G:\test\orx\trace\jlf_dl1.rex".
15 *-* expose s
16 *-* s = 1
17 *-* guard off
18 *-* say "before guard" -- here, no lock
   before guard
19 *-* guard on when s <> 1 -- but here, is locked while waiting...
 3 *-* c1~m2 -- wake-up m1
   >I> Method "M2" with scope "C" in package 
"G:\test\orx\trace\jlf_dl1.rex".

Now, if you are not Rick or Erich or any other deeply acquainted ooRexx programmer you have a 
problem: why is this deadlock occurring, or maybe formulated differently: where is the deadlock 
occurring and why?


This is a relative simple concurrency ooRexx program, and still one can see immediately the 
challenge. Of course, over time, if gaining more and more (and more and more time-consuming) 
experience one may become able to eventually find the problem. But using classic TRACE A is not as 
helpful and not as human-centric in such concurrency cases 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Jean Louis Faucher
Thanks for your feedback.

> Ugh, I don't find this to be helpful information at all.
It's useful, I explained already why, see the CSV screenshot.
We don't have a rexx debugger like the orexx workbench showing the call stack.
But we can have at least the top-level of the call stack, everywhere.

> I can determine that information just by looking at the thread numbers,
When an invocation is popped, you have no information in the trace to tell you 
in which method/routine you are back.
This is also true in mono thread.
You would need something opposite to >I>, like I> corresponding 
to this context.
And in the CSV, you have it immediately.

> the activation number has no real connection to any concept in the 
> interpreter. 

It's related to .context and .context~stackFrames[1]


This extended trace is what I needed 13 years ago to analyse several deadlocks.
All the infos were useful.
Each time, the debug process was the same:
- look at the last line (deadlocked), it’s for the thread Tn and the variable 
pool Vn.
- move up in the trace until I find  another thread Tm using this same variable 
pool Vn and having a lock.
- from here, I know the 2 competing methods.
- and the difficult part begins: find how to fix…


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?

Ugly? That is ugly:
afea2380 1092bb00  0   1 *-* 
.demo~new~exec(1)
afea2380 1092bb00  0 >E>   .DEMO => 
"The DEMO class"
afea2380 1092bb00  0 >M>   "NEW" => 
"a DEMO"
afea2380 1092bb00  0 >L>   "1"
afea2380 1092bb00  0 >A>   "1"
afea2380 10934d80 10934ff0 0 >I> Method 
"EXEC" with scope "DEMO" in package 
"/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
afea2380 10934d80 10934ff0 1*  8 *-* use arg id
afea2380 10934d80 10934ff0 1*>>>   "1"
afea2380 10934d80 10934ff0 1*>=>   ID <= "1"
That was the MT trace generated 13 years ago.
It was transformed in a “human readable” format with beautiful identifiers by a 
rexx script :-)
 


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


Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rick McGuire
On Sat, Feb 11, 2023 at 12:53 PM Rony G. Flatscher 
wrote:

> On 11.02.2023 18:16, Rick McGuire wrote:
>
> 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.
>
> Thank you for the feedback!
>
> A question ad 5): what about using M as a postfix (AM, RM, IM: on, A, R,
> I: off)?
>
I am opposed to any alphabetic marker at all, prefix or suffix. My
recommendation is to make the extra information available whenever it makes
sense (i.e., there's more than one active thread. The user shouldn't have
to adjust things because suddenly things are happening on separate threads.

Rick




> ad 1): indeed in the used example it looks redundant; maybe a different
> example would show both to be benefitial as there may be different
> activities on the same thread, but also a single activity on different
> threads. E.g. example_12_5.rex:
>

This sentence makes no sense to me at all. There will never be multiple
activities active on the same thread at the same time, and an a single
activity will never be active on different threads.

> /* Example of sending message to SELF */
> object1 = .example~new
> object2 = .example~new
> say object1~repeater(5, "Object 1 running")
> say object2~repeater(5, "Object 2 running")
> say "Main ended."
>
> ::class example
> ::method repeater
>use arg reps,msg
>reply "Entered repeater."
>say self~repeat(reps,msg)
>
> ::method repeat
>use arg reps,msg
>do reps
>   say msg
>end
>return "Repeated" msg"," reps "times."
>
> ::options trace a
>
> 
> R1   T1   A12 *-* object1 = .example~new
> R1   T1   A13 *-* object2 = .example~new
> R1   T1   A14 *-* say object1~repeater(5, "Object 1 
> running")
> R1   T1   A2V1>I> Method "REPEATER" with scope "EXAMPLE" 
> in package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".
> R1   T1   A2V1  1* 10 *-* use arg reps,msg
> R1   T1   A2V1  1* 11 *-* reply "Entered repeater."
> Entered repeater.
> R1   T1   A15 *-* say object2~repeater(5, "Object 2 
> running")*R1   T2   A2V1  1*>I> Method "REPEATER" with scope 
> "EXAMPLE" in package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".*
> R1   T1   A3V2>I> Method "REPEATER" with scope "EXAMPLE" 
> in package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".*R1   T2   A2
> V1  1* 12 *-* say self~repeat(reps,msg)*
> R1   T1   A3V2  1* 10 *-* use arg reps,msg*R1   T2   A4V1 
>  1 >I> Method "REPEAT" with scope "EXAMPLE" in package 
> "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".*
> R1   T1   A3V2  1* 11 *-* reply "Entered repeater."*R1   T2   A4  
>   V1  2* 15 *-* use arg reps,msg*Entered repeater.*R1   T2   A4V1 
>  2* 16 *-* do reps*R1   T1   A16 *-* say "Main 
> ended."
> Main ended.*R1   T3   A3V2  1*>I> Method "REPEATER" with 
> scope "EXAMPLE" in package 
> "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".**R1   T2   A4V1  
> 2* 17 *-*   say msg*Object 1 running*R1   T3   A3V2  1* 12 
> *-* say self~repeat(reps,msg)**R1   T2   A4V1  2* 18 *-* end**R1  
>  T3   A5V2  1 >I> Method "REPEAT" with scope "EXAMPLE" in 
> package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".**R1   T2   A4
> V1  2* 16 *-* do reps**R1   T3   A5V2  2* 15 *-* use arg 
> reps,msg**R1   T2   A4V1  2* 17 *-*   say msg*Object 1 running*R1 
>   T3   A5V2  2* 16 *-* do reps**R1   T2   A4V1  2* 18 
> *-* end**R1   T3   A5V2  2* 17 *-*   say msg*
> Object 2 running*R1   T2   A4V1  2* 16 *-* do reps**R1   T3   A5  
>   V2  2* 18 *-* end**R1   T2   A4V1  2* 17 *-*   say 
> msg*Object 1 running*R1   T3   A5V2 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rick McGuire
On Sat, Feb 11, 2023 at 2:12 PM Mike Cowlishaw  wrote:

> 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?
>

The problem here is trace information from different threads gets
interleaved, with no way to determine which line came from which thread.
Being able to distinguish them is useful information. Being able to
determine the guard information can be helpful for debugging purposes, but
I'm not sure adding this to the trace is the way to go. And the information
being presented is not particularly useful. I'm totally against the set of
information currently being proposed. I agree with you that is not focused
on the user. A single thread identifier would fix the interleaving problem
and clutter things up much less.

Rick


>
> 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
>> 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rick McGuire
Ugh, I don't find this to be helpful information at all. I can determine
that information just by looking at the thread numbers, the activation
number has no real connection to any concept in the interpreter.

Rick

On Sat, Feb 11, 2023 at 12:33 PM Jean Louis Faucher 
wrote:

> A quick feedback about point 1:
> The A column is in fact the activation identifier (RexxActivation).
> It’s used to know which method/routine is executing the current line.
> The name of this method/routine can be found by looking back in the trace
> the first >I> for the current T.
>
> In rexxref, “activation” is not used.
> I think the good term is “invocation”, as in "An activity contains a stack
> of invocations… An invocation is activated when an executable unit is
> invoked and removed (popped) when execution completes. "
>
>
> This is the displayed informations
> struct ConcurrencyInfos
> {
> uint32_t interpreter;
> uint32_t activity; —> display a counter related to the system
> tread identifier, not the activity identifier
> uint32_t activation;
> uint32_t variableDictionary;
> unsigned short reserveCount;
> char lock;
> };
>
> On 11 Feb 2023, at 18:16, Rick McGuire  wrote:
>
> 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 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Mike Cowlishaw
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 
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 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rony G. Flatscher

On 11.02.2023 18:16, Rick McGuire wrote:

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.


Thank you for the feedback!

A question ad 5): what about using M as a postfix (AM, RM, IM: on, A, R, I: 
off)?

ad 1): indeed in the used example it looks redundant; maybe a different example would show both to 
be benefitial as there may be different activities on the same thread, but also a single activity on 
different threads. E.g. example_12_5.rex:


   /* Example of sending message to SELF */
   object1 = .example~new
   object2 = .example~new
   say object1~repeater(5, "Object 1 running")
   say object2~repeater(5, "Object 2 running")
   say "Main ended."

   ::class example
   ::method repeater
   use arg reps,msg
   reply "Entered repeater."
   say self~repeat(reps,msg)

   ::method repeat
   use arg reps,msg
   do reps
  say msg
   end
   return "Repeated" msg"," reps "times."

   ::options trace a

   
   R1   T1   A12 *-* object1 = .example~new
   R1   T1   A13 *-* object2 = .example~new
   R1   T1   A14 *-* say object1~repeater(5, "Object 1 
running")
   R1   T1   A2V1>I> Method "REPEATER" with scope "EXAMPLE" in 
package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".
   R1   T1   A2V1  1* 10 *-* use arg reps,msg
   R1   T1   A2V1  1* 11 *-* reply "Entered repeater."
   Entered repeater.
   R1   T1   A15 *-* say object2~repeater(5, "Object 2 
running")
   /R1 T2 A2 V1 1* >I> Method "REPEATER" with scope "EXAMPLE" in package
   "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex"./
   R1   T1   A3V2>I> Method "REPEATER" with scope "EXAMPLE" in 
package "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".
   /R1 T2 A2 V1 1* 12 *-* say self~repeat(reps,msg)/
   R1   T1   A3V2  1* 10 *-* use arg reps,msg
   /R1 T2 A4 V1 1 >I> Method "REPEAT" with scope "EXAMPLE" in package
   "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex"./
   R1   T1   A3V2  1* 11 *-* reply "Entered repeater."
   /R1 T2 A4 V1 2* 15 *-* use arg reps,msg///Entered repeater.
   /R1 T2 A4 V1 2* 16 *-* do reps///R1   T1   A16 *-* say "Main 
ended."
   Main ended.
   *R1 T3 A3 V2 1* >I> Method "REPEATER" with scope "EXAMPLE" in package
   "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".*
   /R1 T2 A4 V1 2* 17 *-* say msg///Object 1 running
   *R1 T3 A3 V2 1* 12 *-* say self~repeat(reps,msg)*
   /R1 T2 A4 V1 2* 18 *-* end///*R1 T3 A5 V2 1 >I> Method "REPEAT" with scope 
"EXAMPLE" in package
   "G:\oorexx.tmp\concurrencyTrace\example_12_5.rex".*
   /R1 T2 A4 V1 2* 16 *-* do reps///*R1 T3 A5 V2 2* 15 *-* use arg reps,msg*
   /R1 T2 A4 V1 2* 17 *-* say msg///Object 1 running
   *R1 T3 A5 V2 2* 16 *-* do reps*
   /R1 T2 A4 V1 2* 18 *-* end///*R1 T3 A5 V2 2* 17 *-* say msg*
   Object 2 running
   /R1 T2 A4 V1 2* 16 *-* do reps///*R1 T3 A5 V2 2* 18 *-* end*
   /R1 T2 A4 V1 2* 17 *-* say msg///Object 1 running
   *R1 T3 A5 V2 2* 16 *-* do reps*
   /R1 T2 A4 V1 2* 18 *-* end///*R1 T3 A5 V2 2* 17 *-* say msg*
   Object 2 running
   /R1 T2 A4 V1 2* 16 *-* do reps///*R1 T3 A5 V2 2* 18 *-* end*
   /R1 T2 A4 V1 2* 17 *-* say msg///Object 1 running
   *R1 T3 A5 V2 2* 16 *-* do reps*
   /R1 T2 A4 V1 2* 18 *-* end///*R1 T3 A5 V2 2* 17 *-* say msg*
   Object 2 running
   /R1 T2 A4 V1 2* 16 *-* do reps///*R1 T3 A5 V2 2* 18 *-* end*
   /R1 T2 A4 V1 2* 17 *-* say msg///Object 1 running
   *R1 T3 A5 V2 2* 16 *-* do reps*
   /R1 T2 A4 V1 2* 18 *-* end///*R1 T3 A5 V2 2* 17 *-* say msg*
   Object 2 running
   /R1 T2 A4 V1 2* 16 *-* do reps///*R1 T3 A5 V2 2* 18 *-* end*
   /R1 T2 A4 V1 2* 19 *-* return "Repeated" msg"," reps "times."///Repeated 
Object 1 running, 5 times.
   *R1 T3 A5 V2 2* 16 *-* do repsR1 T3 A5 V2 2* 17 *-* say msg*
   Object 2 running
   *R1 T3 A5 V2 2* 18 *-* endR1 T3 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Jean Louis Faucher
In complement of the struct, this is how the infos are collected for each trace 
line:

void GetConcurrencyInfos(Activity *activity, RexxActivation *activation, 
ConcurrencyInfos )
{
InterpreterInstance *interpreter = (activity ? activity->getInstance() : 
NULL);
VariableDictionary *variableDictionary = (activation ? 
activation->getVariableDictionary() : NULL);

/* R */ infos.interpreter = interpreter ? interpreter->getIdntfr() : 0;
/* T */ infos.activity = activity ? activity->getIdntfr() : 0;
/* A */ infos.activation = activation ? activation->getIdntfr() : 0;
/* V */ infos.variableDictionary = variableDictionary ? 
variableDictionary->getIdntfr() : 0;
/* n */ infos.reserveCount = activation ? activation-> getReserveCount() : 
0;
/* * */ infos.lock = (activation && activation->isObjectScopeLocked()) ? 
'*' : ' ';
}


> On 11 Feb 2023, at 18:32, Jean Louis Faucher  wrote:
> 
> A quick feedback about point 1:
> The A column is in fact the activation identifier (RexxActivation).
> It’s used to know which method/routine is executing the current line.
> The name of this method/routine can be found by looking back in the trace the 
> first >I> for the current T.
> 
> In rexxref, “activation” is not used.
> I think the good term is “invocation”, as in "An activity contains a stack of 
> invocations… An invocation is activated when an executable unit is invoked 
> and removed (popped) when execution completes. "
> 
> 
> This is the displayed informations
> struct ConcurrencyInfos
> {
> uint32_t interpreter;
> uint32_t activity; —> display a counter related to the system 
> tread identifier, not the activity identifier
> uint32_t activation;
> uint32_t variableDictionary;
> unsigned short reserveCount;
> char lock;
> };
> 
>> On 11 Feb 2023, at 18:16, Rick McGuire > > wrote:
>> 
>> 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 > > 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 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Jean Louis Faucher
A quick feedback about point 1:
The A column is in fact the activation identifier (RexxActivation).
It’s used to know which method/routine is executing the current line.
The name of this method/routine can be found by looking back in the trace the 
first >I> for the current T.

In rexxref, “activation” is not used.
I think the good term is “invocation”, as in "An activity contains a stack of 
invocations… An invocation is activated when an executable unit is invoked and 
removed (popped) when execution completes. "


This is the displayed informations
struct ConcurrencyInfos
{
uint32_t interpreter;
uint32_t activity; —> display a counter related to the system tread 
identifier, not the activity identifier
uint32_t activation;
uint32_t variableDictionary;
unsigned short reserveCount;
char lock;
};

> On 11 Feb 2023, at 18:16, Rick McGuire  wrote:
> 
> 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  > 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
> 

Re: [Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rick McGuire
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 
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:
>
>

[Oorexx-devel] A draft for documenting MT tracing (Re: Planning to add multithreaded (concurrent) tracing (Re: RFC for feature request "794 Concurrency request"

2023-02-11 Thread Rony G. Flatscher
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   A12 *-* object1 = .example~new
R1   T1   A13 *-* object2 = .example~new
R1   T1   A14 *-* a = 
object1~start("REPEAT",3,"Object 1 running")
R1   T1   A15 *-* b = 
object2~start("REPEAT",3,"Object 2 running")
R1   T1   A16 *-* 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 *-*