⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 page.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		 *	Page files: Release page files. 		 */		W n = (W)pte.c.pfa - PB_BASE;		if ( n > 0 ) {			FreePageFile(n);		}	}	return E_OK;}/* * Lock page frame. */EXPORT void LockPageFrame( PFE *pfe ){	if ( pfe == NULL ) {		return; /* Not to be managed */	}	if ( pfe->stat != PFS_lock ) {		MovePageFrame(pfe, PFS_lock);	}}/* * Unlock page frame. */EXPORT void UnlockPageFrame( PFE *pfe ){	if ( pfe == NULL ) {		return; /* Not to be managed */	}	if ( pfe->dbn_id == PAGEFILE_ID ) {		/* Page file */		MovePageFrame(pfe, PFS_use);	} else {		/* Disk map */		CheckStateDiskMap(pfe);	}}/* * Number of lock counts */EXPORT W LockCount( PFE *pfe, VP laddr, UW lsid, W cnt ){	W	lkcnt = E_MACV;	/* If page files are not to be managed, return 1 to indicate they are resident. */	if ( pfe == NULL ) {		return 1;	}	if ( pfe->dbn_id == PAGEFILE_ID ) {		/* Page file */		PFE_ETC	etc;		etc.w = pfe->etc;		lkcnt = (W)etc.p.lkcnt + cnt;		if (( lkcnt < 0 )||( lkcnt > MaxLockCount )) {			goto err_ret1;		}		etc.p.lkcnt = lkcnt;		pfe->etc = etc.w;	} else {		/* Disk map */		MEL	*mel;		for ( mel = pfe->md.mel; mel != NULL; mel = mel->next_me ) {			ME *me = mel->me;			VB *addr;			if ( !me->mapped ) {				continue;	/* Already unmapped */			}			addr = PageAlignL(me->mode.addr);			if (( lsid != me->mode.space )			  ||( (VB*)laddr < addr )			  ||( (VB*)laddr >= (addr + (me->npage * (UW)PAGESIZE )))) {					continue;	/* Not to be managed */			}			lkcnt = (W)mel->lkcnt + cnt;			if (( lkcnt < 0 )||( lkcnt > MaxLockCount )) {				goto err_ret1;			}			mel->lkcnt = (UB)lkcnt;			break;		}	}	if ( lkcnt < E_OK ) {		goto err_ret0;	}	return lkcnt;err_ret1:	lkcnt = E_LIMIT;err_ret0:	DEBUG_PRINT(("LockCount err = %d\n", lkcnt));	return lkcnt;}/* ------------------------------------------------------------------------ *//* *	Statistical information *//* * Obtain memory statistical information */EXPORT void GetMemInfo( MemoryInfo *info ){	LockSEG();	info->page_frame.total      = MaxPages;	info->page_frame.resident   = LockPFE_Q.diskmap + LockPFE_Q.other;	info->page_frame.unresident = UsePFE_Q.other + FreePFE_Q.other;	info->page_frame.diskcache  = UsePFE_Q.diskmap + FreePFE_Q.diskmap;	GetPageFileInfo(&info->page_file.total, &info->page_file.use);	info->safetymargin = (UW)SafetyMargin;	UnlockSEG();}/* * Number of pages allocatable as general-purpose memory */EXPORT W AvailablePages( void ){	UW	pgf_total, pgf_use;	W	npage;	LockSEG();	GetPageFileInfo(&pgf_total, &pgf_use);	npage =   (W)(pgf_total - pgf_use		+ UsePFE_Q.diskmap + FreePFE_Q.diskmap		+ UninitPageCount);	UnlockSEG();	npage -= SafetyMargin;	if ( npage < 0 ) {		npage = 0;	}	return npage;}/* * Number of pages that can be made resident */EXPORT W LockablePages( W *nopgout_p ){	UW	pgf_total, pgf_use;	W	npage, pgf_free, nopgout;	nopgout = 0;	GetPageFileInfo(&pgf_total, &pgf_use);	pgf_free = pgf_total - pgf_use;	/* Number of pages (included in non-resident memory) that can be paged out */	npage = UsePFE_Q.other + FreePFE_Q.other;	if ( npage > pgf_free ) {		nopgout = npage - pgf_free;		npage = pgf_free;	}	npage += UsePFE_Q.diskmap + FreePFE_Q.diskmap + UninitPageCount;	/* leaving the safety margin for the disabled part to resident */	npage -= SafetyMargin;	if ( npage < 0 ) {		nopgout += npage;		if ( nopgout < 0 ) {			nopgout = 0;		}		npage = 0;	}	if ( nopgout_p != NULL ) {		*nopgout_p = nopgout;	}	return npage;}/* * Maximum number of preload pages (1 to MaxPageIO) */EXPORT W MaxPreLoad( void ){	UW	n;	n = UninitPageCount + FreePFE_Q.diskmap + FreePFE_Q.other + 1U;	if ( n > MaxPageIO ) {		n = MaxPageIO;	}	return (W)n;}/* ------------------------------------------------------------------------ *//* *	Initialization processing *//* * Generate page frame entry *	(before kernel startup) */EXPORT ER InitPageFrameEntry( RealMemoryInfo *meminfo ){	W	dbh_limit;	VP	tbl_top, laddr;	UW	n, i;	ER	err;	/* Obtain SYSCONF definition information. */	err = GetSysConf_bms((UB*)"LimitDBH", &dbh_limit, 1);	if ( err < E_OK ) {		goto err_ret;	}	err = GetSysConf_bms((UB*)"SafetyMargin", &SafetyMargin, 1);	if ( err < E_OK ) {		SafetyMargin = TSD_IPE_SAF_32;	}	/* Total amount of memory (number of bytes) */	n = 0U;	for ( i = 0U; i < (UW)meminfo->n; ++i ) {		n += meminfo->a[i].b.nbyte;	}	/* Exclude a memory area for management table to determine the number of pages provisionally. */	n -= sizeof(PFE);	MaxDBH = MaxPages = n / ((UW)PAGESIZE + sizeof(PFE) + sizeof(DBH));	if ( MaxDBH > (UW)dbh_limit ) {		MaxDBH = (UW)dbh_limit;		MaxPages = (n - (sizeof(DBH) * MaxDBH))					/ ((UW)PAGESIZE + sizeof(PFE));	}	/* Reserve area for management table */	n = (sizeof(PFE) * (MaxPages + 1)) + (sizeof(DBH) * MaxDBH);	tbl_top = AllocRealMem(meminfo, n);	if ( tbl_top == NULL ) {		err = E_NOMEM;		goto err_ret;	}	/* Round off memory area on a page basis. */	n = 0U;	for ( i = 0U; i < (UW)meminfo->n; ++i ) {		laddr = PageAlignU(meminfo->a[i].b.laddr);		meminfo->a[i].p.npage = (meminfo->a[i].b.nbyte			- ((UW)laddr - (UW)meminfo->a[i].b.laddr)) / (UW)PAGESIZE;		meminfo->a[i].p.laddr = laddr;		n += meminfo->a[i].p.npage;  /* Count of all pages */		if ( n > MaxPages ) {			meminfo->a[i].p.npage -= n - MaxPages;			n = MaxPages;		}	}	MaxPages = n;			/* Total number of pages */	MemInfo = meminfo;		/* Frame memory information */	/* Generate PFE table  */	PageFrameEntry = tbl_top;	tbl_top = (VP)((PFE*)tbl_top + MaxPages + 1);	/* Generate/initialize DBH table */	DiskBlockHash = tbl_top;	tbl_top = (VP)((DBH*)tbl_top + MaxDBH);	memset_w(DiskBlockHash, 0, (size_t)MaxDBH);	/* Initialize page management queue */	InitUninitPages();		/* Uninitialized page */	InitPFE_Q(&LockPFE_Q);		/* Queue for lock page */	InitPFE_Q(&UsePFE_Q);		/* Queue for page in use */	InitPFE_Q(&FreePFE_Q);		/* Queue for free page */	return E_OK;err_ret:	BMS_DEBUG_PRINT(("InitPageFrameEntry err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* *	Cyclic processing */LOCAL	ID		CycTskID;		/* Cyclic processing task ID */LOCAL	W		SyncPeriod;		/* Operation cycle *//* * Check access to page in use */LOCAL void AccessCheck( void ){	PFE	*pfe, *npfe;	npfe = NextPFE_Q(&UsePFE_Q, NULL);	while ( (pfe = npfe) != NULL ) {		npfe = NextPFE_Q(&UsePFE_Q, pfe);		if ( pfe->dbn_id == PAGEFILE_ID ) {			/* Page file */			CheckAccessPageFile(pfe);		} else {			/* Disk map */			CheckAccessDiskMap(pfe);		}	}}/* * Cyclic processing task */LOCAL void CyclicProcess( void ){	for ( ;; ) {		tk_dly_tsk((RELTIM)(SyncPeriod / TSD_CIP_DIV_2));		/* Synchronize file system */		LockSEG();		(void)SyncDisk(NULL, 0, SYNCONLY);		UnlockSEG();		tk_dly_tsk((RELTIM)(SyncPeriod / TSD_CIP_DIV_2));		/* Check access */		LockSEG();		AccessCheck();		UnlockSEG();	}}/* * Start cyclic processing task */EXPORT ER InitCyclicProcess( void ){	T_CTSK	ctsk;	ER	err;	/* Obtain SYSCONF definition information. */	err = GetSysConf_bms((UB*)"SyncPeriod", &SyncPeriod, 1);	if ( err < E_OK ) {		goto err_ret;	}	if ( SyncPeriod <= 0 ) {		return E_OK;  /* Do not perform cyclic processing */	}	/* Start cyclic processing task */	SetOBJNAME(ctsk.exinf, "SCyc");	ctsk.task    = CyclicProcess;	ctsk.itskpri = TSD_ICP_ITP_136;	ctsk.stksz   = TSD_ICP_STK_2048;	ctsk.tskatr  = TA_HLNG|TA_RNG0;	err = tk_cre_tsk(&ctsk);	if ( err < E_OK ) {		goto err_ret;	}	CycTskID = err;	err = tk_sta_tsk(CycTskID, 0);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	BMS_DEBUG_PRINT(("InitCyclicProcess err = %d\n", err));	return err;}/* ======================================================================== *//* *	Debug support function */#if DEBUGFUNC_SUPPORT#define	M(i, c)		( ( (i) != 0 )? (c): '-' )/* *	opt =	1	Disk map *		2	Page file *		4	Other */LOCAL BOOL dumpPF1( PFE *pfe, UW opt ){	if ( pfe->md.w == 0U ) {		if ( (opt & TSD_DP1_MSK_4) == 0U ) {			return FALSE;		}	} else if ( pfe->dbn_id == PAGEFILE_ID ) {		if ( (opt & TSD_DP1_MSK_2) == 0U ) {			return FALSE;		}	} else {		if ( (opt & TSD_DP1_MSK_1) == 0U ) {			return FALSE;		}	}	printf("  [%4d] %08x s:%d r:%d %c%c%c d:%2d %08x (%4d) h:%4d e:%03x",		PFEtoPFN(pfe),			/* Page frame number */		PFEtoLADR(pfe),			/* Page frame address */		pfe->stat,			/* Usage state */		pfe->rank,			/* Usage rank */		M(pfe->reg, 'R'),		/* Queue registration state */		M(pfe->upd, 'U'),		/* Update state */		M(pfe->err, 'E'),		/* I/O error state */		pfe->dbn_id, pfe->dbn_no,	/* Disk blocks to be used */		DBHindex(pfe->dbn_no),		/* Hash value */		pfe->dbh,			/* Disk block hash */		pfe->etc			/* PFE_ETC information */	);	if ( pfe->md.w == 0U ) {		printf(" -:");	} else if ( pfe->dbn_id == PAGEFILE_ID ) {		printf(" p:%3d %08x",			pfe->md.page.lsid,		/* Logical space */			pfe->md.page.pn * (UW)PAGESIZE	/* Address */		);	} else {		MEL	*mel;		for ( mel = pfe->md.mel;			mel != NULL; mel = mel->next_me ) {			printf(" %c:%d %d:%08x",				( mel->me->mapped != 0 )? 'm': 'u',				mel->me->mapid,				mel->me->mode.space,				mel->me->mode.addr			);		}	}	printf("\n");	if ( DumpMore(1) ) {		return TRUE;	}	return FALSE;}LOCAL BOOL dumpPFque( PFE_Q *pfe_q, UW opt ){	PFE	*pfe = NULL;	while ( (pfe = NextPFE_Q(pfe_q, pfe)) != NULL ) {		if ( dumpPF1(pfe, opt) ) {			return TRUE;		}	}	return FALSE;}LOCAL BOOL dumpPFuninit( UW opt ){	PFN	pfn;	PFE	*pfe;	for ( pfn = UninitPageQ->next; pfn != 0; pfn = pfe->next ) {		pfe = PFNtoPFE(pfn);		printf("  [%4d] - [%4d] s:%d\n",				pfn, pfn + pfe->dbn_no - 1U, pfe->stat);		if ( DumpMore(1) ) {			return TRUE;		}	}	return FALSE;}LOCAL BOOL dumpPFhash( UW opt ){	PFN	pfn;	PFE	*pfe;	W	i;	for ( i = 0; i < MaxDBH; ++i ) {		pfn = DiskBlockHash[i];		while ( pfn != 0 ) {			pfe = PFNtoPFE(pfn);			if ( dumpPF1(pfe, opt) ) {				return TRUE;			}			pfn = pfe->dbh;		}	}	return FALSE;}/* * Indicate state of page frames *	opt =	0x0F000	Lock page *		0x00F00	Page in use *		0x000F0	Unused page *		0x0000F	Uninitialized page *		0xF0000	Hash table */EXPORT void DumpPF( UW opt ){	printf("PAGE FRAME: Total = %d  MaxDBH = %d\n", MaxPages, MaxDBH);	printf("           lock  use free uninit\n"	       "  diskmap  %4d %4d %4d\n"	       "  other    %4d %4d %4d %4d\n",		LockPFE_Q.diskmap, UsePFE_Q.diskmap, FreePFE_Q.diskmap,		LockPFE_Q.other,   UsePFE_Q.other,   FreePFE_Q.other,		UninitPageCount);	DumpMore(0);	if ( (opt & TSD_DPP_MSK_0XF000) != 0U ) {		/* Indicate state of lock page */		if ( dumpPFque(&LockPFE_Q, TSD_DPP_VAL_MC1) ) {			return;		}	}	if ( (opt & TSD_DPP_MSK_0X0F00) != 0U ) {		/* Indicate state of page in use */		if ( dumpPFque(&UsePFE_Q, TSD_DPP_VAL_MC2) != 0 ) {			return;		}	}	if ( (opt & TSD_DPP_MSK_0X00F0) != 0U ) {		/* Indicate state of unused page */		if ( dumpPFque(&FreePFE_Q, TSD_DPP_VAL_MC3) != 0 ) {			return;		}	}	if ( (opt & TSD_DPP_MSK_0X000F) != 0U ) {		/* Indicate state of uninitialized page */		if ( dumpPFuninit(TSD_DPP_VAL_MC4) != 0 ) {			return;		}	}	if ( (opt & TSD_DPP_MSK_0XF0000) != 0U ) {		/* Indicate state of hash table */		if ( dumpPFhash(TSD_DPP_VAL_MC5) != 0 ) {			return;		}	}}/* * Indicate general information on segment management */EXPORT void DumpSegInfo( void ){	UW	n;	printf("SegMgr:\n");	/* Hash hit rate */	n = HashHitCount + HashMissCount;	printf("  Hash Hit = %d/%d [%d%%]\n",		HashHitCount, n, ( n > 0 )? HashHitCount * TSD_DSI_VAL_100 / n: 0);	/* Number of intercepted pages */	printf("  Snatch = %d\n", SnatchCount);	/* Page frame address */	printf("  Page Frame:\n");	for ( n = 0; n < MemInfo->n; n++ ) {		printf("    [%d] 0x%08x - %d page\n",			n, MemInfo->a[n].p.laddr, MemInfo->a[n].p.npage);	}	/* Reset counter */	HashHitCount = 0;	HashMissCount = 0;	SnatchCount = 0;}#endif /* DEBUGFUNC_SUPPORT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -