;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Program:	show_share
;	Author:		Bruce Ellis
;	Date Written:	9/22/87
;	Synopsis:	This program receives a section name and
;			locates all sections named "name_" and
;			displays the share counts for all pages
;			mapped by the section. 
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	.library	/sys$library:lib.mlb/
	.link		/sys$system:sys.stb/
	$ipldef		;IPL symbolic definitions
	$secdef		;Define Section Table Entry offsets 
	$gsddef		;Global Section Descriptor offsets
	$ptedef		;Page Table entry offsets
	$phddef		;Process header offsets

	.macro	check	?l
	blbs	r0,l
	$exit_s	r0
l:
	.endm	check
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Format for fao output
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

fmt:	.ascid	$ Section name: !AC!/!/$-
		$ Total pages: !10UL   Total valid pages: !10UL!/$-
		$ Total memory resident invalid pages: !10UL !/$-
		$ Pages with share count of 1:   !10UL!/$-
		$ Pages with share count of 2:   !10UL!/$-
		$ Pages with share count of 3:   !10UL!/$-
		$ Pages with share count of 4:   !10UL!/$-
		$ Pages with share count of 5:   !10UL!/$-
		$ Pages with share count of 6:   !10UL!/$-
		$ Pages with share count of 7:   !10UL!/$-
		$ Pages with share count of 8:   !10UL!/$-
		$ Pages with share count of 9:   !10UL!/$-
		$ Pages with share count of 10+: !10UL!/$
buffer:					;Buffer location for display
	.long	1024
	.address	10$
10$:	.blkb	1024
pmt:	.ascid	/Image name> /		;Prompt form section name
max_images=20				;Currently limited to 20 different
					;sections
images:
	.blkb	max_images*40		;storage for image names
mem_not_valid:
	.blkl	max_images		;Count of the number of 
					;pages not valid but memory resident
mem_valid:				;Count of valid pages
	.blkl	max_images
pagecnt:				;Total number of pages in the section
	.blkl	max_images
share_list:				;Count of number of sharers
	.blkl	max_images*10

img_count:				;Count of the number of sections
	.blkl	1
image:	.long	39			;storage for the section name
	.address	image_a
image_a:	
	.blkb	39
lock_addr:
	.address	lock_start
	.address	lock_end

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;Code start
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	.entry	share,^m<r2,r3,r4,r5,r6,r7>
	pushal	image			;Read in the section name
	pushal	pmt
	pushal	image
	calls	#3,g^lib$get_input
	check
	movzwl	image,r2		;append an "_" to the end to
	movb	#^a/_/,image_a(r2)	; get a name of the form section_001
	incl	image			;
	$lkwset_s	inadr=lock_addr	;Lock down the pages accessed at
					; High IPL
	check
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;;	Get the section info in kernel mode
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	$cmkrnl_s	routin=count_share_info
	check
	movl	img_count,r2		;count of number of images
	moval	images,r3		;image name buffer
	moval	mem_valid,r4		;count of valid pages
	moval	pagecnt,r5		;count of pages in the section
	moval	mem_not_valid,r6	;count of the memory resident 
					; invalid pages
	moval	share_list,r7		;count of pages shared
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Format and dump the info one image at a time
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

fmt_and_dump:
	$fao_s	ctrstr=fmt,outbuf=buffer,outlen=buffer,-
		p1=r3,p2=(r5)+,p3=(r4)+,p4=(r6)+,p5=(r7),p6=4(r7),-
		p7=8(r7),p8=12(r7),p9=16(r7),p10=20(r7),p11=24(r7),-
		p12=28(r7),p13=32(r7),p14=36(r7)
	check
	pushal	buffer
	calls	#1,g^lib$put_output
	movl	#1024,buffer
	addl	#40,r3
	addl	#40,r7
	sobgtr	r2,fmt_and_dump
	ret

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;	Kernel mode code to get image counts
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	.entry	count_share_info,^m<r2,r3,r4,r5,r6,r7,r8,r9>
	pushl	#ss$_nosuchsec		;assume section is nonexistent
	moval	g^exe$gl_gsdmtx,r0	;Make sure that the section
	jsb	g^sch$lockr		;does not go away while we
					; are looking at it.
					;set up pointers to storage for:
	moval	images,r3		; Image names,
	moval	mem_valid,r4		; valid page count
	moval	pagecnt,r5		; total page count
	moval	mem_not_valid,r2	; invalid memory resident pages
	moval	share_list,r7		; and share counts
	clrl	img_count		;count of images <- 0
	assume	gsd$l_gsdfl eq 0
	moval	g^exe$gl_gsdsysfl,r6	;get listhead of GSDs
lookup_gsd:
	movl	(r6),r6			;Get the next (or first) GSD
	cmpl	r6,#exe$gl_gsdsysfl	;Are we back at the start
	bneq	check_name		;if not check the name
	brw	outta_gsds		;else done
check_name:
	pushr	#^m<r0,r1,r2,r3,r4,r5>	;save regs for cmpc3
	cmpc3	image,image_a,<gsd$t_gsdnam+1>(r6)	;check name
	popr	#^m<r0,r1,r2,r3,r4,r5>	;restore regs
	bneq	lookup_gsd		;if not the right guy check next gsd
	movl	#ss$_normal,(sp)	;got one
	movb	gsd$t_gsdnam(r6),(r3)	;copy up the size if the name
	movzbl	gsd$t_gsdnam(r6),r0	;get count
	pushr	#^m<r0,r1,r2,r3,r4,r5>	;copy up the name
	movc3	r0,<gsd$t_gsdnam+1>(r6),1(r3)
	popr	#^m<r0,r1,r2,r3,r4,r5>
	addl	#40,r3			;skip past name buffer
	cvtwl	gsd$w_gstx(r6),r8	;get the section table index
	movl	g^mmg$gl_sysphd,r1	;get the system header address
	addl2	phd$l_pstbasoff(r1),r1	;;locate the section table
	movl	sec$l_vpxpfc(r1)[r8],r10	;get the global page table indx
	extzv	#sec$v_vpx,#sec$s_vpx,r10,r9	;
	movl	sec$l_pagcnt(r1)[r8],(r5)+	;get the page count
	movl	-4(r5),r11		;save the page count for a counter
lock_start:	;************ start of locked pages **********
next_gpte:
	setipl	#ipl$_synch		;;Make sure the page is not
					;invalidated while we are looking
					;at it.
	movl	@mmg$gl_gptbase[r9],r1	;get the pte contents
	blss	valid			;if valid bit set process as valid
	setipl	#ipl$_astdel		;else go back to ipl 2
	bitl	#pte$m_typ0,r1 		;check to see if the page
	bneq	not_in_mem		; is in memory
	bitl	#pte$m_typ1,r1
	bneq	not_in_mem
	incl	(r2)			; if so increment count of resident 
					;invalid pages

	brb	not_in_mem
valid:	extzv	#pte$v_pfn,#pte$s_pfn,r1,r1	;Get the pfn ffor this page
	tstw	g^mmg$gw_bigpfn		;check the size of the pfn database
	bneq	long_idx		;if long index use movl
	movzwl	@pfn$ax_shrcnt[r1],r1	;get the share count 
	brb	inc_cnt			;bump the count
long_idx:
	movl	@pfn$ax_shrcnt[r1],r1	;get the share count
inc_cnt:
	setipl	#ipl$_astdel		;return back to ipl 2
lock_end:	;************* end of locked pages *******************
	cmpl	#10,r1			;if count is greater than 10 use 10
	bgtr	use_idx			; as the count else use actual count
	movl	#10,r1
use_idx:
	decl	r1			;back track for index 
	incl	(r7)[r1]		;bump the count
	incl	(r4)			;increment the count of valid pages 
not_in_mem:
	incl	r9			;
	sobgtr	r11,next_gpte		;get the next global pte
	tstl	(r4)+			;bump the pointers
	tstl	(r2)+
	addl	#40,r7
	incl	img_count		;increment the count of images
	cmpl	#max_images,img_count	;over quota?
	bleq	maxed_out		;if so skip out
	brw	lookup_gsd		;get the next gsd
outta_gsds:
maxed_out:
	moval	g^exe$gl_gsdmtx,r0	;give up the mutex
	movl	g^sch$gl_curpcb,r4	; on the system gsds
	jsb	g^sch$unlock
	popl	r0
	ret				;scram
	.end	share

