#include "sysdef.h" /* EDPAGR.C work file paging */ /* */ /* 01-Oct-84 11:03:13 Brian Nelson */ /* */ /* Copyright Notice */ /* */ /* */ /* C version Copyright (C) 1984 Change Software, Inc. */ /* Copyright (C) 1978 1979 1980 1981 1982 1983 1984 by */ /* Change Software, Inc. */ /* */ /* */ /* This software is furnished under a license and may */ /* be used and copied only in accordance with the */ /* terms of such license and with the inclusion of */ /* the above copyright notice. This software or any */ /* other copies thereof may not be provided or other- */ /* wise made available to any other person. No title */ /* to and ownership of the software is hereby trans- */ /* ferred. */ /* */ #include "scerrd.h" #include "tempio.h" /* the following things should be evaluated by the C preprocessor */ /* but the DECUS C compiler can't do it */ /* */ /* #define PAGE_SIZE 1024 */ /* #define TEXT_SIZE 512 */ /* #define BUF_COUNT 4 */ /* #define CLUSTER_SIZE PAGE_SIZE/TEXT_SIZE */ /* #define TEXT_COUNT BUF_COUNT*CLUSTER_SIZE */ #if VAXVMS #define _MIN_BUF_COUNT 32 #define _MAX_BUF_COUNT 256 #define _MAX_PAGE_SIZE 0170000 #define _CLUSTER_SIZE 4 #else #define _MIN_BUF_COUNT 4 #define _MAX_BUF_COUNT 16 #define _MAX_PAGE_SIZE 0070000 #define _CLUSTER_SIZE 2 #endif #define then #define _TEXT_SIZE 512 #define _PAGE_SIZE _TEXT_SIZE*_CLUSTER_SIZE #define _MAX_TEXT_COUNT _MAX_BUF_COUNT*_CLUSTER_SIZE static char *text_pointer[_MAX_TEXT_COUNT] ; static char *buf_pointer[_MAX_BUF_COUNT] ; static int buf_res[_MAX_BUF_COUNT] ; static int buf_mod[_MAX_BUF_COUNT] ; static int access_count[_MAX_BUF_COUNT] ; static int least_access ; static int last_page ; static int total_count ; static int page_size ; static int buf_count ; static int cluster_size ; /* The pager will make the assumption that BUF_POOL is contiguous */ /* in memory since the cleanest way to handle the fact that the */ /* page size is greater than the buffer size to return a pointer */ /* to place in the pool where the 512 byte buffer should be. */ char *base_address ; static int all_buf_count ; static int dopageing = 1 ; int vir_pagecount = 0 ; extern struct stats tempstat ; /* PAGEINIT() */ /* */ /* Called from INITTEMP() to setup the cacheing data structures */ /* ALLBUFFER() is called with min and max arguements in 512 byte */ /* units, and returns the buffer count in 512 byte units. */ pageinit() { register int i ; extern char *allbuffer() ; base_address = allbuffer(&all_buf_count , _MIN_BUF_COUNT*_CLUSTER_SIZE , _MAX_BUF_COUNT*_CLUSTER_SIZE ) ; if ( (all_buf_count=all_buf_count/_CLUSTER_SIZE) == 0 ) then return(0) ; vir_pagecount = all_buf_count * _CLUSTER_SIZE ; dopageing = 1 ; for ( i=0; i _MAX_PAGE_SIZE ) then page_size = _MAX_PAGE_SIZE ; cluster_size = page_size / _TEXT_SIZE ; buf_count = 1 ; buf_res[0] = 0 ; buf_mod[0] = 0 ; access_count[0] = 0 ; } /* PAEGON() */ /* */ /* Called from IFL() to reset the cacher to work normally */ pageon(win) int win ; { if ( win != 0 ) then return(1) ; if ( dopageing == 0 ) then { dopageing = 1 ; if ( buf_res[0] && buf_mod[0] ) then { mapcache() ; puttblock(buf_pointer[0],page_size,buf_res[0],win) ; unmapcache() ; last_page = buf_res[0] + cluster_size - 1 ; } buf_mod[0] = 0 ; buf_res[0] = 0 ; access_count[0] = 0 ; page_size = _PAGE_SIZE ; cluster_size = _CLUSTER_SIZE ; buf_count = all_buf_count ; } } gettemp(buf,vbn,win) register char *buf ; int vbn ,win ; { register int i ; extern char *bufcontrol() ; if (win != 0) return(gettblock(buf,_TEXT_SIZE,vbn,win)) ; mapcache(win) ; #if RSX blkmov(buf,bufcontrol(vbn,0,win)) ; #else scopy(buf,bufcontrol(vbn,0,win),_TEXT_SIZE) ; #endif unmapcache(win) ; return(1) ; } puttemp(buf,vbn,win) register char *buf ; int vbn,win ; { register int i ; extern char *bufcontrol() ; if (win != 0) return(puttblock(buf,_TEXT_SIZE,vbn,win)) ; mapcache(win) ; #if RSX blkmov(bufcontrol(vbn,1,win),buf) ; #else scopy(bufcontrol(vbn,1,win),buf,_TEXT_SIZE) ; #endif unmapcache(win) ; return(1) ; } char *bufcontrol(vbn,direction,win) int vbn,direction,win ; { register int buf,block,temp ; int offset,status ; status = sys_normal ; vbn-- ; offset = vbn % cluster_size ; block = vbn - offset + 1 ; for ( buf=0; buf < buf_count && block != buf_res[buf]; buf++ ) ; if ( buf >= buf_count ) then { /* a page fault has occurred */ least_access = 32767 ; temp = 0 ; for ( buf=0; buf < buf_count; buf++ ) { if ( access_count[buf] <= least_access ) then { least_access = access_count[buf] ; temp = buf ; } } buf = temp ; if ( buf_mod[buf] && (temp=buf_res[buf]) ) then { if (temp > last_page) then last_page = temp+cluster_size-1 ; status=puttblock(buf_pointer[buf],page_size,temp,win) ; tempstat.w_faults++ ; } if ( block <= last_page) then { status=gettblock(buf_pointer[buf],page_size,block,win) ; tempstat.r_faults++ ; } buf_res[buf] = block ; buf_mod[buf] = 0 ; } else tempstat.hits++ ; access_count[buf] = ++total_count ; if ( direction ) then buf_mod[buf] = 1 ; if ( status != sys_normal ) then tederror("I/O error on the workfile") ; return( text_pointer[buf*cluster_size+offset] ) ; }