Re: [Oorexx-devel] An ooRexx implementation of the TraceObject class

2024-01-23 Thread Rony G. Flatscher

On 22.01.2024 22:46, Rick McGuire wrote:
The part about the variable dictionary doesn't make any sense at all. The context where the line 
is being traced doesn't really provide any useful information. The guard start is a combination of 
the guard state of all the stack frames for a given activity. Since methods are guarded by 
default, for any call stack, there are going to be many frames in a guarded state on 
potentially many objects and scopes, including nesting. This does NOT belong as part of tracing. 
It seriously clutters stuff up and doesn't really provide information that is needed on a 
statement-by-statement basis.


The scenario where this information becomes helpful, if not important is in debugging complex, large 
multithreaded applications. The variable dictionary number will allow for filtering all traces of a 
specific object in that scope. Also, for scenarios where many instances of the same class exist and 
get dispatched (maybe partially depending on context) on different threads, then one can study (by 
writing a program for analyzing and filtering the produced trace log ex post) the behaviour (the 
sequence of executing methods where context may influence that sequence) of specific instances of a 
specific scope, attempting to find out whether irregularities exist and if so analyze how they 
became to be going up the mtPrefix'ed trace log.


This information may not be so important for rather simple multithreaded traces, but in complex 
situations this should serve as a big time saver for humans and for the programs they write for 
analyzing huge mtPrefix trace logs ex post.


---

One idea that came up while thinking about your comment (not wanting to clutter which is important) 
would be the following: define the class attribute mtPrefix to allow for the following values 
instead of .true/.false as suggested so far (only the option's first letter mandatory):


 * "None" ... no mtPrefix gets generated (default)

 * "Full" ... the full mtPrefix will be generated by makeString, i.e. "[R1   T1   I5 
  G V1   L2   *] "

 * "Standard" ... an mtPrefix will be generated by makeString, that leaves out 
the Rexx interpreter
   instance and the variable dictionary number, i.e. "[T1   I5   G L2   *] "

The default value would be "None", no mtPrefix gets created in the trace message. Otherwise the 
programmer can chose whether he wishes a full or a standard mtPrefix to be created by LogObject. 
This might cover most use cases.


In addition the programmer will be free to use the LogObject information freely to create whatever 
he thinks will be helpful for debugging the multithreaded program in hand. Therefore if any 
information in mtPrefix is seen as clutter or uninteresting for a programmer he can easily change 
that for his mtPrefix trace logs. The same if he wishes to add additional information, e.g. adding 
timestamps (maybe for profiling) to mtPrefix etc.


---

It would be most helpful if it became possible to indicate in the last character a blocking/waiting 
state, such that '*' (indicating method is currently guarded and has the object lock) and ' ' (then 
only if the method is currently unguarded) indicate executing, 'B' (or 'W') indicate 
blocking/waiting (indicating a method currently guarded and waiting on the object's lock). This 
would ease analyzing the trace log considerably, if interested to find the blocked statements in a 
multithreaded program in case of deadlocks.


---rony




On Mon, Jan 22, 2024 at 11:32 AM Rony G. Flatscher  
wrote:

Here an ooRexx implementation of the proposed TraceObject class in today's 
"Proposal for
multithreaded trace prefix" class:

/* 
= */ 
::class
"TraceObject" subclass StringTable public /*

- */ 
::attribute
mtPrefix class -- if .true causes the mtPrefix to be created /*

- */ 
::method
MAKESTRING if self~class~mtPrefix<>.true then -- do not show 
multithreaded prefix return
self["TRACELINE"] -- return standard trace line mb = .MutableBuffer~new 
-- for performance
reasons mb~append("[") mb~append("R", adjLeft(self["INSTANCE"] ,3), " 
") -- R_exx
interpreter instance mb~append("T", adjLeft(self["THREAD"] ,3), " ") -- 
T_hread/activity
mb~append("I", adjLeft(self["INVOCATION"],3) ) -- I_nvocation/activation
vd=self["VARIABLEDICTIONARY"] if vd<>0 then -- an object's variable 
dictionary in hand, we
are in a method do mb~append(" ") mb~append(self["ISGUARDED"]~?("G","U") , " 
") --
G_uarded or U_unguarded mb~append("V", adjLeft(vd ,3), " ") -- 
V_ariable dictionary pool
mb~append("L", adjLeft(self["LOCKCOUNT"],3), " ") -- L ... lock reserve 
count
mb~append(self["ISLOCKED"]~?("*"," ")) -- asterisk to 

Re: [Oorexx-devel] An ooRexx implementation of the TraceObject class

2024-01-22 Thread Rick McGuire
The part about the variable dictionary doesn't make any sense at all. The
context where the line is being traced doesn't really provide any useful
information. The guard start is a combination of the guard state of all the
stack frames for a given activity. Since methods are guarded by default,
for any call stack, there are going to be many frames in a guarded state on
potentially many objects and scopes, including nesting. This does NOT
belong as part of tracing. It seriously clutters stuff up and doesn't
really provide information that is needed on a statement-by-statement
basis.

Rick

On Mon, Jan 22, 2024 at 11:32 AM Rony G. Flatscher 
wrote:

> Here an ooRexx implementation of the proposed TraceObject class in today's
> "Proposal for multithreaded trace prefix" class:
>
> /* = 
> */::class "TraceObject" subclass StringTable public
> /* - 
> */::attribute mtPrefix class -- if .true causes the mtPrefix to 
> be created/* 
> - 
> */::method MAKESTRING
>   if self~class~mtPrefix<>.true then   -- do not show multithreaded prefix
>  return self["TRACELINE"]  -- return standard trace line  mb = 
> .MutableBuffer~new  -- for performance reasons  mb~append("[")
>   mb~append("R", adjLeft(self["INSTANCE"]  ,3), " ")  -- R_exx interpreter 
> instance  mb~append("T", adjLeft(self["THREAD"],3), " ")  -- 
> T_hread/activity  mb~append("I", adjLeft(self["INVOCATION"],3) )  -- 
> I_nvocation/activation  vd=self["VARIABLEDICTIONARY"]
>   if vd<>0 then  -- an object's variable dictionary in hand, we are in a 
> method  do
>  mb~append(" ")
>  mb~append(self["ISGUARDED"]~?("G","U") , " ")  -- G_uarded or 
> U_unguarded mb~append("V", adjLeft(vd   ,3), " ")  -- 
> V_ariable dictionary pool mb~append("L", adjLeft(self["LOCKCOUNT"],3), " 
> ")  -- L ... lock reserve count mb~append(self["ISLOCKED"]~?("*"," "))  
> -- asterisk to indicate holding object lock (can execute)  end
>   mb~append("] ", self["TRACELINE"])
>   return mb~string   -- return trace line with mtPrefixadjLeft: procedure   
> -- left adjust, but make sure we show all chars  use arg value, width
>   if value~length>=width then -- no left adjustment return value
>   return value~left(width)-- left adjust with given width
>
> ---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