Some scheduler hacks

上级 a4551d12
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "percpu.hh" #include "percpu.hh"
#include "sperf.hh" #include "sperf.hh"
#include "major.h" #include "major.h"
#include "rnd.hh"
enum { sched_debug = 0 }; enum { sched_debug = 0 };
enum { steal_nonexec = 1 }; enum { steal_nonexec = 1 };
...@@ -33,14 +34,14 @@ public: ...@@ -33,14 +34,14 @@ public:
} }
sched_stat stats_; sched_stat stats_;
u64 ncansteal_;
private: private:
struct spinlock lock_;
sched_link head_;
void sanity(void); void sanity(void);
volatile u64 ncansteal_ __mpalign__; struct spinlock lock_ __mpalign__;
sched_link head_;
volatile bool cansteal_ __mpalign__;
}; };
percpu<schedule> schedule_; percpu<schedule> schedule_;
...@@ -72,7 +73,8 @@ schedule::enq(proc* p) ...@@ -72,7 +73,8 @@ schedule::enq(proc* p)
head_.prev->next = entry; head_.prev->next = entry;
head_.prev = entry; head_.prev = entry;
if (cansteal((proc*)entry, true)) if (cansteal((proc*)entry, true))
ncansteal_++; if (ncansteal_++ == 0)
cansteal_ = true;
sanity(); sanity();
stats_.enqs++; stats_.enqs++;
} }
...@@ -93,7 +95,8 @@ schedule::deq(void) ...@@ -93,7 +95,8 @@ schedule::deq(void)
entry->next->prev = entry->prev; entry->next->prev = entry->prev;
entry->prev->next = entry->next; entry->prev->next = entry->next;
if (cansteal((proc*)entry, true)) if (cansteal((proc*)entry, true))
--ncansteal_; if (--ncansteal_ == 0)
cansteal_ = false;
sanity(); sanity();
stats_.deqs++; stats_.deqs++;
return (proc*)entry; return (proc*)entry;
...@@ -102,7 +105,7 @@ schedule::deq(void) ...@@ -102,7 +105,7 @@ schedule::deq(void)
proc* proc*
schedule::steal(bool nonexec) schedule::steal(bool nonexec)
{ {
if (ncansteal_ == 0 || !tryacquire(&lock_)) if (!cansteal_ || !tryacquire(&lock_))
return nullptr; return nullptr;
ANON_REGION(__func__, &perfgroup); ANON_REGION(__func__, &perfgroup);
...@@ -110,7 +113,8 @@ schedule::steal(bool nonexec) ...@@ -110,7 +113,8 @@ schedule::steal(bool nonexec)
if (cansteal((proc*)ptr, nonexec)) { if (cansteal((proc*)ptr, nonexec)) {
ptr->next->prev = ptr->prev; ptr->next->prev = ptr->prev;
ptr->prev->next = ptr->next; ptr->prev->next = ptr->next;
--ncansteal_; if (--ncansteal_ == 0)
cansteal_ = false;
sanity(); sanity();
++stats_.steals; ++stats_.steals;
release(&lock_); release(&lock_);
...@@ -174,12 +178,17 @@ steal(void) ...@@ -174,12 +178,17 @@ steal(void)
{ {
struct proc *steal; struct proc *steal;
int r = 0; int r = 0;
u64 s = rnd();
pushcli(); pushcli();
for (int nonexec = 0; nonexec < (steal_nonexec ? 2 : 1); nonexec++) { for (int nonexec = 0; nonexec < (steal_nonexec ? 2 : 1); nonexec++) {
for (int i = 0; i < NCPU; i++) { for (u64 i = 0; i < NCPU; i++) {
steal = schedule_[i].steal(nonexec); u64 k = (s+i) % NCPU;
if (k == myid())
continue;
steal = schedule_[k].steal(nonexec);
if (steal != nullptr) { if (steal != nullptr) {
acquire(&steal->lock); acquire(&steal->lock);
if (steal->get_state() == RUNNABLE && !steal->cpu_pin && if (steal->get_state() == RUNNABLE && !steal->cpu_pin &&
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论