lat_interpose.c
来自「pebble」· C语言 代码 · 共 167 行
C
167 行
/*
* 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.
*
*/
/*
* Test system call interposition
*/
#include "pebble.h"
#include "unistd.h"
#include "types.h"
#include "time.h"
#include "synch.h"
#include "perfcount.h"
#define N 10000
static int sem_id1, sem_id2;
static int child_asid;
static int count[NPORTALS];
void
dump_counters(void)
{
int i;
for (i = 0; i < NPORTALS; i++)
if (count[i] > 0)
printf("portal %d called %d times\n", i, count[i]);
}
int
intercept(int id, int p1, int p2, int p3, int p4, int p5)
{
count[id]++;
if (id == SYS_EXIT) {
dump_counters();
printf("child domain of lat_interpose ended\n");
}
return call_portal(id, p1, p2, p3, p4, p5);
}
int
notify(int asid, int id, char *template)
{
char s[NAMELEN];
printf("portal table changed: asid=%d id=%d template=%s\n",
asid, id, template);
/* create a new portal from the child to the parent with a modified */
/* template */
sprintf(s, "sm#%s", template+3);
portal_create_child(child_asid, id, s, 0, intercept);
return 0;
}
void
measure(void)
{
int code;
int i, perf_ix;
uvlong start, elapsed;
uint perf_count;
/* create semaphores with initial value 0 */
if ((sem_id1 = sem_create(0)) < 0)
panic("sem_create:");
if ((sem_id2 = sem_create(0)) < 0)
panic("sem_create:");
/* create a new thread in the same domain */
if ((code = fork()) < 0)
panic("fork:");
if (code == 0) {
/* child thread */
/* wake up parent */
if (sem_post(sem_id1) < 0)
panic("sem_post:");
for (i = 0;; i++) {
if (sem_wait(sem_id2) < 0)
panic("sem_wait:");
if (sem_post(sem_id1) < 0)
panic("sem_post:");
}
/* never reached */
task_exit(1);
}
/* parent waits for the child to wake up */
if (sem_wait(sem_id1) < 0)
panic("sem_wait:");
for (perf_ix = 0; perf_vec[perf_ix].name != NULL; perf_ix++) {
/* time semphore ping-pong with child */
set_perf_ctrl(perf_vec[perf_ix].ctrl);
start = hrtime();
for (i = 0; i < N; i++) {
if (sem_post(sem_id2) < 0)
panic("sem_post:");
if (sem_wait(sem_id1) < 0)
panic("sem_wait:");
}
perf_count = get_perf_count();
elapsed = 2*(hrtime() - start);
printf("============\n");
printf("elapsed time %d cycles\n", (int)elapsed);
printf("each iteration took %d cycles\n", (int)(elapsed/N));
printf("%s: %d\n", perf_vec[perf_ix].name, perf_count);
}
}
int
main(void)
{
printf("lat_interpose benchmark starting\n");
printf("two threads in the same domain without interposition:\n");
measure();
if (portal_notify(notify) < 0)
panic("portal_notify:");
/* from this place and on, the parent will be notified if a new portal */
/* is generated in its portals table for any reason. */
if ((child_asid = domain_fork(intercept)) < 0)
panic("domain_fork:");
if (child_asid == 0) {
/* child domain */
measure();
task_exit(0);
}
/* parent waits forever */
while(1)
sem_wait(sem_id1);
printf("lat_interpose ended\n");
task_exit(0);
return(1);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?