app1.c
来自「pebble」· C语言 代码 · 共 2,046 行 · 第 1/4 页
C
2,046 行
task_exit(1);
}
printf("correct shared memory contents from both domains\n");
printf("testing mutual exclusion locks in shared region\n");
mutex_init((Lock *)addr, MUTEX_ERRORCHECK);
if (mutex_trylock((Lock *)addr) < 0) {
printf("mutex_trylock failed; expected to succeed\n");
task_exit(1);
}
if (mutex_trylock((Lock *)addr) >= 0) {
printf("mutex_trylock succeeded; expected to fail\n");
task_exit(1);
}
if (call_portal(try_id, addr) >= 0) {
printf("fs trylock succeeded; expected to fail\n");
task_exit(1);
}
mutex_unlock((Lock *)addr);
if (call_portal(try_id, addr) < 0) {
printf("fs trylock failed; expected to succceed\n");
task_exit(1);
}
if (call_portal(try_id, addr) >= 0) {
printf("fs trylock succeeded; expected to fail\n");
task_exit(1);
}
if (mutex_trylock((Lock *)addr) >= 0) {
printf("mutex_trylock succeeded; expected to fail\n");
task_exit(1);
}
printf("check access to shared memory region in a child domain\n");
if ((s1 = sem_create(0)) < 0)
panic("sem_create:");
if ((s2 = sem_create(0)) < 0)
panic("sem_create:");
set_mem(addr, sz);
if ((code = domain_fork(NULL)) < 0)
panic("domain_fork:");
if (code == 0) {
/* child */
check_mem(addr, (int)addr, sz);
printf("child domain accessed shared region successfully\n");
/* wakeup parent */
sem_post(s1);
/* sleep forever */
sem_wait(s2);
}
sem_wait(s1);
printf("shared memory test ended successfully\n\n");
}
void
test_sem(void)
{
int s;
int s1, s2, i, j;
Time start, elapsed;
printf("testing semaphores\n");
if ((s = sem_open("fs_sem")) < 0)
panic("sem_open(fs_sem):");
sem_wait(s);
s1 = sem_create(0);
s2 = sem_create(0);
if (s1 < 0 || s2 < 0)
panic("sem_create:");
printf("created semaphores: s1=%d s2=%d\n", s1, s2);
printf("sem_post(%d) returns %d\n", s1, sem_post(s1));
printf("sem_wait(%d) returns %d\n", s1, sem_wait(s1));
start = hrtime();
sem_twait(s1, start + sec2ticks());
elapsed = hrtime() - start;
printf("sem_twait() for 1 second waited %u clock ticks; expected %u clock ticks\n",
(int)elapsed, (int)sec2ticks());
if (elapsed > (5*sec2ticks())/4)
panic("sem_twait() waited significantly more than one second");
start = hrtime();
sem_post(s1);
sem_twait(s1, start + sec2ticks());
elapsed = hrtime() - start;
printf("sem_twait() on an available semaphore waited %u clock ticks\n",
(int)elapsed);
if (elapsed > sec2ticks()/1000)
panic("sem_twait() on an available semphore took too long");
start = hrtime();
for (i = 0; i < N; i++) {
sem_post(s2);
sem_wait(s2);
}
elapsed = 2*(hrtime() - start) - loop_overhead;
printf("elapsed cycles of %d sem_wait/sem_post pairs is %d\n", i,
(int)elapsed);
printf("each sem_wait/sem_post pair: %d cycles\n\n",
(int)(elapsed+N/2)/N);
printf("before fork: parent status=%08lx stack at %p\n",
get_psw(), &j);
if (fork() == 0) {
printf("after fork: child status=%08lx stack at %p\n",
get_psw(), &j);
printf("the child asid=%d calling rpc1\n", get_asid());
printf("portal(%d,3)=%d\n", rpc1, call_portal(rpc1, 3));
do {
printf("shared_flag=%d\n", shared_flag);
yield();
} while(shared_flag == 0);
printf("child: shared_flag=%d\n", shared_flag);
/* semaphore ping-pong with parent */
printf("child before semaphore ping-pong\n");
for (i = 0; i < N; i++) {
sem_post(s1);
sem_wait(s2);
}
/* child waits forever */
sem_wait(s2);
}
printf("after fork: parent status=%08lx stack at %p\n",
get_psw(), &j);
yield();
shared_flag = 1;
yield();
printf("parent before semaphore ping-pong\n");
start = hrtime();
for (i = 0; i < N; i++) {
sem_wait(s1);
sem_post(s2);
}
elapsed = 2*(hrtime() - start) - loop_overhead;
printf("elapsed cycles of %d sem_wait/sem_post with child is %d\n", i,
(int)elapsed);
printf("each sem_wait/sem_post with child: %d cycles\n",
(int)(elapsed+N/2)/N);
printf("semaphore test ended successfully\n\n");
}
void
measure_timeout(char *test_name, int keep_event[])
{
Time now, max_delay, start_idle, elapsed_idle, expected_idle;
Time first_event, latest_event;
int i;
Time usec2ticks = sec2ticks() / SEC2USEC;
printf("starting %s test\n", test_name);
/* compute the largest expected delay */
latest_event = when[0];
first_event = when[0];
for (i = 1; i < M; i++) {
if (when[i] < first_event)
first_event = when[i];
if (when[i] > latest_event)
latest_event = when[i];
}
/* generate M timeout events */
start_idle = idle_time();
now = hrtime();
if (first_event < now)
panic("measure_timeout: first event=%u %u now=%u %u\n",
(int)(first_event >> 32), (int)first_event,
(int)(now >> 32), (int)now);
usec2ticks = sec2ticks() / SEC2USEC;
/* generate the M timeout events */
for (i = 0; i < M; i++) {
timeout_flag[i] = 0;
if (timeout(tout, (void*)i, when[i]) < 0) {
printf("timeout(%d) failed\n", i);
task_exit(1);
}
/* allow timeout thread to run after generating each timeout event */
usleep((first_event - now) / ((M+1)*usec2ticks));
}
/* cancel the requested events */
for (i = 0; i < M; i++) {
if (keep_event[i])
continue;
if (untimeout(tout, (void*)i, when[i]) < 0) {
printf("untimeout(%d) failed\n", i);
task_exit(1);
}
}
/* wait until all timeout events have occured */
hrsleep(latest_event + sec2ticks());
expected_idle = (latest_event + sec2ticks()) - now;
/* verify that the timeouts have occured on time */
elapsed_idle = idle_time() - start_idle;
max_delay = 0;
for (i = 0; i < M; i++) {
printf("timeout event %d @ %u %u \n",
i, (int)(when[i] >> 32), (int)when[i]);
if (timeout_flag[i])
printf("called with delay of %u ticks\n",
(int)timeout_delay[i]);
else
printf("not called\n");
if (timeout_flag[i] != keep_event[i]) {
printf("timeout_flag[%d] is %d. should be %d\n",
i, timeout_flag[i], keep_event[i]);
task_exit(1);
}
if (timeout_delay[i] > max_delay)
max_delay = timeout_delay[i];
}
printf("idle time during %s test: %u %u ticks; expected %u %u ticks\n",
test_name,
(int)(elapsed_idle >> 32), (int)elapsed_idle,
(int)(expected_idle >> 32), (int)expected_idle);
printf("maximal timeout delay during %s test: %u %u ticks\n",
test_name, (int)(max_delay >> 32), (int)max_delay);
if (max_delay > sec2ticks()/1000)
panic("*** %s test failed ***\n\n", test_name);
else
printf("%s test passed successfully\n\n", test_name);
}
void
test_timeout(void)
{
Time now;
int i;
Time s2ticks = sec2ticks();
int keep_event[M];
/* increasing timeout test */
now = hrtime();
for (i = 0; i < M; i++) {
when[i] = now + s2ticks + (s2ticks * i) / M;
keep_event[i] = 1;
}
measure_timeout("increasing timeout", keep_event);
/* decreasing timeout test */
now = hrtime();
for (i = 0; i < M; i++) {
when[i] = now + 2*s2ticks - (s2ticks * i) / M;
keep_event[i] = 1;
}
measure_timeout("decreasing timeout", keep_event);
/* generate M random timeout events, waiting between a second and two */
now = hrtime();
random(); /* get the first random number */
/* none of the timeout events has occurred yet, since they all */
/* start at least one second after "now" */
/* cancel every second timeout event */
for (i = 0; i < M; i++) {
when[i] = now + s2ticks + ((Time)random() % s2ticks);
keep_event[i] = i & 01;
}
measure_timeout("random timeout with event deletions", keep_event);
}
void
printenv(const char *name)
{
char val[NAMELEN];
if (get_env(name, val) < 0)
printf("environment variable %s not defined\n", name);
else
printf("environment variable %s = %s\n", name, val);
}
int
main(int arg, char *argv[])
{
int i, code;
int fd;
int last_time;
volatile int *q, *u;
Time start, elapsed;
Time start_usec, elapsed_usec;
char msg[NAMELEN];
printf("hello, world! arg=%d\n", arg);
printf("hr_count=%d psw=%08lx asid=%d\n",
(int)hrtime(), get_psw(), get_asid());
if ((code = get_caller_asid(0)) != get_asid())
panic("get_caller_asid(0) returned %d; expected %d :",
code, get_asid());
printf("initial TLB miss count=%d general exceptions count=%d\n",
get_tlb_excpt_count(), get_gen_excpt_count());
test_mod(1622650073);
test_idle();
printenv("hostname");
printenv("netaddr");
printenv("netmask");
printf("initial error msg=%s\n", msg);
printf("fd_open(\"?\")=%d\n", fd_open("?"));
get_error(msg);
printf("error msg=%s\n", msg);
printf("calling portal(0)\n");
code = call_portal(0);
if (code >= 0)
panic("call_portal(0) did not fail!");
get_error(msg);
printf("code=%d error msg=%s\n", code, msg);
printf("calling portal(-1)\n");
code = call_portal(-1);
if (code >= 0)
panic("call_portal(-1) did not fail!");
get_error(msg);
printf("code=%d error msg=%s\n", code, msg);
printf("calling portal(too large)\n");
code = call_portal(NPORTALS);
if (code >= 0)
panic("call_portal(NPORTALS) did not fail!");
get_error(msg);
printf("code=%d error msg=%s\n", code, msg);
/* The following yield allows the fs thread to run, so that */
/* if the debug messages are enabled, they do not appear AFTER */
/* the input prompt. Before this fix, you may miss the input prompt */
/* due to the lengthy debug messages that appear after it. */
yield();
printf("reading from console, type up to 64 chars\n");
fgets(msg, sizeof(msg), NULL);
printf("read %d chars, \"%s\" from console\n", strlen(msg), msg);
fd = 0;
printf("writing on LED display\n");
if ((fd = fd_open("led")) < 0)
panic("fd_open(led):");
if (write(fd, "d00d", 4) < 0)
panic("write:");
printf("task %d asid=%d defines rpc1 & rpc2\n", arg, get_asid());
if ((rpc1 = portal_create(-1, "smtiii", 0, &f, 0)) < 0)
panic("portal_create(rpc1):");
printf("task asid=%d portal_create(-1,\"smtiii\", 0, %p, 0) returns %d\n",
get_asid(), &f, rpc1);
if ((rpc2 = portal_create(-1, "smtiii", 0, &g, 0)) < 0)
panic("portal_create(rpc2):");
printf("task asid=%d portal_create(-1,\"smtiii\", 0, %p, 0) returns %d\n",
get_asid(), &g, rpc2);
start = hrtime();
for (i = 0; i < N; i++)
yield();
elapsed = 2*(hrtime() - start);
printf("elapsed cycles of %d yields is %d\n", i, (int)elapsed);
printf("each yield: %d cycles\n", (int)(elapsed+N/2)/N);
start = hrtime();
for (i = 0; i < N; i++)
;
loop_overhead = 2*(hrtime() - start);
printf("empty loop overhead %d iterations=%d cycles. should be %d\n",
i, (int)loop_overhead, i*3);
set_error(NULL);
printf("phys(NULL)=%p\n", virt2phys(NULL));
get_error(msg);
printf("expected error message=%s\n", msg);
set_error(NULL);
printf("&shared_flag=%p phys=%p\n",
&shared_flag, virt2phys(&shared_flag));
get_error(msg);
if (strlen(msg) != 0) {
printf("virt2phys(data address) failed. message=%s\n", msg);
task_exit(1);
}
set_error(NULL);
printf("&f=%p phys=%p\n",
&f, virt2phys(&f));
get_error(msg);
printf("expected error message=%s\n\n", msg);
printf("testing uncached access\n");
q = &shared_flag;
if ((u = (int *)uncached_window((void *)q)) == (int *)-1)
panic("uncached_window:");
printf("virt addr=%p phys addr=%p uncached addr=%p\n",
q, virt2phys((void *)q), u);
if (uncached_window((void *)q) != (void *)-1)
panic("second uncached_window did not fail");
get_error(msg);
printf("expected error from uncached_window: %s\n", msg);
*u = 0x12345678;
*q = 0xdeadbeef;
printf("before cache flush: virt mem=%08x uncached mem=%08x\n", *q, *u);
clean_cache((void *)q, sizeof(int));
if (*q != *u) {
printf("after cache flush: virt mem=%08x uncached mem=%08x\n",
*q, *u);
printf("*** uncached memory not equal to virtual memory ***\n");
task_exit(1);
}
printf("after cache flush: virt mem=%08x uncached mem=%08x\n\n",
*q, *u);
test_csd();
test_log();
test_malloc();
test_portal_alloc();
test_portal_window();
test_page_transfer();
last_time = time();
printf("current time() is %d\n", last_time);
while (time() < last_time + 10)
yield();
printf("time() after 10 seconds is %d\n\n", time());
test_mutex();
test_signal();
test_shm();
test_sem();
printf("the parent asid=%d before calling rpc1\n", get_asid());
printf("portal(%d,3)=%d\n",
rpc1, call_portal(rpc1, 3));
printf("task %d asid=%d before calling rpc2\n", arg, get_asid());
printf("portal(%d,4)=%d\n",
rpc2, call_portal(rpc2, 4));
start = hrtime();
for (i = 0; i < N; i++)
hrtime();
elapsed = 2*(hrtime() - start) - loop_overhead;
printf("elapsed time of %d hrtime=%d cycles\n", i, (int)elapsed);
printf("each hrtime: %d cycles\n", (int)(elapsed+N/2)/N);
printf("hrcount per second=%d\n", sec2ticks());
start = hrtime();
for (i = 0; i < N; i++)
uptime();
elapsed = 2*(hrtime() - start) - loop_overhead;
printf("elapsed time of %d uptime()=%d cycles\n", i, (int)elapsed);
printf("each uptime: %d cycles\n", (int)(elapsed+N/2)/N);
start_usec = uptime();
for (i = 0; i < N; i++)
uptime();
elapsed_usec = uptime() - start_usec;
printf("elapsed time of %d uptime()=%d usec.\n", i, (int)elapsed_usec);
printf("each uptime: %d usec.\n", (int)((elapsed_usec+N/2)/N));
for (i = 0; i < N; i++)
if (call_portal(rpc2, i) != -i)
printf("error in rpc2(%d)\n", i);
start = hrtime();
for (i = 0; i < N; i++)
call_portal(rpc2, i);
elapsed = 2*(hrtime() - start) - loop_overhead;
printf("elapsed time of %d rpc2=%d cycles\n", i, (int)elapsed);
printf("each RPC: %d cycles\n\n", (int)(elapsed+N/2)/N);
test_timeout();
printf("APP1 ENDING\n");
printf("parent domain asid=%d calling task exit\n", get_asid());
task_exit(0);
return(1);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?