📄 vm.c
字号:
/*
* Copyright 1999, 2000, 2001, 2002 Lucent Technologies Inc.
* All Rights Reserved.
* Information Sciences Research Center, Bell Labs.
*
* LUCENT TECHNOLOGIES DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE
* OR THE SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The
* software is provided "as is" without expressed or implied warranty
* of any kind.
*
* These notices must be retained in any copies of any part of this
* software.
*
*/
#include "unistd.h"
#include "types.h"
#include "pebble.h"
#include "machine/cpu.h"
#include "diag.h"
#include "time.h"
#include "nucleus.h"
typedef struct {
int *base;
} mobj;
mobj *create_mobj(size_t, int);
#define vm_map(x, client) \
call_portal(SYS_VM_MAP, (x), (client))
#define vm_protect(x, client, y) \
call_portal(SYS_VM_PROTECT, (x), (client), (y))
#define vm_allocate(x, client) \
call_portal(SYS_VM_ALLOCATE, (x), (client))
/*
* Fault handlers that the VM server will install in the clients'
* portal tables.
*
* pagefault: Handles TLBL, TLBS exceptions. It backs the virtual page
* by a physical frame. Additionally, it write-protects the
* page if it is in a range with transactional semantics.
* protectionfault: Handles MOD exception.
*/
Time start, elapsed;
uint elapsedcount;
static void pagefault(Thread *t, int asid, int switched_stack,
char *badvirt)
{
/* Got page fault. Need to find out what memory object backs
* this vaddr, then decide how to back it up.
* For now, just allocate a physical page and update the pte.
*/
start = hrtime();
vm_map(badvirt, asid);
elapsed = 2 * (hrtime() - start);
if (VM_DIAG)
printf("map: %d cycles\n", (int)elapsed);
/* Write-protect the page - should only be done when in
* transactional range XXX
*/
start = hrtime();
get_thread();
elapsed = 2 * (hrtime() - start);
if (VM_DIAG)
printf("null: %d cycles\n", (int)elapsed);
start = hrtime();
vm_protect(badvirt, asid, 1);
elapsed = 2 * (hrtime() - start);
if (VM_DIAG)
printf("mprotect: %d cycles\n", (int)elapsed);
return;
}
static void protectionfault(Thread *t, int asid, int switched_stack,
char *badvirt)
{
/*
* Got write protection fault.
*/
elapsedcount = get_count();
elapsed = hrtime();
if (VM_DIAG)
printf("elapsed = %u %u, elapsedcount = %d\n",
(uint)(elapsed>>32), (uint)elapsed, elapsedcount);
/* Write-enable the page
*
* This should be the first time a client tries to modify this
* page. A write lock should be acquired on the page so that
* no other transaction can modify it before this one commits
* or aborts.
*
* At this point, we should either copy the page to a shadow
* page, or write it to the log. In both cases, we are
* preparing for undo action in a possible abort (due to
* explicit action, or recovery after failure)
*/
vm_protect(badvirt, asid, 0);
return;
}
/*
* Triggered by a low watermark on free physical frames, it
* can propose an alternative victim for replacement.
*
* If the page to be evicted is dirty after being modified by
* an ongoing transaction, the undo log record will need to be
* flushed to disk before the frame is written to the stable
* database.
*/
static int pageout(char *victim)
{
return (int)NULL;
}
static int transmem(int asid, int size)
{
int *mem;
printf("Creating transactional memory segment of size %d for"
" domain %d\n", size, asid);
/* In response to client request for memory segment with
* transactional semantics, the VM server will install fault
* handlers to the client portal table.
*
* Hence, when the client is causing a page or protection
* fault, it will be the VM server that handles it.
*/
/* note: register A2 is != 0 if portal code switched stacks */
if (portal_create(EXC_MOD, "eftai", 0, (Func) protectionfault, 1) < 0)
panic("portal_create_excpt for intr_dispatcher failed\n");
/* note: register A2 is != 0 if portal code switched stacks */
if (portal_create(EXC_TLBL, "eftaii", 0, (Func) pagefault, 1) < 0)
panic("portal_create_excpt for intr_dispatcher failed\n");
/* note: register A2 is != 0 if portal code switched stacks */
if (portal_create(EXC_TLBS, "eftaii", 0, (Func) pagefault, 1) < 0)
panic("portal_create_excpt for intr_dispatcher failed\n");
printf("Portals created okay\n");
mem = (int *)vm_allocate(size, asid);
return (int)mem;
}
/* Need interface to physical memory, still */
int
main(int arg, char *argv[])
{
/* verify that we are running in user mode with interrupts enabled */
if (!check_psw(1,1)) {
printf("idle: invalid processor status: %08lx\n", get_psw());
task_exit(1);
}
printf("Transactional memory server (id %d) is active.\n",
get_asid());
if (portal_create(SYS_TRANSMEM, "spai", 0, (Func) transmem, 0)
< 0) {
panic("portal_create failed for transactional memory\n");
}
if (portal_create(SYS_TRANSPAGEOUT, "spai", 0, (Func) pageout, 0)
< 0) {
panic("portal_create failed for transactional memory pageout\n");
}
/*
* return to initialization code.
* cannot just "return", since the startup code (crt0.S) calls
* exit when main routine terminates.
*/
call_portal(SYS_RTN_RPC);
return(1);
}
/* Things I need to do with memory objects
*
* a. Create a memory object of a certain size. Demand-paged, it is
* backed by a cache of physical pages.
* b. Map a memory object to a virtual address range.
*
*/
mobj *create_mobj(size_t size, int client_asid)
{
mobj *m = (mobj *) malloc(sizeof(mobj));
m->base = (int *) vm_allocate(size, client_asid);
return m;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -