wq rejigger

上级 e783ddce
#if defined(XV6_KERNEL) #define WQSIZE 8192
typedef struct spinlock wqlock_t; class work;
#elif defined(LINUX)
typedef pthread_spinlock_t wqlock_t;
#else
typedef struct uspinlock wqlock_t;
#endif
#include "percpu.hh" int wq_trywork(void);
int wq_push(work *w);
#define NSLOTS (1 << WQSHIFT) void initwq(void);
struct work { struct work {
virtual void run() = 0; virtual void run() = 0;
}; };
class wq {
public:
wq();
int push(work *w);
int trywork();
void dump();
static void* operator new(unsigned long);
private:
work *steal(int c);
work *pop(int c);
struct wqueue {
work *w[NSLOTS];
volatile int head __mpalign__;
volatile int tail;
wqlock_t lock;
};
struct stat {
u64 push;
u64 full;
u64 pop;
u64 steal;
};
percpu<wqueue> q_;
percpu<stat> stat_;
};
struct cwork : public work{ struct cwork : public work{
virtual void run(); virtual void run();
...@@ -60,11 +24,6 @@ struct cwork : public work{ ...@@ -60,11 +24,6 @@ struct cwork : public work{
void *arg4; void *arg4;
}; };
void initwq(void);
struct work * allocwork(void);
void freework(struct work *w);
int wq_push(work *w);
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)
......
#include "types.h"
#include "kernel.hh"
#include "spinlock.h"
#include "amd64.h"
#include "cpu.hh"
#include "kalloc.hh"
#include "wq.hh"
typedef struct spinlock wqlock_t;
static inline void*
allocwq(void)
{
return ksalloc(slab_wq);
}
static inline void
wqlock_acquire(wqlock_t *lock)
{
acquire(lock);
}
static inline int
wqlock_tryacquire(wqlock_t *lock)
{
return tryacquire(lock);
}
static inline void
wqlock_release(wqlock_t *lock)
{
release(lock);
}
static inline void
wqlock_init(wqlock_t *lock)
{
initlock(lock, "wq lock", LOCKSTAT_WQ);
}
static inline void
wqarch_init(void)
{
}
#define xprintf cprintf
#define xmalloc(n) kmalloc(n)
#define xfree(p, sz) kmfree(p, sz)
// XXX(sbw)
typedef struct uspinlock wqlock_t;
...@@ -275,7 +275,7 @@ initkalloc(u64 mbaddr) ...@@ -275,7 +275,7 @@ initkalloc(u64 mbaddr)
slabmem[slab_kshared][c].ninit = CPUKSTACKS; slabmem[slab_kshared][c].ninit = CPUKSTACKS;
strncpy(slabmem[slab_wq][c].name, " wq", MAXNAME); strncpy(slabmem[slab_wq][c].name, " wq", MAXNAME);
slabmem[slab_wq][c].size = PGROUNDUP(sizeof(wq)); slabmem[slab_wq][c].size = WQSIZE;
slabmem[slab_wq][c].ninit = NCPU; slabmem[slab_wq][c].ninit = NCPU;
for (int i = 0; i < slab_type_max; i++) { for (int i = 0; i < slab_type_max; i++) {
......
#if defined(LINUX) #if defined(LINUX)
#include <stdlib.h> #include "user/wqlinux.hh"
#include <stdio.h> #include "include/percpu.hh"
#include <assert.h>
#include <pthread.h>
#include "include/types.h"
#include "include/wq.hh"
static __thread int myid_;
int
mycpuid(void)
{
return myid_;
}
static inline void*
allocwq(void)
{
return malloc(sizeof(wq));
}
static inline void
wqlock_acquire(wqlock_t *lock)
{
pthread_spin_lock(lock);
}
static inline int
wqlock_tryacquire(wqlock_t *lock)
{
return (pthread_spin_trylock(lock) == 0);
}
static inline void
wqlock_release(wqlock_t *lock)
{
pthread_spin_unlock(lock);
}
static inline void
wqlock_init(wqlock_t *lock)
{
pthread_spin_init(lock, 0);
}
static inline u64
rdtsc(void)
{
u32 hi, lo;
__asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((u64)lo)|(((u64)hi)<<32);
}
#define xprintf printf
#define xmalloc(n) malloc(n)
#define xfree(p, sz) free(p)
#define pushcli()
#define popcli()
#elif defined(XV6_KERNEL) #elif defined(XV6_KERNEL)
#include "wqkernel.hh"
#include "percpu.hh"
#else
#warning "Unknown wq implementation"
#endif
#include "types.h" #define NSLOTS (1 << WQSHIFT)
#include "kernel.hh"
#include "spinlock.h"
#include "amd64.h"
#include "cpu.hh"
#include "kalloc.hh"
#include "wq.hh"
static inline int
mywqid(void)
{
return mycpu()->id;
}
static inline void*
allocwq(void)
{
return ksalloc(slab_wq);
}
static inline void class wq {
wqlock_acquire(wqlock_t *lock) public:
{ wq();
acquire(lock); int push(work *w);
} int trywork();
void dump();
static inline int static void* operator new(unsigned long);
wqlock_tryacquire(wqlock_t *lock)
{
return tryacquire(lock);
}
static inline void private:
wqlock_release(wqlock_t *lock) work *steal(int c);
{ work *pop(int c);
release(lock);
}
static inline void struct wqueue {
wqlock_init(wqlock_t *lock) work *w[NSLOTS];
{ volatile int head __mpalign__;
initlock(lock, "wq lock", LOCKSTAT_WQ); volatile int tail;
} wqlock_t lock;
};
#define xprintf cprintf struct stat {
#define xmalloc(n) kmalloc(n) u64 push;
#define xfree(p, sz) kmfree(p, sz) u64 full;
u64 pop;
u64 steal;
};
#else percpu<wqueue> q_;
#warning "Unknown wq implementation" percpu<stat> stat_;
#endif };
static wq *wq_; static wq *wq_;
static_assert(sizeof(wq) <= WQSIZE, "WQSIZE too small");
int int
wq_push(work *w) wq_push(work *w)
{ {
...@@ -135,6 +67,7 @@ void ...@@ -135,6 +67,7 @@ void
initwq(void) initwq(void)
{ {
wq_ = new wq(); wq_ = new wq();
wqarch_init();
} }
// //
......
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <pthread.h>
#include "user/util.h"
#include "include/types.h"
#include "include/wq.hh"
static __thread int myid_;
typedef pthread_spinlock_t wqlock_t;
int
mycpuid(void)
{
return myid_;
}
static inline void*
allocwq(void)
{
return malloc(WQSIZE);
}
static inline void
wqlock_acquire(wqlock_t *lock)
{
pthread_spin_lock(lock);
}
static inline int
wqlock_tryacquire(wqlock_t *lock)
{
return (pthread_spin_trylock(lock) == 0);
}
static inline void
wqlock_release(wqlock_t *lock)
{
pthread_spin_unlock(lock);
}
static inline void
wqlock_init(wqlock_t *lock)
{
pthread_spin_init(lock, 0);
}
static inline u64
rdtsc(void)
{
u32 hi, lo;
__asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((u64)lo)|(((u64)hi)<<32);
}
static void*
workerth(void *x)
{
u64 c = (u64)x;
myid_ = c;
setaffinity(c);
while (1)
wq_trywork();
return NULL;
}
static inline void
wqarch_init(void)
{
pthread_t th;
int r;
myid_ = 0;
setaffinity(0);
for (int i = 1; i < NCPU; i++) {
r = pthread_create(&th, NULL, workerth, (void*)(u64)i);
if (r < 0)
edie("pthread_create");
}
}
#define xprintf printf
#define xmalloc(n) malloc(n)
#define xfree(p, sz) free(p)
#define pushcli()
#define popcli()
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论