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

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