Fill in wq_for, but a race lurks somewhere..

上级 cc29cea9
...@@ -23,8 +23,7 @@ UPROGS= \ ...@@ -23,8 +23,7 @@ UPROGS= \
preadtest \ preadtest \
scripttest \ scripttest \
ftest \ ftest \
perf \ perf
xdu
# pdu # pdu
# pls # pls
......
...@@ -42,6 +42,7 @@ du(int fd) ...@@ -42,6 +42,7 @@ du(int fd)
return 0; return 0;
} }
// XXX(sbw) size should use an add reducer
int size = ST_SIZE(st); int size = ST_SIZE(st);
if (ST_ISDIR(st)) { if (ST_ISDIR(st)) {
dirit di(fd); dirit di(fd);
...@@ -69,6 +70,7 @@ du(int fd) ...@@ -69,6 +70,7 @@ du(int fd)
int int
main(int ac, char **av) main(int ac, char **av)
{ {
initwq();
printf("%d\n", du(open(".", 0))); printf("%d\n", du(open(".", 0)));
return 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 #define WQSIZE 8192
class work; class work;
int wq_trywork(void); int wq_trywork(void);
...@@ -9,7 +25,7 @@ struct work { ...@@ -9,7 +25,7 @@ struct work {
virtual void run() = 0; virtual void run() = 0;
}; };
struct cwork : public work{ struct cwork : public work {
virtual void run(); virtual void run();
static void* operator new(unsigned long); static void* operator new(unsigned long);
...@@ -24,12 +40,58 @@ struct cwork : public work{ ...@@ -24,12 +40,58 @@ struct cwork : public work{
void *arg4; 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> template <typename IT, typename BODY>
static inline void static inline void
wq_for(IT &init, bool (*cond)(IT &it), BODY body) wq_for(IT &init, bool (*cond)(IT &it), BODY body)
{ {
forframe_t frame(0);
// XXX(sbw) should be able to coarsen loop // 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) ...@@ -44,5 +44,3 @@ wqarch_init(void)
} }
#define xprintf cprintf #define xprintf cprintf
#define xmalloc(n) kmalloc(n)
#define xfree(p, sz) kmfree(p, sz)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论