For userspace to explicitly enable user wqs

上级 dcddf43f
......@@ -54,35 +54,3 @@ struct elfnote {
#define ELF_PROG_FLAG_EXEC 1
#define ELF_PROG_FLAG_WRITE 2
#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 {
struct uwq : public referenced, public rcu_freed {
friend struct uwq_worker;
static uwq* alloc(vmap* vmap, filetable *ftable);
static uwq* alloc(vmap* vmap, filetable *ftable, uptr uentry);
bool haswork() const;
bool tryworker();
void setuentry(uptr uentry);
virtual void do_gc(void) { delete this; }
protected:
virtual void onzero() const;
private:
uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf *ipc);
uwq(vmap* vmap, filetable* ftable, uwq_ipcbuf *ipc, uptr uentry);
~uwq();
uwq& operator=(const uwq&);
uwq(const uwq& x);
......
......@@ -2,11 +2,11 @@
#include "uspinlock.h"
#include "amd64.h"
#include "user.h"
#include "memlayout.h"
#include "uwq.hh"
#include "wqtypes.hh"
int mycpuid(void);
uwq_ipcbuf* allocipc(void);
static inline void*
allocwq(unsigned long nbytes)
......@@ -20,18 +20,6 @@ freewq(void* 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
wqlock_acquire(wqlock_t *lock)
{
......
......@@ -19,36 +19,6 @@
#define BRK (USERTOP >> 1)
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)
{
struct proghdr ph;
......@@ -177,7 +147,6 @@ exec(const char *path, char **argv, void *ascopev)
ANON_REGION(__func__, &perfgroup);
struct inode *ip = nullptr;
struct vmap *vmp = nullptr;
uwq* newuwq = nullptr;
const char *s, *last;
struct elfhdr elf;
struct proghdr ph;
......@@ -218,9 +187,6 @@ exec(const char *path, char **argv, void *ascopev)
if((vmp = vmap::alloc()) == 0)
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)){
Elf64_Word type;
if(readi(ip, (char*)&type,
......@@ -229,10 +195,6 @@ exec(const char *path, char **argv, void *ascopev)
goto bad;
switch (type) {
case ELF_PROG_NOTE:
if (donotes(ip, newuwq, off) < 0)
goto bad;
break;
case ELF_PROG_LOAD:
if (dosegment(ip, vmp, off) < 0)
goto bad;
......@@ -254,7 +216,6 @@ exec(const char *path, char **argv, void *ascopev)
oldvmap = myproc()->vmap;
olduwq = myproc()->uwq;
myproc()->vmap = vmp;
myproc()->uwq = newuwq;
myproc()->tf->rip = elf.entry;
myproc()->tf->rsp = sp;
......@@ -279,8 +240,6 @@ exec(const char *path, char **argv, void *ascopev)
cprintf("exec failed\n");
if(vmp)
vmp->decref();
if(newuwq)
newuwq->dec();
gc_end_epoch();
return 0;
}
......@@ -54,6 +54,23 @@ uwq_trywork(void)
//SYSCALL
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)
{
uwq_worker* w = myproc()->worker;
......@@ -103,7 +120,7 @@ uwq_worker::wait(void)
// uwq
//
uwq*
uwq::alloc(vmap* vmap, filetable *ftable)
uwq::alloc(vmap* vmap, filetable *ftable, uptr uentry)
{
uwq_ipcbuf* ipc;
uwq* u;
......@@ -115,7 +132,7 @@ uwq::alloc(vmap* vmap, filetable *ftable)
ftable->incref();
vmap->incref();
u = new uwq(vmap, ftable, ipc);
u = new uwq(vmap, ftable, ipc, uentry);
if (u == nullptr) {
ftable->decref();
vmap->decref();
......@@ -131,10 +148,10 @@ uwq::alloc(vmap* vmap, filetable *ftable)
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"),
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++)
ipc_->len[i].v_ = 0;
......@@ -254,12 +271,6 @@ uwq::onzero() const
u->finish();
}
void
uwq::setuentry(uptr uentry)
{
uentry_ = uentry;
}
proc*
uwq::allocworker(void)
{
......
......@@ -5,7 +5,7 @@
#include "wq.hh"
#include "atomic.hh"
#include "pthread.h"
#include "elf.hh"
#include "memlayout.h"
u64 wq_maxworkers = NWORKERS;
......@@ -28,7 +28,20 @@ initworker(void)
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
mycpuid(void)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论