app1.c
来自「pebble」· C语言 代码 · 共 2,046 行 · 第 1/4 页
C
2,046 行
if ((fd = fd_open("fs2")) < 0)
panic("fd_open(fs2):");
printf("before window passing test: TLB miss count=%d general exceptions count=%d\n",
get_tlb_excpt_count(), get_gen_excpt_count());
printf("calling fs write2\n");
start = hrtime();
for (i = 0; i < N; i++)
call_portal(WRITE2PORT(fd), np, sz);
elapsed = 2*(hrtime() - start) - loop_overhead;
printf(
"elapsed cycles of %d portal crossing with window open/close w/out TLB update: %d\n",
i, (int)elapsed);
printf("each portal crossing: %d cycles\n",
(int)(elapsed+N/2)/N);
printf("after window passing test: TLB miss count=%d general exceptions count=%d\n",
get_tlb_excpt_count(), get_gen_excpt_count());
printf("calling fs read2\n");
np[0] = 0;
start = hrtime();
for (i = 0; i < N; i++)
call_portal(READ2PORT(fd), np, sz);
elapsed = 2*(hrtime() - start) - loop_overhead;
printf(
"elapsed cycles of %d portal crossing with window open/close and TLB update: %d\n",
i, (int)elapsed);
printf("each portal crossing: %d cycles\n",
(int)(elapsed+N/2)/N);
printf(
"after window access test: TLB miss count=%d general exceptions count=%d\n",
get_tlb_excpt_count(), get_gen_excpt_count());
printf("portal window test ended successfully\n\n");
}
void
test_page_transfer(void)
{
int i, code, sz, npages, *p1, *p2, *p3, *pp;
void *q;
int give_id, peek_id, take_id, swap_id;
int share_id, set_id, unmap_id, count_id;
char msg[NAMELEN];
Time start, elapsed;
/* check window give/take/swap */
printf("testing window give/take/swap\n");
p1 = alloc_page();
p2 = alloc_page();
p3 = alloc_page();
sz = getpagesize();
printf("p1=%p p2=%p p3=%p pagesize=%d\n", p1, p2, p3, sz);
set_mem(p1, sz);
set_mem(p2, sz);
set_mem(p3, sz);
clean_cache(p1, sz);
clean_cache(p2, sz);
clean_cache(p3, sz);
check_mem(p1, (int)p1, sz);
check_mem(p2, (int)p2, sz);
check_mem(p3, (int)p3, sz);
if ((give_id = portal_open("fs_give", 1)) < 0)
panic("portal_open(fs_give):");
if ((peek_id = portal_open("fs_peek", 1)) < 0)
panic("portal_open(fs_peek):");
if ((take_id = portal_open("fs_take", 1)) < 0)
panic("portal_open(fs_take):");
if ((swap_id = portal_open("fs_swap", 1)) < 0)
panic("portal_open(fs_swap):");
if ((share_id = portal_open("fs_share", 1)) < 0)
panic("portal_open(fs_share):");
if ((set_id = portal_open("fs_set", 1)) < 0)
panic("portal_open(fs_set):");
if ((unmap_id = portal_open("fs_unmap", 1)) < 0)
panic("portal_open(fs_unmap):");
if ((count_id = portal_open("fs_count", 1)) < 0)
panic("portal_open(fs_count):");
/* testing fs_give */
if (call_portal(give_id, NULL, 0) >= 0)
panic("fs_give(NULL) expected to fail but did not");
get_error(msg);
printf("expected error message from fs_give(NULL): %s\n", msg);
if (call_portal(give_id, &shared_flag, 0) >= 0)
panic("fs_give(<data address>) expected to fail but did not");
get_error(msg);
printf("expected error message from fs_give(<data address>): %s\n",
msg);
if (vm_count_page(&shared_flag) >= 0)
panic("vm_count_page(<data addr>) did not fail\n");
get_error(msg);
printf("expected error message from vm_count_page(<data addr>): %s\n",
msg);
if ((code = vm_count_page(p1)) < 0)
panic("vm_count_page(p1) failed:");
if (code != 1) {
printf("fs_count(%p) returned %d; expected 1\n", p1, code);
task_exit(1);
}
if (call_portal(give_id, p1, 0) < 0)
panic("fs_give:");
/* this doamin can not access page p1 any longer */
if (vm_count_page(p1) >= 0)
panic("vm_count_page(%p) expected to fail but did not\n", p1);
get_error(msg);
printf("expected error msg from vm_count_page(p1) after fs_give: %s\n",
msg);
/* fs domain can access page p1 */
if ((code = call_portal(count_id, p1)) < 0)
panic("fs_count(p1) failed:");
if (code != 1) {
printf("fs_count(%p) returned %d; expected 1\n", p1, code);
task_exit(1);
}
if (call_portal(give_id, p1, 0) >= 0)
panic("2nd fs_give expected to fail but did not");
get_error(msg);
printf("expected error message from 2nd give: %s\n", msg);
/* verify that page is available now in the fs domain */
printf("checking page contents after transfer to fs domain\n");
for (i = 0; i < sz; i += sizeof(int)) {
code = call_portal(peek_id, (int)p1 + i);
if (code != ~((int)p1+i)) {
printf("fs_peek failed: addr=%p value=%d expected=%d\n",
(int *)((int)p1 + i), code, ~((int)p1 + i));
task_exit(1);
}
}
printf("page contents is correct when accessed from fs domain\n");
/* get the page back */
pp = (int *)call_portal(take_id, 0);
if (pp == (int *)-1)
panic("fs_take:");
if (pp != p1) {
printf("fs_take returned %p; expected %p\n", pp, p1);
task_exit(1);
}
/* verify that fs domain can not access the page any longer */
if ((code = call_portal(count_id, p1)) >= 0)
panic("fs_count(%p) expected to fail but did not\n", p1);
get_error(msg);
printf("expected error msg from fs_count(p1) after fs_take: %s\n",
msg);
/* verify that calling domain can access the page */
if ((code = vm_count_page(pp)) < 0)
panic("vm_count_page(pp) failed:");
if (code != 1) {
printf("fs_count(%p) returned %d; expected 1\n", pp, code);
task_exit(1);
}
printf("vm_count_page(p1) after fs_take: %d\n", code);
printf("checking returned page contents\n");
check_mem(pp, (int)p1, sz);
pp = (int *)call_portal(take_id, 0);
if (pp != (int *)-1) {
printf("2nd fs_take did not fail as expected");
task_exit(1);
}
get_error(msg);
printf("expected error message from 2nd fs_take: %s\n", msg);
/* give page p1; then swap it with page p2 */
printf("checking page swap\n");
if (call_portal(give_id, p1, 0) < 0)
panic("fs_give:");
if (call_portal(swap_id, NULL, 0) >= 0) {
printf("fs_swap(NULL) did not fail as expected\n");
task_exit(1);
}
get_error(msg);
printf("expected error message from fs_swap(NULL): %s\n", msg);
if (call_portal(swap_id, &shared_flag, 0) >= 0) {
printf("fs_swap(<data area>) did not fail as expected\n");
task_exit(1);
}
get_error(msg);
printf("expected error message from fs_swap(<data area>): %s\n", msg);
if (call_portal(swap_id, p1, 0) >= 0) {
printf("fs_swap(p1) did not fail as expected\n");
task_exit(1);
}
get_error(msg);
printf("expected error message from fs_swap(p1): %s\n", msg);
if (call_portal(swap_id, p2, 0) < 0)
panic("fs_swap(p2):");
pp = (int *)call_portal(take_id, 0);
if (pp == (int *)-1)
panic("fs_take:");
if (pp != p1) {
printf("fs_take returned %p; expected %p\n", pp, p1);
task_exit(1);
}
printf("checking contents of swapped pages\n");
check_mem(p1, (int)p2, sz);
check_mem(p2, (int)p1, sz);
/* test page share */
if (call_portal(share_id, p3) < 0)
panic("fs_share(p3):");
/* verify that page is available now in the fs domain */
printf("checking page contents after sharing with fs domain\n");
for (i = 0; i < sz; i += sizeof(int)) {
code = call_portal(peek_id, (int)p3 + i);
if (code != ~((int)p3+i)) {
printf("fs_peek failed: addr=%p value=%d expected=%d\n",
(int *)((int)p3 + i), code, ~((int)p3 + i));
task_exit(1);
}
}
printf("correct shared page contents when accessed from fs domain\n");
if (call_portal(set_id, p3, ~0) < 0)
panic("fs_set(p3, 0):");
if (*p3 != ~0) {
printf("fs_set failed: addr=%p value=%d expected=%d\n",
p3, *p3, ~0);
task_exit(1);
}
printf("fs_set succeeded\n");
if (call_portal(unmap_id, p3) < 0)
panic("fs_unmap(p3):");
if (call_portal(unmap_id, p3) >= 0) {
printf("2nd fs_unmap(%p) did not fail as expected\n", p3);
task_exit(1);
}
get_error(msg);
printf("expected error message from 2nd fs_unmap(p3): %s\n", msg);
if (vm_unmap_page(p3) >= 0) {
printf("vm_unmap_page(%p) did not fail as expected\n", p3);
task_exit(1);
}
get_error(msg);
printf("expected error message from vm_unmap_page(p3): %s\n", msg);
/* test vm_unmap_page() when page is shared twice with fs domain */
if (call_portal(share_id, p3) < 0)
panic("1st fs_share(p3):");
if (call_portal(share_id, p3) < 0)
panic("2nd fs_share(p3):");
if ((code = vm_count_page(p3)) < 0)
panic("vm_count_page(p3) failed:");
if (code != 1) {
printf("vm_count_page(%p) returns %d; expected 1\n", p3, code);
task_exit(1);
}
if ((code = call_portal(count_id, p3)) < 0)
panic("fs_count(p3) failed:");
if (code != 2) {
printf("fs_count(%p) returns %d; expected 2\n", p3, code);
task_exit(1);
}
printf("fs_count(p3) after two sharing with fs is %d\n", code);
if (vm_unmap_page(p3) < 0)
panic("vm_unmap_page(p3):");
printf("vm_unmap_page(p3) successful\n");
if (vm_count_page(p3) >= 0) {
printf("vm_count_page(%p) did not fail as expected\n", p3);
task_exit(1);
}
/* can unmap only once, since page is shared twice with fs domain */
if (call_portal(unmap_id, p3) < 0)
panic("1st fs_unmap(p3):");
if ((code = call_portal(count_id, p3)) < 0)
panic("fs_count(p3) failed:");
if (code != 1) {
printf("fs_count(%p) returns %d; expected 1\n", p3, code);
task_exit(1);
}
if (call_portal(unmap_id, p3) >= 0) {
printf("2nd fs_unmap(%p) did not fail as expected\n", p3);
task_exit(1);
}
get_error(msg);
printf("expected error message from 2nd fs_unmap(p3): %s\n", msg);
printf("page count/give/take/swap/share/set/unmap is successful\n\n");
npages = MEM/sz;
for (i = 0; i < npages; i++) {
if ((v[i] = (void *)malloc(sz)) == NULL)
panic("malloc:");
/* to force loading TLB entry */
memset((char *)v[i], 0, sz);
}
/* time page give with prior access */
start = hrtime();
for (i = 0; i < npages; i++)
if (call_portal(give_id, v[i], i) < 0)
panic("fs_give:");
elapsed = 2*(hrtime() - start) - (loop_overhead * npages) / N;
printf("elapsed cycles of %d page give (with TLB erase) is %d\n",
i, (int)elapsed);
printf("each page give (with TLB erase): %d cycles\n",
(int)(elapsed+npages/2)/npages);
/* force loading TLB entry in fs domain */
for (i = 0; i < npages; i++)
call_portal(peek_id, v[i]);
start = hrtime();
for (i = 0; i < npages; i++)
if (call_portal(swap_id, p1, i) < 0)
panic("fs_swap:");
elapsed = 2*(hrtime() - start) - (npages * loop_overhead) / N;
printf("elapsed cycles of %d page swaps (with TLB erase) is %d\n",
i, (int)elapsed);
printf("each page swap (with TLB erase): %d cycles\n",
(int)(elapsed+npages/2)/npages);
/* force loading TLB entry in fs domain */
for (i = 0; i < npages; i++)
call_portal(peek_id, v[i]);
/* time page take with prior access */
start = hrtime();
for (i = 0; i < npages; i++) {
q = (void *)call_portal(take_id, i);
if (v[i] != q) {
printf("fs take failed. returned %p expected %p\n",
q, v[i]);
task_exit(1);
}
}
elapsed = 2*(hrtime() - start) - (npages * loop_overhead) / N;
printf("elapsed cycles of %d page take (with TLB erase) is %d\n",
i, (int)elapsed);
printf("each page take (with TLB erase): %d cycles\n",
(int)(elapsed+npages/2)/npages);
/* time page give w/out prior access */
start = hrtime();
for (i = 0; i < npages; i++)
if (call_portal(give_id, v[i], i) < 0)
panic("fs_give:");
elapsed = 2*(hrtime() - start) - (npages * loop_overhead) / N;
printf("elapsed cycles of %d page give (w/out TLB erase) is %d\n",
i, (int)elapsed);
printf("each page give (w/out TLB erase): %d cycles\n",
(int)(elapsed+npages/2)/npages);
/* time page take w/out prior access */
start = hrtime();
for (i = 0; i < npages; i++) {
q = (void *)call_portal(take_id, i);
if (v[i] != q) {
printf("fs take failed. returned %p expected %p\n",
q, v[i]);
task_exit(1);
}
}
elapsed = 2*(hrtime() - start) - (npages * loop_overhead) / N;
printf("elapsed cycles of %d page take (w/out TLB erase) is %d\n",
i, (int)elapsed);
printf("each page take (w/out TLB erase): %d cycles\n",
(int)(elapsed+npages/2)/npages);
printf("\n");
}
void
cond_barrier_init(Cond_Barrier *cb)
{
cond_init(&cb->cond);
cb->count = cb->version = 0;
mutex_init(&cb->lock, MUTEX_ERRORCHECK);
}
void
cond_barrier(Cond_Barrier *cb, int i, int n)
{
vlong old_version;
mutex_lock_safe(&cb->lock, "lock barrier");
cb->count++;
if (cb->count < n) {
old_version = cb->version;
do {
if (cond_wait(&cb->cond, &cb->lock) < 0)
panic("cond_barrier: cond_wait failed:");
} while (cb->version == old_version);
} else {
cb->count = 0;
cb->version++;
if (cond_broadcast(&cb->cond) < 0)
panic("cond_barrier: cond_broadcast failed:");
}
mutex_unlock_safe(&cb->lock, "unlock barrier");
}
void
chan_init(Chan *c)
{
mutex_init(&c->lock, MUTEX_ERRORCHECK);
cond_init(&c->cond);
c->head = c->tail = NULL;
}
/* put a value in a channel which can obtained later by */
/* cond_get() or cond_tget() */
void
cond_put(Chan *c, int val)
{
Elem *e;
if ((e = (Elem *)malloc(sizeof(Elem))) == NULL)
panic("cond_put: malloc failed:");
e->val = val;
e->next = NULL;
mutex_lock_safe(&c->lock, "cond_put: lock channel");
if (c->tail != NULL)
c->tail->next = e;
else
c->head = e;
c->tail = e;
if (cond_signal(&c->cond) < 0)
panic("cond_put: cond_signal failed:");
mutex_unlock_safe(&c->lock, "cond_put: unlock channel");
}
/* get a value from a channel without timeout (blocking) */
int
cond_get(Chan *c)
{
Elem *e;
int val;
mutex_lock_safe(&c->lock, "cond_get: lock channel");
while ((e = c->head) == NULL) {
if (cond_wait(&c->cond, &c->lock) < 0)
panic("cond_get: cond_wait %p failed:", &c->cond);
}
c->head = e->next;
if (e->next == NULL)
c->tail = NULL;
mutex_unlock_safe(&c->lock, "cond_get: unlock channel");
val = e->val;
free(e);
return val;
}
/* get a value from a channel with timeout */
int
cond_tget(Chan *c, Time t)
{
Elem *e = NULL;
int val;
mutex_lock_safe(&c->lock, "cond_tget: lock channel");
if ((e = c->head) == NULL) {
if (cond_twait(&c->cond, &c->lock, t) >= 0)
e = c->head;
}
if (e != NULL) {
c->head = e->next;
if (e->next == NULL)
c->tail = NULL;
}
mutex_unlock_safe(&c->lock, "cond_tget: unlock channel");
if (e != NULL) {
val = e->val;
free(e);
return val;
} else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?