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

📄 segmgr.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	segmgr.c (memory) * *	Segment management (Virtual storage version) */#include "segmgr.h"#include <extension/sys/tkse_ssid.h>#include <extension/sys/svc/ifsegment.h>LOCAL W SegSVCentry( VP para, W fn );LOCAL ER segInitialize( void );LOCAL ER segFinish( void );#define TSD_IFM_VAL_3	3U#define TSD_ARM_VAL_7	7U/* * Exclusive control lock *	At OS startup, Lock() is called before CreateLock(). *	In this case, set initial values to prevent wait sate. */EXPORT	FastLock	SegLock = { -1, -1 };EXPORT	FastLock	FsLock  = { -1, -1 };/* * Read SYSCONF (with error logs by syslog) */EXPORT ER GetSysConf_log( UB *name, W *val, W n ){	W	buf[L_SYSCONF_VAL];	if ( GetSysConf((UB*)name, buf) != n ) {		SYSLOG((LOG_ERR, "SegMgr: %s not defined", name));		return E_SYS;	}	while ( --n >= 0 ) {		val[n] = buf[n];	}	return E_OK;}/* * Read SYSCONF (with error logs by BMS output) */EXPORT ER GetSysConf_bms( UB *name, W *val, W n ){	W	buf[L_SYSCONF_VAL];	if ( GetSysConf((UB*)name, buf) != n ) {		BMS_DEBUG_PRINT(("SegMgr: %s not defined\n", name));		return E_SYS;	}	while ( --n >= 0 ) {		val[n] = buf[n];	}	return E_OK;}/* * Allocate memory from real memory area (RealMemoryInfo) *	Used in initialization processing at startup only. *	Cannot be used after initialization of page frames (InitPageFrameEntry) */EXPORT VP AllocRealMem( RealMemoryInfo *meminfo, UW size ){	W	i;	VP	p;	/* Round up on an 8-byte basis */	size = (size + TSD_ARM_VAL_7) & ~TSD_ARM_VAL_7;	for ( i = 0; i < meminfo->n; ++i ) {		if ( size <= meminfo->a[i].b.nbyte ) {			p = meminfo->a[i].b.laddr;			meminfo->a[i].b.laddr += size;			meminfo->a[i].b.nbyte -= size;			return p;		}	}	return NULL; /* No free space */}/* ------------------------------------------------------------------------ *//* *	Fixed-length memory pool management * *	Library for efficiently managing small fixed-length memory blocks *	Manages small memory blocks each of which can be accommodated in one page. */typedef struct {	QUEUE	q;		/* Queue for page connection */	UW	freeblk;	/* Number of free blocks */	VP	freelst;	/* Free list */} FMB_HDR;/* * Initialize fixed-length memory pool */EXPORT void InitFMB( FMB_Pool *fmbp, UW size ){	/* Round up on a 4-byte basis */	size = (size + TSD_IFM_VAL_3) & ~TSD_IFM_VAL_3;	QueInit(&fmbp->q);	fmbp->blksz = size;	fmbp->maxblk = (PAGESIZE - sizeof(FMB_HDR)) / size;}/* * Obtain fixed-length memory block *	To disable writing to disk (page-out) when memory is obtained, *	specify "nowrite = TRUE". */EXPORT VP AllocFMB( FMB_Pool *fmbp, BOOL nowrite ){	FMB_HDR	*pg;	VP	alloc;	/* Search for pages that have free blocks */	pg = (FMB_HDR*)QueSearchNE(&fmbp->q, &fmbp->q,					0, (W)offsetof(FMB_HDR, freeblk));	if ( (QUEUE*)pg == &fmbp->q ) {		/* Obtain new page */		PFE *pfe = GetPFM(PFS_lock, nowrite);		if ( pfe == NULL ) {			goto err_ret;		}		pg = PFEtoLADR(pfe);		pg->freeblk = fmbp->maxblk;		pg->freelst = (VP)((UW)(pg + 1) | 1);		QueInsert(&pg->q, &fmbp->q);	}	/* Obtain free block */	alloc = (VP)((UW)pg->freelst & ~1U);	if ( ((UW)pg->freelst & 1U) == 0U ) {		/* Fetch from free list */		pg->freelst = *(VP*)alloc;	} else {		/* Fetch from consecutive free areas located at the end of page */		pg->freelst = (VP)((VB*)pg->freelst + fmbp->blksz);	}	pg->freeblk--;	return alloc;err_ret:	DEBUG_PRINT(("AllocFMB Error\n"));	return NULL;}/* * Release fixed-length memory block */EXPORT void FreeFMB( FMB_Pool *fmbp, VP adr ){	FMB_HDR	*pg = PageAlignL(adr);	if ( ++pg->freeblk < fmbp->maxblk ) {		/* Connect to free list */		*(VP*)adr = pg->freelst;		pg->freelst = adr;	} else {		/* Release page */		QueRemove(&pg->q);		DiscardPageFrame(LADRtoPFE(pg));	}}/* ------------------------------------------------------------------------ *//* *	Indirect queue */LOCAL	FMB_Pool	IndQuePool;/* * Initialize indirect queue */EXPORT void InitIndQue( IndQueTop *top ){	QueInit(&top->q);	top->num = 0;}/* * Delete/re-initialize indirect queue */EXPORT void DeleteIndQue( IndQueTop *top ){	QUEUE	*q, *nq;	nq = top->q.next;	while ( (q = nq) != &top->q ) {		nq = q->next;		FreeFMB(&IndQuePool, q);	}	InitIndQue(top);}/* * Insert ent at the end of top *	To disable writing to disk (page-out) when memory is obtained for indirect queues, *	specify "nowrite = TRUE". */EXPORT ER InsertIndQue( IndQueTop *top, VP ent, BOOL nowrite ){	IndQue	*q;	q = AllocFMB(&IndQuePool, nowrite);	if ( q == NULL ) {		goto err_ret;	}	QueInsert(&q->q, &top->q);	q->ent = ent;	top->num++;	return E_OK;err_ret:	DEBUG_PRINT(("InsertIndQue err = E_NOMEM\n"));	return E_NOMEM;}/* * Delete ent. */EXPORT void RemoveIndQue( IndQueTop *top, VP ent ){	QUEUE	*q;	for ( q = top->q.next; q != &top->q; q = q->next ) {		if ( ((IndQue*)q)->ent == ent ) {			QueRemove(q);			FreeFMB(&IndQuePool, q);			top->num--;			break;		}	}}/* * Return an entry that follows pos. *	When "pos = NULL", return the first entry. *	If pos is the last entry, return NULL. */EXPORT IndQue* NextIndQue( IndQueTop *top, IndQue *pos ){	VP	q;	if ( pos == NULL ) {		q = top->q.next;	} else {		q = pos->q.next;	}	return ( q == top )? NULL: q;}/* ------------------------------------------------------------------------ */IMPORT ER ChkCallPLevel( void );  /* Examine call protection level (T-Kernel/SM) *//* * Extended SVC entry */LOCAL W SegSVCentry( VP para, W fn ){	ER	err;	/* Examine call protection level */	err = ChkCallPLevel();	if ( err < E_OK ) {		goto err_ret;	}	switch ( fn ) {	  case SEG_ATTACHFS_FN: {		SEG_ATTACHFS_PARA *p = para;		err = _AttachFS(p->devname, p->omode, p->pinfo, p->diskinfo);	  }	  break;	  case SEG_DETACHFS_FN: {		SEG_DETACHFS_PARA *p = para;		err = _DetachFS(p->diskid, p->pinfo, p->eject);	  }	  break;	  case SEG_CHECKFS_FN: {		SEG_CHECKFS_PARA *p = para;		err = _CheckFS(p->devname, p->omode, p->pinfo);	  }	  break;	  case SEG_INFORMFS_FN: {		SEG_INFORMFS_PARA *p = para;		err = _InformFS(p->diskid, p->spec);	  }	  break;	  case SEG_SYNCFS_FN: {		SEG_SYNCFS_PARA *p = para;		err = _SyncFS(p->diskid, p->info);	  }	  break;	  case SEG_MAPDISK_FN: {		SEG_MAPDISK_PARA *p = para;		err = _MapDisk(p->diskid, p->block, p->mode);	  }	  break;	  case SEG_UNMAPDISK_FN: {		SEG_UNMAPDISK_PARA *p = para;		err = _UnmapDisk(p->mapid, p->flag);	  }	  break;	  case SEG_NOTIFYDISKERR_FN: {		SEG_NOTIFYDISKERR_PARA *p = para;		err = _NotifyDiskErr(p->errhdr);	  }	  break;	  case SEG_MAPMEMORY_FN: {		SEG_MAPMEMORY_PARA *p = para;		err = _MapMemory(p->paddr, p->len, p->attr, p->laddr);	  }	  break;	  case SEG_UNMAPMEMORY_FN: {		SEG_UNMAPMEMORY_PARA *p = para;		err = _UnmapMemory(p->laddr);	  }	  break;	  case SEG_MAKESPACE_FN: {		SEG_MAKESPACE_PARA *p = para;		err = _MakeSpace(p->laddr, p->npage, (UW)p->lsid, p->pte);	  }	  break;	  case SEG_UNMAKESPACE_FN: {		SEG_UNMAKESPACE_PARA *p = para;		err = _UnmakeSpace(p->laddr, p->npage, (UW)p->lsid);	  }	  break;	  case SEG_CHANGESPACE_FN: {		SEG_CHANGESPACE_PARA *p = para;		err = _ChangeSpace(p->laddr, p->npage, (UW)p->lsid, p->pte);	  }	  break;	  case SEG_LOCKSPACE_FN: {		SEG_LOCKSPACE_PARA *p = para;		err = _LockSpace(p->laddr, p->len);	  }	  break;	  case SEG_UNLOCKSPACE_FN: {		SEG_UNLOCKSPACE_PARA *p = para;		err = _UnlockSpace(p->laddr, p->len);	  }	  break;	  case SEG_CNVPHYSICALADDR_FN: {		SEG_CNVPHYSICALADDR_PARA *p = para;		err = _CnvPhysicalAddr(p->laddr, p->len, p->paddr);	  }	  break;	  case SEG_CHKSPACE_FN: {		SEG_CHKSPACE_PARA *p = para;		err = _ChkSpace(p->laddr, p->len, p->mode, p->env);	  }	  break;	  case SEG_CHKSPACETSTR_FN: {		SEG_CHKSPACETSTR_PARA *p = para;		err = _ChkSpaceTstr(p->str, p->max, p->mode, p->env);	  }	  break;	  case SEG_CHKSPACEBSTR_FN: {		SEG_CHKSPACEBSTR_PARA *p = para;		err = _ChkSpaceBstr(p->str, p->max, p->mode, p->env);	  }	  break;	  case SEG_CHKSPACELEN_FN: {		SEG_CHKSPACELEN_PARA *p = para;		err = _ChkSpaceLen(p->laddr, p->len, p->mode, p->env,								(UW)p->lsid);	  }	  break;	  case SEG_READMEMSPACE_FN: {		SEG_READMEMSPACE_PARA *p = para;		err = _ReadMemSpace(p->laddr, p->buf, p->len, (UW)p->lsid);	  }	  break;	  case SEG_WRITEMEMSPACE_FN: {		SEG_WRITEMEMSPACE_PARA *p = para;		err = _WriteMemSpace(p->laddr, p->buf, p->len, (UW)p->lsid);	  }	  break;	  case SEG_SETMEMSPACEB_FN: {		SEG_SETMEMSPACEB_PARA *p = para;		err = _SetMemSpaceB(p->laddr, p->len, p->data, (UW)p->lsid);	  }	  break;	  default: {		err = E_RSFN;	  }	  break;	}err_ret:	return err;}/* * Initialization processing of segment management *	Initialization immediately before kernel startup */EXPORT ER init_segmgr( void ){	RealMemoryInfo	*meminfo;	ER		err;	/* Set page table corresponding to the entire real memory area,	   and obtain real memory area information (meminfo). */	err = InitRealMemoryArea(&meminfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Initialization related to logical space control */	err = InitLogicalSpace(meminfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Generate page frame entry (meminfo cannot be used subsequently) */	err = InitPageFrameEntry(meminfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	BMS_DEBUG_PRINT(("InitSegmentMgr_Part1 err = %d\n", err));	return err;}/* * Initialization processing of segment management *	Initialization immediately after kernel startup */EXPORT ER start_segmgr( void ){	T_DSSY	dssy;	ER	err;	/* Generate exclusive control lock */	err = CreateLock(&SegLock, (UB*)"Seg");	if ( err < E_OK ) {		goto err_ret;	}	err = CreateLock(&FsLock, (UB*)"SegF");	if ( err < E_OK ) {		goto err_ret;	}	/* Initialize memory pool for indirect link */	InitFMB(&IndQuePool, sizeof(IndQue));	/* Initialization related to disk I/O */	err = InitSegIO();	if ( err < E_OK ) {		goto err_ret;	}	/* Initialize disk map */	err = InitDiskMap();	if ( err < E_OK ) {		goto err_ret;	}	/* Initialize system exception management */	err = InitExcMgr(TRUE);	if ( err < E_OK ) {		goto err_ret;	}	/* Initialize memory map for disk I/O */	err = InitMemoryMap();	if ( err < E_OK ) {		goto err_ret;	}	/* Register the manager. */	dssy.ssyatr    = TA_NULL;	dssy.ssypri    = SEG_PRI;	dssy.svchdr    = (FP)SegSVCentry;	dssy.breakfn   = NULL;	dssy.startupfn = NULL;	dssy.cleanupfn = NULL;	dssy.eventfn   = NULL;	dssy.resblksz  = 0;	err = tk_def_ssy(SEG_SVC, &dssy);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	BMS_DEBUG_PRINT(("InitSegmentMgr_Part2 err = %d\n", err));	return err;}/* * Termination processing of segment management */EXPORT ER finish_segmgr( void ){	return E_OK;}/* * Initialization processing of segment management (Part3) */LOCAL ER segInitialize( void ){	ER	err;	/* Start cyclic processing task */	err = InitCyclicProcess();	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	BMS_DEBUG_PRINT(("segInitialize err = %d\n", err));	return err;}/* * Termination processing of segment management */LOCAL ER segFinish( void ){	ER	err, error = E_OK;	/* Deregister the manager. */	err = tk_def_ssy(SEG_SVC, NULL);	if ( err < E_OK ) {		error = err;	}	/* Termination processing of system exception management */	err = InitExcMgr(FALSE);	if ( err < E_OK ) {		error = err;	}	/* Delete exclusive control lock */	DeleteLock(&SegLock);	DeleteLock(&FsLock);	return error;}/* * Manager entry */EXPORT ER SegmentMgr( INT ac, UB *av[] ){	ER	err;	if ( ac >= 0 ) {		/* Initialization processing */		err = segInitialize();		if ( err < E_OK ) {			(void)segFinish();		}	} else {		/* Termination processing */		/* If termination processing "segFinish()" is performed here,		 * it becomes impossible to use CheckSpace() and output syslog().		 * Since system termination is performed subsequently,		 * skip the termination processing of segment management.		 */		err = E_OK;	}	return err;}

⌨️ 快捷键说明

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