In progress userspace wq and du stuff

上级 9ba75050
......@@ -6,71 +6,28 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include "include/wq.hh"
#include "user/dirit.hh"
#define ST_SIZE(st) (st).st_size
#define ST_ISDIR(st) S_ISDIR((st).st_mode)
#define BSIZ 256
typedef DIR* dir_t;
static inline int getdent(dir_t d, char *buf, size_t n)
{
struct dirent *entryp, *result;
char *dbuf[512];
int r;
entryp = (struct dirent *)dbuf;
r = readdir_r(d, entryp, &result);
if (r == 0 && result != NULL) {
strcpy(buf, entryp->d_name);
return 0;
}
return -1;
}
#else // assume xv6
#include "types.h"
#include "stat.h"
#include "user.h"
#include "lib.h"
#include "fs.h"
#include "wq.hh"
#include "dirit.hh"
#define ST_SIZE(st) (st).size
#define ST_ISDIR(st) ((st).type == T_DIR)
#define stderr 2
#define BSIZ (DIRSIZ+1)
typedef int dir_t;
static inline dir_t
fdopendir(int fd) {
return fd;
}
static inline void
closedir(dir_t d) {
}
static inline int
getdent(dir_t fd, char *buf, size_t n)
{
struct dirent de;
int r;
again:
r = read(fd, &de, sizeof(de));
if (r == sizeof(de)) {
if (de.inum == 0)
goto again;
memmove(buf, de.name, n-1);
buf[n-1] = 0;
return 0;
}
return -1;
}
#endif
static int
......@@ -85,17 +42,21 @@ du(int fd)
int size = ST_SIZE(st);
if (ST_ISDIR(st)) {
char buf[BSIZ];
dir_t d = fdopendir(fd);
while (getdent(d, buf, BSIZ) == 0) {
dirit di(fd);
wq_for<dirit>(di,
[](dirit &i)->bool { return !i.end(); },
[&](dirit &i)->void
{
char buf[BSIZ];
i.name(buf, BSIZ);
if (!strcmp(buf, ".") || !strcmp(buf, ".."))
continue;
return;
int nfd = openat(fd, buf, 0);
if (nfd >= 0)
size += du(nfd); // should go into work queue
}
closedir(d);
});
}
close(fd);
......
class dirit {
public:
dirit(int fd) : fd_(fd), end_(false) {
refill();
}
dirit& operator ++() {
refill();
return *this;
}
bool end() const { return end_; }
char *name(char *buf, size_t n) const {
n = MIN(DIRSIZ+1, n);
memmove(buf, de_.name, n-1);
buf[n-1] = 0;
return buf;
}
private:
void refill(void) {
int r;
again:
r = read(fd_, &de_, sizeof(de_));
if (r == sizeof(de_)) {
if (de_.inum == 0)
goto again;
} else {
end_ = true;
}
}
int fd_;
bool end_;
struct dirent de_;
};
......@@ -7,3 +7,12 @@ struct work {
void *arg4;
char data[];
};
template <typename IT, typename BODY>
static inline void
wq_for(IT &init, bool (*cond)(IT &it), BODY body) {
for (IT &it = init; cond(it); ++it) {
body(it);
}
}
NCXXFLAGS = -static -g -MD -m64 -O3 -Wall -Werror -DHW_$(HW) -DXV6 \
-fno-builtin -fno-strict-aliasing -fno-omit-frame-pointer \
-fms-extensions -mno-sse -mcx16 -mno-red-zone -std=c++0x \
-Wno-sign-compare -fno-exceptions -fno-rtti -fcheck-new -I.
$(O)/user/%.o: bin/%.cc
@echo " CXX $@"
$(Q)mkdir -p $(@D)
$(Q)$(CXX) -DLINUX $(NCXXFLAGS) -c -o $@ $<
$(O)/xdu: $(O)/user/xdu.o
@echo " LD $@"
$(Q)mkdir -p $(@D)
$(Q)$(CXX) -o $@ $^ -lpthread
.PRECIOUS: $(O)/user/%.o
-include $(O)/user/*.d
#include <sys/types.h>
#include <dirent.h>
class dirit {
public:
dirit(int fd) : fd_(fd), end_(false) {
d_ = fdopendir(fd);
ent_ = (struct dirent*)ebuf_;
refill();
}
dirit& operator ++() {
refill();
return *this;
}
bool end() const { return end_; }
char *name(char *buf, size_t n) const {
strncpy(buf, ent_->d_name, n-1);
buf[n-1] = 0;
return buf;
}
private:
void refill(void) {
struct dirent *result;
int r = readdir_r(d_, ent_, &result);
if (r != 0 || result == NULL)
end_ = true;
}
int fd_;
bool end_;
char *ebuf_[512];
struct dirent *ent_;
DIR *d_;
};
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论