Fill in wq_for, but a race lurks somewhere..

上级 cc29cea9
......@@ -23,8 +23,7 @@ UPROGS= \
preadtest \
scripttest \
ftest \
perf \
xdu
perf
# pdu
# pls
......
......@@ -42,6 +42,7 @@ du(int fd)
return 0;
}
// XXX(sbw) size should use an add reducer
int size = ST_SIZE(st);
if (ST_ISDIR(st)) {
dirit di(fd);
......@@ -69,6 +70,7 @@ du(int fd)
int
main(int ac, char **av)
{
initwq();
printf("%d\n", du(open(".", 0)));
return 0;
}
#pragma once
#if defined(LINUX)
#include <stdlib.h>
#include <assert.h>
#include <atomic>
#define xmalloc(n) malloc(n)
#define xfree(p, sz) free(p)
#elif defined(XV6_KERNEL)
#define xmalloc(n) kmalloc(n)
#define xfree(p, sz) kmfree(p, sz)
#else
#warning "Unknown wq implementation"
#endif
#define WQSIZE 8192
class work;
int wq_trywork(void);
......@@ -9,7 +25,7 @@ struct work {
virtual void run() = 0;
};
struct cwork : public work{
struct cwork : public work {
virtual void run();
static void* operator new(unsigned long);
......@@ -24,12 +40,58 @@ struct cwork : public work{
void *arg4;
};
typedef std::atomic<int> forframe_t;
template <typename IT, typename BODY>
struct forwork : public work {
forwork(IT &it, bool (*cond)(IT &it), BODY &body, forframe_t &frame)
: it_(it), cond_(cond), body_(body), frame_(frame) {}
virtual void run() {
decltype(*it_) v = *it_;
++it_;
if (cond_(it_)) {
forwork<IT, BODY> *w = new forwork<IT, BODY>(it_, cond_, body_, frame_);
++frame_;
wq_push(w);
}
body_(v);
--frame_;
delete this;
}
static void* operator new(unsigned long nbytes) {
assert(nbytes == sizeof(forwork<IT, BODY>));
return xmalloc(sizeof(forwork));
}
static void operator delete(void*p) {
xfree(p, sizeof(forwork));
}
IT &it_;
bool (*cond_)(IT&);
BODY &body_;
forframe_t &frame_;
};
template <typename IT, typename BODY>
static inline void
wq_for(IT &init, bool (*cond)(IT &it), BODY body)
{
forframe_t frame(0);
// XXX(sbw) should be able to coarsen loop
for (IT &it = init; cond(it); ++it) {
body(*it);
decltype(*init) v = *init;
++init;
if (cond(init)) {
forwork<IT, BODY> *w = new forwork<IT, BODY>(init, cond, body, frame);
++frame;
wq_push(w);
}
body(v);
while (frame != 0)
wq_trywork();
}
......@@ -44,5 +44,3 @@ wqarch_init(void)
}
#define xprintf cprintf
#define xmalloc(n) kmalloc(n)
#define xfree(p, sz) kmfree(p, sz)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论