📄 memmgr.c
字号:
if ( (mb_atr & (MB_LOCAL | MB_DELETE)) != 0U ) { pinfo = GetPinfo(TSK_SELF); if ( pinfo == NULL ) { err = E_CTX; goto err_ret1; } } memgrp = ( (mb_atr & MB_LOCAL) != 0U )? &pinfo->lmemgrp: (( (mb_atr & MB_DELETE) != 0U )? &pinfo->smemgrp: NULL); /* Release memory */ err = relPages(pt, adr, memgrp); if ( err < E_OK ) { goto err_ret1; } nblk = (W)err; /* Delete memory space (Reset resident state at the same time) */ err = UnmakeSpace(adr, nblk, (W)GetLSID_tid(TSK_SELF)); if ( err < E_OK ) { goto err_ret1; } UnlockMEM(); return E_OK;err_ret1: UnlockMEM(); DEBUG_PRINT(("_tkse_rel_mbk err = %d\n", err)); return ERtoERR(err);}/* * Refer to memory state */LOCAL ER _tkse_mbk_sts( M_STATE *sts ){ T_RSMB rsmb; ER err; /* Parameter check */ err = ChkSpaceRW(sts, sizeof(M_STATE)); if ( err < E_OK ) { goto err_ret; } /* Obtain memory information */ err = RefSysMemInfo(&rsmb); if ( err < E_OK ) { goto err_ret; } sts->blksz = rsmb.blksz; sts->total = rsmb.total; sts->free = rsmb.free; return E_OK;err_ret: DEBUG_PRINT(("_tkse_mbk_sts err = %d\n", err)); return ERtoERR(err);}/* ------------------------------------------------------------------------ *//* * Release one memory block in group. */LOCAL ER relMemGrpPiece( PAGETBL *pt, PN pn, UW lsid ){ VP adr = PageAdr(pt, pn); ER err; /* Release memory */ err = relPage1(pt, pn); if ( err < E_OK ) { goto err_ret; } /* Delete memory space (Reset resident state at the same time) */ err = UnmakeSpace(adr, (W)err, (W)lsid); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("relMemGrpPiece err = %d\n", err)); return err;}/* * Release all memory blocks in group */LOCAL ER relMemGrp( PAGETBL *pt, VP *p_grp, UW lsid ){ PN pn; ER err; if ( *p_grp == NULL ) { return 0; /* Group is empty */ } pn = PageNo(pt, *p_grp); while ( !isEmptyPageQue(pt, pn) ) { err = relMemGrpPiece(pt, pt->pageque[pn].next, lsid); if ( err < E_OK ) { goto err_ret; } } *p_grp = NULL; err = relMemGrpPiece(pt, pn, lsid); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("relMemGrp err = %d\n", err)); return err;}/* * Obtain system memory (for T-Kernel/SM) * attr = TA_RNGn | TA_NORESIDENT | TA_NOCACHE */EXPORT VP GetSysMemBlk( INT nblk, UINT attr ){ VP adr; UW mb_atr; UW pte; ER err; /* Memory attribute */ mb_atr = 0U; if ( (attr & TA_RNG3) == TA_RNG3 ) { mb_atr |= MB_SHARE; } LockMEM(); /* Obtain memory */ adr = getPages(SystemPageTable, NULL, nblk, mb_atr); if ( adr == NULL ) { goto err_ret1; } /* Allocate space */ pte = ( (attr & TA_RNG3) != TA_RNG3 )? PTE_SMEM_NC: PTE_UMEM_NC; if ( (attr & TA_NOCACHE) != 0U ) { pte = PTE_CacheOff(pte); } err = _MakeSpace(adr, nblk, 0, pte); if ( err < E_OK ) { goto err_ret2; } if ( (attr & TA_NORESIDENT) == 0U ) { /* Resident */ err = _LockSpace(adr, nblk * PAGESIZE); if ( err < E_OK ) { goto err_ret3; } } else { /* Allocate physical memory to all pages so that it will be reflected in the amount of physical memory consumed. */ W i; for ( i = (nblk - 1) * PAGESIZE; i >= 0; i -= PAGESIZE ) { ((UB*)adr)[i] = 0; } } UnlockMEM(); return adr;err_ret3: (void)_UnmakeSpace(adr, nblk, 0);err_ret2: (void)relPages(SystemPageTable, adr, NULL);err_ret1: UnlockMEM(); BMS_DEBUG_PRINT(("GetSysMemBlk err = %d\n", err)); return NULL;}/* * Release system memory (for T-Kernel/SM) */EXPORT ER RelSysMemBlk( VP adr ){ LockMEM(); (void)relMemGrpPiece(SystemPageTable, PageNo(SystemPageTable, adr), 0); UnlockMEM(); return E_OK;}/* * Obtain system memory information (for T-Kernel/SM) */EXPORT ER RefSysMemInfo( T_RSMB *rsmb ){ MemoryInfo info; /* Obtain memory statistical information */ GetMemInfo(&info); rsmb->blksz = PAGESIZE; rsmb->total = (W)info.page_frame.total + (W)info.page_file.total; rsmb->free = rsmb->total - (W)(info.page_frame.resident + info.page_frame.unresident + info.page_file.use); rsmb->free -= (W)info.safetymargin; if ( rsmb->free < 0 ) { rsmb->free = 0; } return E_OK;}/* * Obtain memory area * Reserve a memory area for npage in lsid logical space. * lsid == 0 Allocate to system space. * lsid != 0 Allocate to local space. * Do not perform setting of memory space (MakeSpace). */EXPORT VP AllocMemorySpace( W npage, UW lsid ){ PAGETBL *pt; T_TSKSPC curspc; VP laddr; ER err; if ( lsid == 0U ) { /* Obtain from system space */ pt = SystemPageTable; } else { /* Obtain from local space */ pt = GetPINFO_lsid(lsid)->lpgtbl; /* Switch to logical space to be processed */ err = ChangeLogicalSpace(&curspc, GetTSKSPC_lsid(lsid)); if ( err < E_OK ) { goto err_ret1; } } /* Obtain memory area */ LockMEM(); laddr = getPages(pt, NULL, npage, 0); UnlockMEM(); if ( laddr == NULL ) { err = E_NOMEM; goto err_ret2; } /* Turn back to original logical space. */ if ( lsid != 0U ) { (void)ChangeLogicalSpace(NULL, curspc); } return laddr;err_ret2: if ( lsid != 0U ) { (void)ChangeLogicalSpace(NULL, curspc); }err_ret1: DEBUG_PRINT(("AllocMemorySpace err = %d\n", err)); return NULL;}/* * Release memory area * Release an area specified by laddr in lsid logical space. * Do not perform deletion of memory space (UnmakeSpace). * Return the number of released pages. */EXPORT W FreeMemorySpace( VP laddr, UW lsid ){ BOOL sys = !isLocalSpace(laddr); PAGETBL *pt; T_TSKSPC curspc; ER err; if ( sys != 0 ) { /* Release in system space. */ pt = SystemPageTable; } else { /* Release in local space. */ pt = GetPINFO_lsid(lsid)->lpgtbl; /* Switch to logical space to be processed */ err = ChangeLogicalSpace(&curspc, GetTSKSPC_lsid(lsid)); if ( err < E_OK ) { goto err_ret1; } } /* Release memory area */ LockMEM(); err = relPages(pt, laddr, NULL); UnlockMEM(); if ( err < E_OK ) { goto err_ret2; } /* Turn back to original logical space. */ if ( !sys ) { (void)ChangeLogicalSpace(NULL, curspc); } return err;err_ret2: if ( !sys ) { (void)ChangeLogicalSpace(NULL, curspc); }err_ret1: DEBUG_PRINT(("FreeMemorySpace err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ *//* * Initialize local memory space * Create and initialize a new local memory space for pinfo process. */EXPORT ER InitLocalMemory( PINFO *pinfo ){ VP top; T_TSKSPC curspc; ER err; /* Switch to logical space to be processed */ err = ChangeLogicalSpace(&curspc, GetTSKSPC_pinfo(pinfo)); if ( err < E_OK ) { goto err_ret1; } /* Start of local memory area (immediately posterior to bss area) */ top = (VB*)pinfo->ldinfo.topadr + ((pinfo->ldinfo.dpage + pinfo->ldinfo.mpage) * PAGESIZE); /* Initialize local memory space management table */ err = initPageTable(top, (VP)LOCALSPACE_END, GetLSID_pinfo(pinfo)); if ( err < E_OK ) { goto err_ret2; } pinfo->lpgtbl = top; /* Add the size of management table to the number of memory map pages. */ pinfo->ldinfo.mpage += (UW)err; /* Turn back to original logical space. */ ChangeLogicalSpace(NULL, curspc); return E_OK;err_ret2: (void)ChangeLogicalSpace(NULL, curspc);err_ret1: DEBUG_PRINT(("InitLocalMemory err = %d\n", err)); return err;}/* * Obtain the number of pages allocated to local memory. * Called during LockPinfo. */EXPORT W GetLocalMemoryUseCount( PINFO *pinfo ){ PAGETBL *pt = pinfo->lpgtbl; T_TSKSPC curspc; W usecount; ER err; /* Switch to logical space to be processed */ err = ChangeLogicalSpace(&curspc, GetTSKSPC_pinfo(pinfo)); if ( err < E_OK ) { goto err_ret; } LockMEM(); /* Number of allocated pages */ usecount = (W)pt->maxpage - (W)pt->freepage; UnlockMEM(); /* Turn back to original logical space. */ ChangeLogicalSpace(NULL, curspc); return usecount;err_ret: DEBUG_PRINT(("GetLocalMemoryUseCount err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ *//* * Cleanup function * Processing at process termination */LOCAL void MemCleanUp( ID resid, W pid ){ PINFO *pinfo; T_TSKSPC curspc, tskspc; ER err; err = GetPidToPinfo(pid, &pinfo); if ( err < E_OK ) { goto err_ret; } /* Switch to logical space of the process */ tskspc = GetTSKSPC_pinfo(pinfo); err = ChangeLogicalSpace(&curspc, tskspc); if ( err < E_OK ) { goto err_ret; } LockMEM(); /* Release all memory blocks that are set to be deleted at process termination. */ (void)relMemGrp(pinfo->lpgtbl, &pinfo->lmemgrp, (UW)tskspc.lsid); (void)relMemGrp(SystemPageTable, &pinfo->smemgrp, (UW)tskspc.lsid); UnlockMEM(); /* Turn back to original logical space. */ (void)ChangeLogicalSpace(NULL, curspc); return;err_ret: DEBUG_PRINT(("MemCleanUp err = %d\n", err)); return;}/* * Extended SVC entry */LOCAL WER MemSVCentry( VP para, W fn ){ switch ( fn ) { case MM_GET_MBK_FN: { MM_GET_MBK_PARA *p = para; return _tkse_get_mbk(p->adr, p->nblk, p->atr); } case MM_REL_MBK_FN: { MM_REL_MBK_PARA *p = para; return _tkse_rel_mbk(p->adr); } case MM_MBK_STS_FN: { MM_MBK_STS_PARA *p = para; return _tkse_mbk_sts(p->sts); } default: { /* nothing to do */ break; } } return E_RSFN;}/* * Memory management initialization processing * Initialization before kernel startup */EXPORT ER init_memmgr( void ){ ER err; /* Initialization of system memory space management table */ err = initPageTable((VP)SYSSPACE_TOP, (VP)SYSSPACE_END, 0); if ( err < E_OK ) { goto err_ret; } SystemPageTable = (PAGETBL*)SYSSPACE_TOP; return E_OK;err_ret: BMS_DEBUG_PRINT(("InitMemoryMgr_Part1 err = %d\n", err)); return err;}/* * Memory management initialization processing * Initialization immediately after kernel startup */EXPORT ER start_memmgr( void ){ ER err; /* Generate exclusive control lock */ err = CreateLock(&MemLock, (UB*)"Mem"); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: BMS_DEBUG_PRINT(("InitMemoryMgr_Part2 err = %d\n", err)); return err;}/* * Memory management termination processing */EXPORT ER finish_memmgr( void ){ return E_OK;}/* * Memory management initialization processing (Part 3) */EXPORT ER MemoryMgr( INT ac, UB *av[] ){ T_DSSY dssy; W w[L_SYSCONF_VAL]; ER err; if ( ac < 0 ) { return E_OK; /* Skip termination processing. */ } /* Minimum size of memory to be reserved for system (number of pages) */ err = GetSysConf_log((UB*)"SRsvMem", w, 1); if ( err == E_OK ) { SysReserve = w[0]; } /* Register the manager. */ dssy.ssyatr = TA_NULL; dssy.ssypri = MM_PRI; dssy.svchdr = (FP)MemSVCentry; dssy.breakfn = NULL; dssy.startupfn = NULL; dssy.cleanupfn = MemCleanUp; dssy.eventfn = NULL; dssy.resblksz = 0; err = tk_def_ssy(MM_SVC, &dssy); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("InitMemoryMgr err = %d\n", err)); return err;}/* ======================================================================== *//* * Debug support function */#if DEBUGFUNC_SUPPORT/* * Indicate memory management table state * pid > 0 Local memory of pid process * pid = 0 System memory */EXPORT void DumpMemoryTable( W pid ){ PINFO *pinfo; T_TSKSPC curspc; PAGETBL *pt; PAGEQUE *tp, *ep; W i, n; ER err; if ( pid > 0 ) { /* Local memory */ printf("LOCAL MEMORY: pid = %d", pid); /* Switch to the process space */ err = PidToPinfo(pid, &pinfo); if ( err < E_OK ) { goto err_ret1; } err = ChangeLogicalSpace(&curspc, GetTSKSPC_pinfo(pinfo)); if ( err < E_OK ) { UnlockPinfo();err_ret1: printf("\n"); return; } pt = pinfo->lpgtbl; UnlockPinfo(); } else { switch ( pid ) { case 0: /* System memory */ printf("SYSTEM MEMORY:"); pt = SystemPageTable; break; default: return; } } printf(" total = %d (%d KB) free = %d (%d KB)\n", pt->maxpage, pt->maxpage * (PAGESIZE / TSD_DMT_DIV_1024), pt->freepage, pt->freepage * (PAGESIZE / TSD_DMT_DIV_1024)); i = 1; while ( i <= pt->maxpage ) { tp = &pt->pageque[i]; n = NumOfPages(tp); ep = &pt->pageque[i + n - 1]; printf(" 0x%08x %c%c - 0x%08x %c%c %c a:%x (%d page)\n", PageAdr(pt, i), ( (tp->wall & TWALL) != 0 )? 'T': ' ', ( (tp->wall & EWALL) != 0 )? 'E': ' ', PageAdr(pt, i + n - 1), ( (ep->wall & TWALL) != 0 )? 'T': ' ', ( (ep->wall & EWALL) != 0 )? 'E': ' ', ( tp->use != 0 )? 'U': 'F', tp->atr, n ); if ( n < 1 ) { printf(" ** ERROR n = %d **\n", n); break; } i += n; } if ( pid > 0 ) { /* Turn back to original space. */ ChangeLogicalSpace(NULL, curspc); }}#endif /* DEBUGFUNC_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -