For userspace to explicitly enable user wqs

上级 dcddf43f
...@@ -54,35 +54,3 @@ struct elfnote { ...@@ -54,35 +54,3 @@ struct elfnote {
#define ELF_PROG_FLAG_EXEC 1 #define ELF_PROG_FLAG_EXEC 1
#define ELF_PROG_FLAG_WRITE 2 #define ELF_PROG_FLAG_WRITE 2
#define ELF_PROG_FLAG_READ 4 #define ELF_PROG_FLAG_READ 4
// All known .note types
#define ELF_NOTE_XV6_ADDR 1
// xv6-specific address note
struct xv6_addrdesc {
Elf64_Word id;
Elf64_Addr vaddr;
};
struct xv6_addrnote {
struct elfnote elfnote;
// name is 0 bytes
struct xv6_addrdesc desc;
};
// All xv6-specific IDs for notes about addresses
#define XV6_ADDR_ID_WQ 1
#define DEFINE_XV6_ADDRNOTE(xname, xid, xvaddr) \
const struct xv6_addrnote xname PROG_NOTE_ATTRIBUTE = { \
elfnote: { \
namesz: 0, \
descsz: sizeof(((xv6_addrnote *)nullptr)->desc), \
type: ELF_NOTE_XV6_ADDR \
}, \
desc: { \
id: (xid), \
vaddr: (Elf64_Addr)(xvaddr) } \
}
#define PROG_NOTE_ATTRIBUTE __attribute__ ((section(".note"), used))
...@@ -35,19 +35,17 @@ struct uwq_worker { ...@@ -35,19 +35,17 @@ struct uwq_worker {
struct uwq : public referenced, public rcu_freed { struct uwq : public referenced, public rcu_freed {
friend struct uwq_worker; friend struct uwq_worker;
static uwq* alloc(vmap* vmap, filetable *ftable); static uwq* alloc(vmap* vmap, filetable *ftable, uptr uentry);
bool haswork() const; bool haswork() const;
bool tryworker(); bool tryworker();
void setuentry(uptr uentry);
virtual void do_gc(void) { delete this; } virtual void do_gc(void) { delete this; }
protected: protected:
virtual void onzero() const; virtual void onzero() const;
private: private:
uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf *ipc); uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf *ipc, uptr uentry);
~uwq(); ~uwq();
uwq& operator=(const uwq&); uwq& operator=(const uwq&);
uwq(const uwq& x); uwq(const uwq& x);
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
#include "uspinlock.h" #include "uspinlock.h"
#include "amd64.h" #include "amd64.h"
#include "user.h" #include "user.h"
#include "memlayout.h"
#include "uwq.hh" #include "uwq.hh"
#include "wqtypes.hh" #include "wqtypes.hh"
int mycpuid(void); int mycpuid(void);
uwq_ipcbuf* allocipc(void);
static inline void* static inline void*
allocwq(unsigned long nbytes) allocwq(unsigned long nbytes)
...@@ -20,18 +20,6 @@ freewq(void* p) ...@@ -20,18 +20,6 @@ freewq(void* p)
free(p); free(p);
} }
static inline uwq_ipcbuf*
allocipc(void)
{
static bool alloced;
if (alloced)
die("allocklen: allocing more than once");
if (sizeof(uwq_ipcbuf) > USERWQSIZE)
die("allocipc: too large");
alloced = true;
return (uwq_ipcbuf*)USERWQ;
}
static inline void static inline void
wqlock_acquire(wqlock_t *lock) wqlock_acquire(wqlock_t *lock)
{ {
......
...@@ -19,36 +19,6 @@ ...@@ -19,36 +19,6 @@
#define BRK (USERTOP >> 1) #define BRK (USERTOP >> 1)
static int static int
donotes(struct inode *ip, uwq *uwq, u64 off)
{
struct proghdr ph;
struct elfnote note;
if (readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
return -1;
if (readi(ip, (char*)&note, ph.offset, sizeof(note)) != sizeof(note))
return -1;
if (note.type == ELF_NOTE_XV6_ADDR) {
struct xv6_addrdesc desc;
if (note.descsz != sizeof(desc))
return -1;
if (readi(ip, (char*)&desc,
ph.offset+__offsetof(struct xv6_addrnote, desc),
sizeof(desc)) != sizeof(desc))
return -1;
if (desc.id == XV6_ADDR_ID_WQ) {
uwq->setuentry(desc.vaddr);
return 0;
}
}
return -1;
}
static int
dosegment(inode* ip, vmap* vmp, u64 off) dosegment(inode* ip, vmap* vmp, u64 off)
{ {
struct proghdr ph; struct proghdr ph;
...@@ -177,7 +147,6 @@ exec(const char *path, char **argv, void *ascopev) ...@@ -177,7 +147,6 @@ exec(const char *path, char **argv, void *ascopev)
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
struct inode *ip = nullptr; struct inode *ip = nullptr;
struct vmap *vmp = nullptr; struct vmap *vmp = nullptr;
uwq* newuwq = nullptr;
const char *s, *last; const char *s, *last;
struct elfhdr elf; struct elfhdr elf;
struct proghdr ph; struct proghdr ph;
...@@ -218,9 +187,6 @@ exec(const char *path, char **argv, void *ascopev) ...@@ -218,9 +187,6 @@ exec(const char *path, char **argv, void *ascopev)
if((vmp = vmap::alloc()) == 0) if((vmp = vmap::alloc()) == 0)
goto bad; goto bad;
if((newuwq = uwq::alloc(vmp, myproc()->ftable)) == 0)
goto bad;
for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){ for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
Elf64_Word type; Elf64_Word type;
if(readi(ip, (char*)&type, if(readi(ip, (char*)&type,
...@@ -229,10 +195,6 @@ exec(const char *path, char **argv, void *ascopev) ...@@ -229,10 +195,6 @@ exec(const char *path, char **argv, void *ascopev)
goto bad; goto bad;
switch (type) { switch (type) {
case ELF_PROG_NOTE:
if (donotes(ip, newuwq, off) < 0)
goto bad;
break;
case ELF_PROG_LOAD: case ELF_PROG_LOAD:
if (dosegment(ip, vmp, off) < 0) if (dosegment(ip, vmp, off) < 0)
goto bad; goto bad;
...@@ -254,7 +216,6 @@ exec(const char *path, char **argv, void *ascopev) ...@@ -254,7 +216,6 @@ exec(const char *path, char **argv, void *ascopev)
oldvmap = myproc()->vmap; oldvmap = myproc()->vmap;
olduwq = myproc()->uwq; olduwq = myproc()->uwq;
myproc()->vmap = vmp; myproc()->vmap = vmp;
myproc()->uwq = newuwq;
myproc()->tf->rip = elf.entry; myproc()->tf->rip = elf.entry;
myproc()->tf->rsp = sp; myproc()->tf->rsp = sp;
...@@ -279,8 +240,6 @@ exec(const char *path, char **argv, void *ascopev) ...@@ -279,8 +240,6 @@ exec(const char *path, char **argv, void *ascopev)
cprintf("exec failed\n"); cprintf("exec failed\n");
if(vmp) if(vmp)
vmp->decref(); vmp->decref();
if(newuwq)
newuwq->dec();
gc_end_epoch(); gc_end_epoch();
return 0; return 0;
} }
...@@ -54,6 +54,23 @@ uwq_trywork(void) ...@@ -54,6 +54,23 @@ uwq_trywork(void)
//SYSCALL //SYSCALL
int int
sys_wqinit(uptr uentry)
{
uwq* uwq;
if (myproc()->uwq != nullptr)
return -1;
uwq = uwq::alloc(myproc()->vmap, myproc()->ftable, uentry);
if (uwq == nullptr)
return -1;
myproc()->uwq = uwq;
return 0;
}
//SYSCALL
int
sys_wqwait(void) sys_wqwait(void)
{ {
uwq_worker* w = myproc()->worker; uwq_worker* w = myproc()->worker;
...@@ -103,7 +120,7 @@ uwq_worker::wait(void) ...@@ -103,7 +120,7 @@ uwq_worker::wait(void)
// uwq // uwq
// //
uwq* uwq*
uwq::alloc(vmap* vmap, filetable *ftable) uwq::alloc(vmap* vmap, filetable *ftable, uptr uentry)
{ {
uwq_ipcbuf* ipc; uwq_ipcbuf* ipc;
uwq* u; uwq* u;
...@@ -115,7 +132,7 @@ uwq::alloc(vmap* vmap, filetable *ftable) ...@@ -115,7 +132,7 @@ uwq::alloc(vmap* vmap, filetable *ftable)
ftable->incref(); ftable->incref();
vmap->incref(); vmap->incref();
u = new uwq(vmap, ftable, ipc); u = new uwq(vmap, ftable, ipc, uentry);
if (u == nullptr) { if (u == nullptr) {
ftable->decref(); ftable->decref();
vmap->decref(); vmap->decref();
...@@ -131,10 +148,10 @@ uwq::alloc(vmap* vmap, filetable *ftable) ...@@ -131,10 +148,10 @@ uwq::alloc(vmap* vmap, filetable *ftable)
return u; return u;
} }
uwq::uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf* ipc) uwq::uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf* ipc, uptr uentry)
: rcu_freed("uwq"), : rcu_freed("uwq"),
vmap_(vmap), ftable_(ftable), ipc_(ipc), vmap_(vmap), ftable_(ftable), ipc_(ipc),
uentry_(0), ustack_(UWQSTACK), uref_(0) uentry_(uentry), ustack_(UWQSTACK), uref_(0)
{ {
for (int i = 0; i < NELEM(ipc_->len); i++) for (int i = 0; i < NELEM(ipc_->len); i++)
ipc_->len[i].v_ = 0; ipc_->len[i].v_ = 0;
...@@ -254,12 +271,6 @@ uwq::onzero() const ...@@ -254,12 +271,6 @@ uwq::onzero() const
u->finish(); u->finish();
} }
void
uwq::setuentry(uptr uentry)
{
uentry_ = uentry;
}
proc* proc*
uwq::allocworker(void) uwq::allocworker(void)
{ {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "wq.hh" #include "wq.hh"
#include "atomic.hh" #include "atomic.hh"
#include "pthread.h" #include "pthread.h"
#include "elf.hh" #include "memlayout.h"
u64 wq_maxworkers = NWORKERS; u64 wq_maxworkers = NWORKERS;
...@@ -28,7 +28,20 @@ initworker(void) ...@@ -28,7 +28,20 @@ initworker(void)
assert(wqwait() == 0); assert(wqwait() == 0);
} }
} }
DEFINE_XV6_ADDRNOTE(xnote, XV6_ADDR_ID_WQ, &initworker);
uwq_ipcbuf*
allocipc(void)
{
static bool alloced;
if (alloced)
die("allocklen: allocing more than once");
if (sizeof(uwq_ipcbuf) > USERWQSIZE)
die("allocipc: too large");
if (wqinit((uptr)initworker) < 0)
die("wqinit: failed");
alloced = true;
return (uwq_ipcbuf*)USERWQ;
}
int int
mycpuid(void) mycpuid(void)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论