Execution Monitoring¶
Unicon monitoring¶
Execution monitoring is a profiling aid for Unicon
programs.
Relying on multi threading, a monitoring control program loads other programs and receives (possibily filtering) events.
- TP
- Target Program
- EM
- Execution Monitor
In the Unicon source distribution, in unicon/tests/special
there is a
basic monitoring test. Monitoring is usually setup with a TP (target program)
and an EM (execution monitor). That sample has 1to10.icn
a simple
generator as the target program, and monitor.icn
the sample EM.
For the capture, 1to10.icn
is changed to 1to4.icn
, to decrease the
listing size.
#
# program counts to 4 for use by monitoring test
#
procedure main()
every write("\n" || (1 to 4))
end
#
# if you can't do this much monitoring, the monitoring facilities do not work
#
link evinit
procedure main()
if not (&features == "dynamic loading") then runerr(121)
if not (&features == "event monitoring") then runerr(121)
EvInit("1to4")
while EvGet() do {
write(ord(&eventcode), ": ", image(&eventvalue))
}
end
# Make the monitor sample
.RECIPEPREFIX = >
monitor: monitor.icn 1to4
> unicon monitor
> ./monitor
1to4: 1to4.icn
> unicon 1to4
prompt$ make monitor
make[1]: Entering directory '/home/btiffin/wip/writing/unicon/examples'
make[1]: 'monitor' is up to date.
make[1]: Leaving directory '/home/btiffin/wip/writing/unicon/examples'
Hmm, codes. What all the monitoring event numbers mean are held in the
IPL, in the mprocs, mprogs, mincl directories. mprocs/evnames.icn
is a good clue, but they are indexed by enumeration names, which is in
mincl/evdefs.icn
(which is mostly octal character code). Execution
monitoring with Unicon is very much a tool chain that requires computer
assistance to use effectively at the capture and dump level. Higher level
programs that provide visualization is a much more human friendly interface to
execution monitoring.
But just for instance, when the first column is 80:
(octal 120), that
matches an E_Fret
event code. Makes sense as the second column for those
events are the 1, 2, 3, 4 values returned from the 1to4
program.
Let’s change the EM to be a little more friendly as a sample.
#
# if you can't do this much monitoring, the monitoring facilities do not work
#
link evinit, evnames
procedure main()
if not (&features == "dynamic loading") then runerr(121)
if not (&features == "event monitoring") then runerr(121)
EvInit("1to4")
while e := EvGet() do {
write(right(ord(&eventcode), 3), ": ", right(image(&eventvalue), 16),
": ", evnames(e))
}
end
prompt$ make monitor-names
make[1]: Entering directory '/home/btiffin/wip/writing/unicon/examples'
make[1]: 'monitor-names' is up to date.
make[1]: Leaving directory '/home/btiffin/wip/writing/unicon/examples'
Ahh, that’s a little easier on the eyes and brain. And a sweet little view of what’s going on. I wonder how that maps to some ucode?
make[1]: Entering directory '/home/btiffin/wip/writing/unicon/examples'
make[1]: 'monitor-names.u' is up to date.
make[1]: Leaving directory '/home/btiffin/wip/writing/unicon/examples'
version U12.1.00
uid monitor-names.u1-1476161329-0
impl local
link evinit.u
link evnames.u
global 1
0,000005,main,0
^L
proc main
local 0,000000,runerr
local 1,000000,EvInit
local 2,000000,e
local 3,000000,EvGet
local 4,000000,write
local 5,000000,right
local 6,000000,ord
local 7,000000,image
local 8,000000,evnames
con 0,010000,15,144,171,156,141,155,151,143,040,154,157,141,144,151,156,147
con 1,002000,3,121
con 2,010000,16,145,166,145,156,164,040,155,157,156,151,164,157,162,151,156,147
con 3,010000,4,061,164,157,064
con 4,002000,1,3
con 5,010000,2,072,040
con 6,002000,2,16
declend
filen monitor-names.icn
line 13
colm 12
synt any
mark L1
line 14
colm 3
synt if
mark0
mark L2
pnull
line 14
colm 11
synt any
keywd features
str 0
line 14
colm 21
synt any
lexeq
unmark
efail
lab L2
pnull
unmark
var 0
int 1
line 14
colm 54
synt any
invoke 1
line 14
colm 3
synt endif
unmark
lab L1
mark L3
line 15
colm 3
synt if
mark0
mark L4
pnull
line 15
colm 11
synt any
keywd features
str 2
line 15
colm 21
synt any
lexeq
unmark
efail
lab L4
pnull
unmark
var 0
int 1
line 15
colm 55
synt any
invoke 1
line 15
colm 3
synt endif
unmark
lab L3
mark L5
var 1
str 3
line 16
colm 9
synt any
invoke 1
unmark
lab L5
mark L6
lab L7
line 17
colm 3
synt while
mark0
pnull
var 2
var 3
line 17
colm 19
synt any
invoke 0
line 17
colm 11
synt any
asgn
unmark
mark L7
var 4
var 5
var 6
line 18
colm 23
synt any
keywd eventcode
line 18
colm 22
synt any
invoke 1
int 4
line 18
colm 18
synt any
invoke 2
str 5
var 5
var 7
line 18
colm 58
synt any
keywd eventvalue
line 18
colm 57
synt any
invoke 1
int 6
line 18
colm 51
synt any
invoke 2
str 5
var 8
var 2
line 19
colm 26
synt any
invoke 1
line 18
colm 12
synt any
invoke 5
lab L8
unmark
goto L7
lab L9
line 17
colm 3
synt endwhile
unmark
lab L6
pnull
line 21
colm 1
synt any
pfail
end
And, no, not really any quick grok matching .u to the monitor; that listing
means relatively little, at this point in studying Unicon, in relation to the
execution events. .u with the VM, and this particular monitor, are at
different layers, and there is no one to one mapping. That’s ok, lesson
learned. Reading .u is pretty nice though, the line
and colm
mnemonics make it pretty easy to mentally map source to VM and let the brain
know where things are in the code for each operation.
Visualization¶
And Event Monitoring starts to shine. Take your eyes off the code and look at some pictures. Let the running programming paint its own picture.
Todo
add some plots
Index | Previous: Debugging | Next: Performance