XV6_USER wqs track q_ length in a user-kernel shared buffer

上级 702e5a07
#define KBASE 0xFFFFFF0000000000ull #define KBASE 0xFFFFFF0000000000ull
#define KCODE 0xFFFFFFFFC0000000ull #define KCODE 0xFFFFFFFFC0000000ull
#define KSHARED 0xFFFFF00000000000ull #define KSHARED 0xFFFFF00000000000ull
#define USERWQ 0xFFFFF00100000000ull #define USERWQLEN 0xFFFFF00100000000ull
#define USERTOP 0x0000800000000000ull #define USERTOP 0x0000800000000000ull
...@@ -11,6 +11,11 @@ typedef struct uspinlock wqlock_t; ...@@ -11,6 +11,11 @@ typedef struct uspinlock wqlock_t;
static pthread_key_t idkey; static pthread_key_t idkey;
static volatile int exiting; static volatile int exiting;
struct padded_length {
volatile u64 v_ __mpalign__;;
__padout__;
};
int int
mycpuid(void) mycpuid(void)
{ {
...@@ -20,11 +25,19 @@ mycpuid(void) ...@@ -20,11 +25,19 @@ mycpuid(void)
static inline void* static inline void*
allocwq(unsigned long nbytes) allocwq(unsigned long nbytes)
{ {
return malloc(nbytes);
}
static inline padded_length*
allocklen(unsigned long nbytes)
{
static bool alloced; static bool alloced;
if (alloced) if (alloced)
die("allocwq: allocing more than once"); die("allocklen: allocing more than once");
if (nbytes > USERWQSIZE)
die("allocklen: too large");
alloced = true; alloced = true;
return (void*)USERWQ; return (padded_length*)USERWQLEN;
} }
static inline void static inline void
......
...@@ -100,8 +100,8 @@ setupuvm(pgmap *pml4, char *kshared, char *uwq) ...@@ -100,8 +100,8 @@ setupuvm(pgmap *pml4, char *kshared, char *uwq)
char *uvm; char *uvm;
size_t size; size_t size;
} todo[] = { } todo[] = {
{ kshared, (char*)KSHARED, KSHAREDSIZE }, { kshared, (char*)KSHARED, KSHAREDSIZE },
{ uwq, (char*)USERWQ, PGROUNDUP(wq_size()) } { uwq, (char*)USERWQLEN, PGROUNDUP(wq_size()) }
}; };
for (int i = 0; i < NELEM(todo); i++) { for (int i = 0; i < NELEM(todo); i++) {
......
$(O)/lib/%.o: CFLAGS:=$(CFLAGS) $(O)/lib/%.o: CFLAGS:=$(CFLAGS) -DXV6_USER
$(O)/lib/%.o: CXXFLAGS:=$(CXXFLAGS) $(O)/lib/%.o: CXXFLAGS:=$(CXXFLAGS) -DXV6_USER
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \ ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \
threads.o crt.o wq.o perf.o threads.o crt.o wq.o perf.o
......
...@@ -21,6 +21,8 @@ public: ...@@ -21,6 +21,8 @@ public:
private: private:
work *steal(int c); work *steal(int c);
work *pop(int c); work *pop(int c);
void inclen(int c);
void declen(int c);
struct wqueue { struct wqueue {
work *w[NSLOTS]; work *w[NSLOTS];
...@@ -38,6 +40,10 @@ private: ...@@ -38,6 +40,10 @@ private:
percpu<wqueue> q_; percpu<wqueue> q_;
percpu<stat> stat_; percpu<stat> stat_;
#if defined(XV6_USER)
padded_length* len_;
#endif
}; };
static wq *wq_; static wq *wq_;
...@@ -103,6 +109,10 @@ wq::wq(void) ...@@ -103,6 +109,10 @@ wq::wq(void)
for (i = 0; i < NCPU; i++) for (i = 0; i < NCPU; i++)
wqlock_init(&q_[i].lock); wqlock_init(&q_[i].lock);
#if defined(XV6_USER)
len_ = allocklen(NCPU*sizeof(padded_length));
#endif
} }
void void
...@@ -115,6 +125,22 @@ wq::dump(void) ...@@ -115,6 +125,22 @@ wq::dump(void)
stat_[i].pop, stat_[i].steal); stat_[i].pop, stat_[i].steal);
} }
inline void
wq::inclen(int c)
{
#if defined(XV6_USER)
__sync_fetch_and_add(&len_[c].v_, 1);
#endif
}
inline void
wq::declen(int c)
{
#if defined(XV6_USER)
__sync_fetch_and_sub(&len_[c].v_, 1);
#endif
}
int int
wq::push(work *w) wq::push(work *w)
{ {
...@@ -131,6 +157,7 @@ wq::push(work *w) ...@@ -131,6 +157,7 @@ wq::push(work *w)
q_->w[i] = w; q_->w[i] = w;
barrier(); barrier();
q_->head++; q_->head++;
inclen(mycpuid());
stat_->push++; stat_->push++;
popcli(); popcli();
return 0; return 0;
...@@ -156,6 +183,7 @@ wq::pop(int c) ...@@ -156,6 +183,7 @@ wq::pop(int c)
i = (i-1) & (NSLOTS-1); i = (i-1) & (NSLOTS-1);
w = q->w[i]; w = q->w[i];
q->head--; q->head--;
declen(c);
wqlock_release(&q->lock); wqlock_release(&q->lock);
stat_->pop++; stat_->pop++;
...@@ -179,6 +207,7 @@ wq::steal(int c) ...@@ -179,6 +207,7 @@ wq::steal(int c)
i = i & (NSLOTS-1); i = i & (NSLOTS-1);
w = q->w[i]; w = q->w[i];
q->tail++; q->tail++;
declen(c);
wqlock_release(&q->lock); wqlock_release(&q->lock);
stat_->steal++; stat_->steal++;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define VERIFYFREE 0 // Unreliable, e.g. vma's vmnode pointer gets reused #define VERIFYFREE 0 // Unreliable, e.g. vma's vmnode pointer gets reused
#define ALLOC_MEMSET DEBUG #define ALLOC_MEMSET DEBUG
#define KSHAREDSIZE (32 << 10) #define KSHAREDSIZE (32 << 10)
#define USERWQSIZE (1 << 14)
#define WQSHIFT 7 #define WQSHIFT 7
#define CILKENABLE 0 #define CILKENABLE 0
#if defined(HW_josmp) #if defined(HW_josmp)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论