At <https://wi.wu.ac.at/rgf/rexx/tmp/20240128_mt/> you will find a portable ooRexx debug version for
Windows that includes a test version of the suggested multithreaded trace, implemented in a way that
adheres to Rick's idea, such that a Rexx programmer can freely format traces as he or she wishes.
The above web site includes Rexx test scripts that are only meant to demonstrate and test the
current implemtation.
The readme.txt file includes suggested drafts and is copied to this message at
the end.
Please post any feedback, findings, bugs here.
---rony
readme.txt:
Multithreaded tracing, TraceObject class
----------------------------------------
This readme.txt file accompanies a portable Windows version of ooRexx 5.1beta
that implements multithreaded trace prefixes and makes it possible to create
one own's trace line renderings as well as to use the infrastructure for
profiling (analyzing) the execution of Rexx programs.
- unzip the ooRexx portable version, go into the directory and run
"setupoorexx.cmd" which creates batch files, e.g.:
- setenv2rxenv.cmd ... run to change PATH to first point to the
portable version of ooRexx; run Rexx programs
with "rexx myProgram.rex" such that the
operating system looks and finds for rexx.exe
- there are three test Rexx programs (you can use your own Rexx programs):
- test01.rex ... a simple test Rexx program
- test02.rex ... a multithreaded test Rexx program to test guarded and
unguarded method routines
- test03.rex ... this is test01.rex with an intenional syntax error at the
end
- there are three Rexx programs that exploit the new infrastructure:
- p1_traceRunner.rex ... executes the Rexx program (name supplied via the
command line argument) four times, once with
.TraceObject~option set to 'N' (normal),
'S' (standard), 'F' (full), 'P' (profiling mode);
each run will have the generated TraceObjects
collected in an array that could be used to
analyze
the runs afterwards
- p2_traceInterceptor.rex ... like p1_traceRunner.rex in addition:
demonstrates how to intercept each TraceObject
- p3_traceEditingPrefix.rex ... like p2_traceInterceptor.rex in addition:
demonstrates how to change the trace line
information
To use the infrastructure:
- unzip the portable ooRexx version, run setupoorexx.cmd, then the
generated
script setenv2rxenv.cmd and remain in that session to run the above
programs (PATH got set in it), e.g.
rexx p1_traceRunner.rex test01.rex (or any other Rexx
program)
rexx p2_traceInterceptor.rex test02.rex (or any other Rexx
program)
rexx p3_traceEditingPrefix.rex test03.rex (or any other Rexx
program)
Please note: the test programs are artificial and got created to test and
demonstrate the infrastructure.
---
What follows are drafts for rexxref.pdf.
---------------------------------------------------------------------
Starting out with the current documentation the nomenclatura is kept the
same,
possibly with additional information meant for the debugging section in
rexxref.pdf.
--- draft (rexxref.pdf) - begin ---
15.4 Debugging Multithreaded Programs
ooRexx allows for executing different parts of ooRexx programs on
multiple
threads of execution using different Rexx interpreter within a single
operating system process. This makes it difficult and at times even
impossible to debug such multithreaded programs without any additional
information about the specific execution context. Relevant information
for debugging multithreaded programs may be: the Rexx interpreter
instance
that executes an invocation ("activation") running on which operating
system thread and whether a lock is held for exclusive access of an
object's attribute ("object variable") pool.
To ease debugging of multithreaded programs the execution context can be
indicated with a "multithreaded trace prefix" ("OPTION") string in the
following form "[R1 T1 I5 G A1 L2 *]", where
- "R1": "R" stands for Rexx interpreter instance and the number (a
counter) indicates which of the instances executes the current
invocation (activation).
- "T1": "T" stands for (operating system) thread and the number (a
counter) indicates on which of the currently existing threads the
activity gets executed
- "I5": "I" stands for invocation (activation) and the number (a
counter)
indicates which invocation gets executed on that thread (activity)
Information in the OPTION if currently tracing statements of method
routines (otherwise the remainder of the prefix will be blank):
- "G" or "U": this character indicates whether the method routine is
defined to be guarded or unguarded.
- "A1" : "A" stands for "attribute pool" ("object variable
dictionary")
and the number (a counter) indicates which object variable
dictionary
gets used in this invocation of the method routine. Each object
will
have its own attribute pool which can be directly accessed by method
routines of the same scope, i.e. method routines that are defined
in
the same class from which the object got created. Therefore the A
indicator will refer to the same object if the number is the same.
- "L2": "L" stands for object lock count and the number (a counter)
indicates how many object lock reservations have taken place at that
point in time. Whenever another method routine of the same scope
gets
invoked the object lock count increases by one, upon return the
object
lock count decreases by one.
- "*" or " ": the asterisk indicates that the activity holds the
object
lock. Guarded methods are blocked, if they do not hold the object
lock.
Methods in the unguarded state will never block.
Notes:
- the GUARD keyword instruction can be used within a method routine to
change the state from guarded (synchronize on the object lock) to
unguarded (ignore the object lock) using unconditionally the keyword
statement GUARD OFF and vice versa (using unconditionally the
keyword
statement GUARD ON),
- the keyword instructions "GUARD ON someAttribute=someValue" and
"GUARD
OFF someAttribute=someValue" allow changing the state of the method
routine to guarded or to unguarded depending on the value of an
exposed
attribute "someAttribute" which needs to get changed in another
concurrently running method routine of the same (class) scope. Such
attributes are known to be used as "control variables" to
synchronize
activities on different threads,
- if you wish to directly change the value of any exposed attribute
then
make sure that the changes take place in the guarded state to
inhibit
concurrent updates from other threads to inhibit inconsistent
states,
- the object variable dictionary number represents a specific object,
- methods in the guarded state that do not possess the trailing
asterisk
are blocked, they are waiting for the object lock,
- methods in the unguarded state get never blocked,
- the standard layout of the OPTION is intentionally designed to make
parsing easy such that analyzing the trace 3output of complex
multithreaded ooRexx programs becomes easy.
Starting with ooRexx 5.1 each traced line will be represented with an
instance of the class TraceObject. Its class attribute OPTION (see the
documentation of the class TraceObject) is set to N (normal) by default.
If one needs additional, multithreaded trace information prefixed
then changing the class attribute OPTION to S (standard) or
to F (full, for complex multithreaded programs) prepends it to each
traced line. Each TraceObject will be sent as argument to the LINEOUT
message to the .traceOutput monitor object.
This makes it possible to intercept these trace LINEOUT messages with
the TraceObject argument by adding one own's Rexx object as a
destination
object which implements the LINEOUT method (if doing so, one should
also implement the UNKNOWN method to forward all unknown messages).
--- draft (rexxref.pdf) - end ---
--- draft for class TraceObject (rexxref.pdf) - begin ---
5.3.x TraceObject Class
A TraceObject is a subclass of StringTable and therefore is a MapCollection
using unique character string indexes. The items of a StringTable can be any
valid Rexx object. See also Directory Class, a MapCollection similar to
StringTable, but with additional methods setMethod and unsetMethod.
The trace infrastructure of ooRexx will create an instance for each trace
line
and store the following information with the following indexes:
Index Item
"ATTRIBUTEPOOL" a number, makeString prepends it with the letter A
"HASOBJECTLOCK" .true/.false, makeString uses an asterisk, if .true,
a blank character else
"INTERPRETER" a number, makeString prepends it with the letter R
"INVOCATION" a number, makeString prepends it with the letter I
"ISGUARDED" .true/.false, makeString uses the letter G, if
.true,
the letter U else
"OBJECTLOCKCOUNT" a number, makeString prepends it with the letter L
"OPTION" the option at creation time, e.g. N or S
"THREAD" a number, makeString prepends it with the letter T
"TIMESTAMP" the creation .DateTime
"TRACELINE" the trace line string
The section "15.4 Debugging Multithreaded Programs" gives more information
about debugging multithreaded programs.
r.3.x.1. collector (Class Attribute)
This attribute controls whether created TraceObjects get collected or not.
If its value is set to .nil (default) then the created TraceObjects are not
collected. This attribute can be set to anything else, if the object can
understand the APPEND message, which is the case for all OrderedCollections
like Array.
r.3.x.2. option (Class Attribute)
This attribute controls whether a traced line gets displayed and how
makeString renders the traced line. The following values are defined for this
attribute:
Letter
N "normal", the trace line gets displayed without any
multithreaded prefix information
S "standard", the trace line gets prefixed with a
bracketed string that indicates the thread and the
invocation number, e.g. "[T1 I2 ]" or if a method
routine gets traced in addition whether it was defined
guarded or ungaurded, the object lock count and whether
the object lock is reserved (indicated by an asterisk),
e.g. "[T1 I9 G L1 *] "
F "full", the trace line with a bracketed string that adds
the Rexx instance and the activity pool number, e.g.
"[R1 T1 I15 ]" or if a method routine gets traced adds
the attribute pool number, e.g. "R1 T4 I19 G A3 L1
*]".
P "profiling", no trace line will be shown, yet, each created
TraceObject will get appended to the class attribute
COLLECTOR
if not .nil. This allows analyzing the execution of traced
Rexx programs for many purposes.
r.3.x.3. compareTo
Implements the default sort order using the value of the TIMESTAMP entry.
r.3.x.4. init
The constructor adds the TIMESTAMP and OPTION entries for later analysis.
r.3.x.5. makeString
This method formats the traceline according to the current setting of the
class attribute OPTION:
N or P normal trace line
S standard prefix prepended to trace line
F full prefix prepended to trace line
For more information see class attribute OPTION and section "15.4 Debugging
Multithreaded Programs".
--- draft for class TraceObject (rexxref.pdf) - end ---
If there are questions, comments please use the ooRexx developer list on
sourceforge (https://sourceforge.net/p/oorexx/mailman/oorexx-devel/).
2024-01-28, rgf
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel