From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  2-NOV-1989 19:58
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Spinlock monitoring program, part 1 of 3

Received: From UCBVAX.BERKELEY.EDU by GIZMO.SRI.COM with TCP; Wed,  1 NOV 89 18:03:35 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.39)
	id AA23431; Wed, 1 Nov 89 17:47:10 -0800
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 1 Nov 89 17:02:42 GMT
From: amdahl!rtech!jim@ames.arc.nasa.gov  (Jim Gessling)
Organization: Relational Technology Inc. Alameda, CA 94501
Subject: Spinlock monitoring program, part 1 of 3
Message-Id: <3954@rtech.rtech.com>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user JIM
$! on  1-NOV-1989 08:46:55.29.
$!
$! ATTENTION: To keep each article below 31 blocks (15872 bytes), this
$!            program has been transmitted in 3 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 5 files:
$!        BUILD.COM
$!        SPINLOCK.CLD
$!        SPINLOCK.DOC
$!        SPINLOCK.MAR
$!        SPINLOCK_ERR.MSG
$!
$!============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$VERSION_OK:
$ GOTO START
$!
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors 
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN 
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail 
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP
; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK
( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 )
; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip 
<> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF
; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT )
; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip 
:= MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip 
<> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET )
; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) 
); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1
; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line 
<> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors 
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL
( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH
( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 
); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP
; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION
( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO
( "The following !UL errors were detected while unpacking !AS", i_errors
, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" )
; ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." )
$ RETURN
$!
$START: 
$ FILE_IS = "BUILD.COM"
$ CHECKSUM_IS = 655322511
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$! build file for SPINLOCK`032
X$!
X$message spinlock_err
X$MACRO/NODEBUG/NOLIST  SPINLOCK+sys$library:lib/library `032
X$LINK/NODEBUG SPINLOCK,spinlock_err,sys$input/options
Xsys$system:sys.stb/selective
X$exit
$ GOSUB UNPACK_FILE

$ FILE_IS = "SPINLOCK.CLD"
$ CHECKSUM_IS = 1464359968
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X!
X! command definition file for spinlocks program
X!`032
X! jjg  December 16, 1988
X
Xdefine verb spinlocks
X`009image sys_tools:spinlock
X`009qualifier interval, default, value(default=5,type=$number)
X`009qualifier range, default, value(default=100,type=$number)
X`009parameter p1, label=class, default,`032
X`009`009value(default=spins, type=spin_class)
Xdefine type spin_class`032
X`009keyword spins              ! 0 - spins/second
X`009keyword percent_busy       ! 1 - busys/acquisitions (%)
X`009keyword wait_spins         ! 2 - spins/acquisition
X`009keyword busy_spins         ! 3 - spins/busy
X`009keyword acquisitions       ! 4 - acquistions/sec
$ GOSUB UNPACK_FILE

$ FILE_IS = "SPINLOCK.DOC"
$ CHECKSUM_IS = 2016257795
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X    `032
X                    SPINLOCK monitoring program
X
XWith the advent of Symetrical Multiprocessing on VMS, has come spinlocks.`032
VThese are bits that are used by parts of the OS to protect data structures fr
Xom
Xconcurrent access by multiple CPU's.  For example, the scheduler needs to
Xprotect the priority queues from access by another CPU while one CPU is
Xworking on the data.
X
VVMS does not provide for monitoring the use of these locks except in one plac
Xe.`032
XThe "$monitor modes" command provides a bar chart including a bar for MP
Vsynchronization.  This is too gross a measure considering the fact that on so
Xme
Xsystems we have observed upwards of 50% being allocated to this bar.
X
XI have written this monitoring utility to provide a finer look at where the
Vspinlocks are getting used.  It provides a bar graph display of five differen
Xt
Vstatistics.  Two qualifiers allow for tailoring the display and a parameter`0
X32
Xis used to select the statistic displayed.
X
XVMS only collects spinlock performance data if the sysgen parameter
XMULTIPROCESSING is set to 1 or 2.  Normally this is set to 3, meaning don't
Xcollect the information.  This program aborts if the data is not being
Xcollected.`032
X
XWARNING:  This program contains kernel mode code that accesses system data
Vstructures.  While it has been tested on VMS 5.0, I cannot take responsibilit
Xy
Xfor any problems caused by running this program.
X
X
XQualifiers:
X
V/interval=n   is used to select the time interval (in seconds) between updati
Xng
V              the display.  The values displayed are always divided by the`03
X2
X              interval to give units/second.  A longer interval will give`032
V              a sample over a longer interval and will be more representative
X.
X              The default is 5 seconds.
X
V/range=n      is used to set the maximum excursion of the bars.  Bars longer`
X032
V              than this value are truncated.  Pick a value based on the numbe
Xrs
X              observed. `032
X              The default is 100 units.  `032
X
XParameter:
X
Xspins         displays the raw spins/second for the top 8 locks.  This is the
X              first display to examine to determine which locks should be
X              examined further. (this is the default)
X
Xpercent_busy  displays the ratio of busys to acquisitions.  This is a measure
X              of how often a lock is busy when requested.  Always displayed
X              as a percentage no matter what /range is set at.
X
Xwait_spins    displays the ratio of spins/acquisition.  This is a measure`032
X              of average number of spins while waiting for the acquisition
X              of a lock.
X
Xbusy_spins    displays the ration of spins/busy wait.  This is a measure of
X              of number of spins that occurred while waiting for a lock`032
X              that was found to be busy.  It is an indication of how
X              much work the other processor(s) was doing while holding
X              the lock.
X
Xacquisitions  displays the raw acquisitions/second for the top 8 locks. `032
X
X
XOperational:
X
XThe command definition file is spinlock.cld.  This must be added to command
Xtables before running.  The image file (spinlock.exe) is assumed to be
Xin the directory sys_tools.  Set this logical name to locate the image.
XOnly the first letter of the parameter is required.
X
XNotes:
X
XWritten in VAX macro as an exercise in system coding.  Uses three kernel mode
Xroutines to get spinlock data so CMKRNL privilege is required to run.  See
Xappendix A of the Device Support Manual for details on the spinlock data
Vstructure.  All devices that fork at IPL 8 use the same IOLOCK8 spinlock.  Us
Xe
Vthe anal/system command to see which locks are contributing to the use of thi
Xs
Xlock.
X
X!
X! command definition file for spinlocks program
X!`032
X! jjg  December 16, 1988
X
Xdefine verb spinlocks
X`009image sys_tools:spinlock
X`009qualifier interval, default, value(default=5,type=$number)
X`009qualifier range, default, value(default=100,type=$number)
X`009parameter p1, label=class, default,`032
X`009`009value(default=spins, type=spin_class)
Xdefine type spin_class`032
X`009keyword spins              ! 0 - spins/second
X`009keyword percent_busy       ! 1 - busys/acquisitions (%)
X`009keyword wait_spins         ! 2 - spins/acquisition
X`009keyword busy_spins         ! 3 - spins/busy
X`009keyword acquisitions       ! 4 - acquistions/sec
$ GOSUB UNPACK_FILE

$ FILE_IS = "SPINLOCK.MAR"
$ CHECKSUM_IS = 121571784
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X`009.TITLE`009spinlock complete monitor for spinlocks
X`009.IDENT`009/v2.0/
X
X; the new completely rewritten, totally neat spinlock monitor, handles
X; four classes of display:
X;`0091) spins, bar graph of spins/second of top spinners
X;`0092) overhead, bar graph of acqusitions per busy                      `032
X;`0093) acquisition, bar graph of spins per acquisition
X;`0094) busy, bar graph of spins per busy
X;
X; data is all held in a data structure that looks like this:
X;
X;         `124-------------------------------`124
X;         `124     copy of spinlock          `124  0
X;         `124     structure as found in     `124
X;         `124     system space fills this   `124
X;         `124-------------------------------`124
X;         `124     address of spinlock       `124 80
X;         `124-------------------------------`124
X;         `124     lock name (10 bytes)      `124 84
X;         `124-------------------------------`124
X;         `124                               `124 88
X;         `124-------------------------------`124
X;         `124  type `124  1   `124                `124 92
X;         `124-------------------------------`124
X;         `124     spin difference           `124 96
X;         `124-------------------------------`124
X;         `124     acquisition count diff    `124 100
X;         `124-------------------------------`124
X;         `124     busy waits difference     `124 104
X;         `124-------------------------------`124
X;         `124    BUSY diff/ ACQ  diff       `124 108
X;         `124-------------------------------`124
X;         `124     spin diff/ acq diff       `124 112
X;         `124-------------------------------`124
X;         `124     spin diff/ busy diff      `124 116
X;         `124-------------------------------`124
X;
X; an array of these is used, the same offsets are used into
X; this structure as the system locks except for the fields, that
X; I have added so define those:
XSPL$L_ADDRESS   = 80
XSPL$L_LOCK_NAME = 84
XSPL$B_ASCII_TYPE = 94
XSPL$L_SPIN_DIFF = 96
XSPL$L_ACQ_DIFF  = 100
XSPL$L_BUSY_DIFF = 104
XSPL$L_BUSY_PER_ACQ = 108
XSPL$L_SPIN_PER_ACQ = 112
XSPL$L_SPIN_PER_BUSY = 116
XLBLOCK_SIZE = 120
X;
X; system supplied macros
X$SPLDEF
X$SPLCODDEF
X$SSDEF
X$CLIDEF
X$DDBDEF
X$UCBDEF
X$SYIDEF
X;
X; structures for "qio"ing to terminal
XTT_DESC:`009.ASCID`009/TT:/
X;
X; static data
XNUM_LOCKS:`009.LONG`009`009`009; number of lock blocks
XFIRST_BLOCK:`009.LONG`009`009`009; address of first lock block
XWAIT_TIME:`009.FLOAT`009`009`009; interval between samples
XDISPLAY_TYPE:`009.BYTE`009`009`009; type of display
X`009`009`009`009`009; 0 - spins/sec
X`009`009`009`009`009; 1 - percent busy
X`009`009`009`009`009; 2 - wait_spins
X`009`009`009`009`009; 3 - busy_spins
X`009`009`009`009`009; 4 - acquisitions/sec
XRANGE:`009`009.LONG`009`009`009; range for bars
XQUALIFIER:`009.ASCID`009/INTERVAL/`009; command line parsing
XQUALIFIER2:`009.ASCID`009/RANGE/
XPARAMETER:`009.ASCID`009/CLASS/
XRETURN_DESC:`009.ASCID`009/            /`009
X
XSPNAMES:`009.ASCII`009/EMB       / `009; lock rank 0`009
X                .ASCII  /MCHECK    /`009; 1
X`009`009.ASCII  /MEGA      /`009; 2
X`009`009.ASCII  /HWCLK     /
X`009`009.ASCII  /VIRTCONS  /
X`009`009.ASCII`009/INVALIDATE/
X`009`009.ASCII  /PERFMON   /
X`009`009.ASCII  /POOL      /
X`009`009.ASCII  /MAILBOX   /
X`009`009.ASCII  /PR_LK11   /
X`009`009.ASCII  /IOLOCK11  /
X`009`009.ASCII  /PR_LK10   /
X`009`009.ASCII  /IOLOCK10  /
X`009`009.ASCII  /PR_LK9    /
X`009`009.ASCII  /IOLOCK9   /
X`009`009.ASCII  /SCHED     /
X`009`009.ASCII  /MMG       /
X`009`009.ASCII  /JIB       /
X`009`009.ASCII  /TIMER     /
X`009`009.ASCII  /PR_LK8    /
X`009`009.ASCII  /IOLOCK8   /
X`009`009.ASCII  /FILSYS    /
X`009`009.ASCII  /QUEUEAST  /
X`009`009.ASCII  /ASTDEL    /`009; lock rank 23
X;
X; sort data structures
XSORT_MASK:`009.LONG`009SOR$M_STABLE`009; sort options
XLRL:`009`009.WORD`009LBLOCK_SIZE`009; sort block size
XKEY_BUFFER:`009.WORD`0091             `009; sort key descriptor
X`009`009.WORD`009DSC$K_DTYPE_LU
X`009`009.WORD`0091
X`009`009.WORD`009
X`009`009.WORD`0094
VBLOCK_DESC:`009.WORD`009LBLOCK_SIZE `009; descriptor for passing block to sor
Xt
X`009`009.BYTE`009DSC$K_DTYPE_T
X`009`009.BYTE`009DSC$K_CLASS_S
X`009`009.LONG
X;
X; screen painting symbols
XESC = 27
XQIO_PARAM:`009.LONG   12
X`009`009.LONG
XTT_CHAN:`009.LONG`009
X`009`009.LONG`009IO$_WRITEVBLK!IO$M_NOFORMAT
X`009`009.BLKL`0099
X
XTITLE:`009`009.ASCID`009<ESC>/[2J/ -
X                        <ESC>#[2;29HJim G's Monitor Utility#
X
XONNODE:`009`009.ASCID`009<ESC>/[4;34Hon node /
X
XT0:`009`009.ADDRESS`009DISPLAY0
X`009`009.ADDRESS`009DISPLAY1
X`009`009.ADDRESS`009DISPLAY2
X`009`009.ADDRESS`009DISPLAY3    `032
X`009`009.ADDRESS`009DISPLAY4    `032
X
XDISPLAY0:`009.ASCID  <ESC>/[3;31HTOP SPINLOCK USAGE/`032
XDISPLAY1:`009.ASCID`009<ESC>#[3;31HBUSYS/ACQUISITION %#`032
XDISPLAY2:`009.ASCID`009<ESC>#[3;31HSPINS/ACQUISITION #`032
XDISPLAY3:`009.ASCID`009<ESC>#[3;31H    SPINS/BUSY    #
XDISPLAY4:`009.ASCID`009<ESC>#[3;31H ACQUISITIONS/SEC #
X
XTIME:`009`009.ASCID`009<ESC>/[5;28H                       /
VTLINE:`009`009.ASCID`009<ESC>/[8;38H+ - - - - + - - - - + - - - - + - - - - +
X/
VBLINE:`009`009.ASCID`009<ESC>/[24;38H+ - - - - + - - - - + - - - - + - - - -
X +/
VDASH:`009`009.ASCID`009<ESC>/[!SL;38H`124         `124         `124         `
X124         `124/
-+-+-+-+-+ End of part 1 +-+-+-+-+-

