Add a stat member to devsw and a sampstat function

上级 1258b4c3
......@@ -53,6 +53,7 @@ struct inode : public rcu_freed {
struct devsw {
int (*read)(struct inode*, char*, u32, u32);
int (*write)(struct inode*, char*, u32, u32);
void (*stat)(struct inode*, struct stat*);
};
extern struct devsw devsw[];
......
......@@ -529,6 +529,14 @@ itrunc(struct inode *ip)
void
stati(struct inode *ip, struct stat *st)
{
if(ip->type == T_DEV){
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].stat)
memset(st, 0, sizeof(*st));
else
devsw[ip->major].stat(ip, st);
return;
}
st->dev = ip->dev;
st->ino = ip->inum;
st->type = ip->type;
......
......@@ -29,36 +29,6 @@ conf(int fd, sampop_t op)
close(fd);
}
static void
save(void)
{
static char buf[4096];
int fd, sfd;
int r;
fd = open("/dev/sampler", O_RDONLY);
if (fd < 0)
die("perf: open failed");
unlink("perf.data");
sfd = open("perf.data", O_RDWR|O_CREATE);
if (sfd < 0)
die("perf: open failed");
while (1) {
r = read(fd, buf, sizeof(buf));
if (r < 0)
die("perf: read failed");
if (r == 0)
break;
if (write(sfd, buf, r) != r)
die("perf: truncated write");
}
close(sfd);
close(fd);
}
int
main(int ac, const char *av[])
{
......@@ -78,6 +48,5 @@ main(int ac, const char *av[])
wait();
conf(fd, SAMP_DISABLE);
save();
exit();
}
......@@ -11,7 +11,7 @@
int
main(int ac, char **av)
{
static const char *pathname = "perf.data";
static const char *pathname = "sampler";
struct logheader *header;
struct stat buf;
void *x;
......
......@@ -4,6 +4,7 @@ extern "C" {
#include "condvar.h"
#include "fs.h"
#include "kernel.h"
#include "stat.h"
}
#include "file.hh"
......@@ -15,6 +16,9 @@ extern "C" {
#include "sampler.h"
}
#define LOGHEADER_SZ (sizeof(struct logheader) + \
sizeof(((struct logheader*)0)->cpu[0])*NCPU)
static volatile u64 selector;
static volatile u64 period;
......@@ -153,20 +157,36 @@ readlog(char *dst, u32 off, u32 n)
return ret;
}
static void
sampstat(struct inode *ip, struct stat *st)
{
struct pmulog *q = &pmulog[NCPU];
struct pmulog *p;
u64 sz = 0;
sz += LOGHEADER_SZ;
for (p = &pmulog[0]; p != q; p++)
sz += p->count * sizeof(struct pmuevent);
st->dev = ip->dev;
st->ino = ip->inum;
st->type = ip->type;
st->nlink = ip->nlink;
st->size = sz;
}
static int
sampread(struct inode *ip, char *dst, u32 off, u32 n)
{
struct pmulog *q = &pmulog[NCPU];
struct pmulog *p;
struct logheader *hdr;
u64 hdrlen;
int ret;
int i;
ret = 0;
hdrlen = sizeof(*hdr) + sizeof(hdr->cpu[0])*NCPU;
if (off < hdrlen) {
u64 len = hdrlen;
if (off < LOGHEADER_SZ) {
u64 len = LOGHEADER_SZ;
u64 cc;
hdr = (logheader*) kmalloc(len);
......@@ -182,7 +202,7 @@ sampread(struct inode *ip, char *dst, u32 off, u32 n)
i++;
}
cc = MIN(hdrlen-off, n);
cc = MIN(LOGHEADER_SZ-off, n);
memmove(dst, (char*)hdr + off, cc);
kmfree(hdr);
......@@ -192,8 +212,8 @@ sampread(struct inode *ip, char *dst, u32 off, u32 n)
dst += cc;
}
if (off >= hdrlen)
ret += readlog(dst, off-hdrlen, n);
if (off >= LOGHEADER_SZ)
ret += readlog(dst, off-LOGHEADER_SZ, n);
return ret;
}
......@@ -257,4 +277,5 @@ initsamp(void)
devsw[SAMPLER].write = sampwrite;
devsw[SAMPLER].read = sampread;
devsw[SAMPLER].stat = sampstat;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论