hopefully fixed race condition updating priorities
This commit is contained in:
parent
b853e5fd3f
commit
17fbc7d1ca
wrap/gcache
|
@ -169,6 +169,7 @@ protected:
|
||||||
mt::mutexlocker locker(&(this->heap_lock));
|
mt::mutexlocker locker(&(this->heap_lock));
|
||||||
|
|
||||||
//2 we have some element not in the upper caches (heap.size() > 0
|
//2 we have some element not in the upper caches (heap.size() > 0
|
||||||
|
assert(this->heap.size());
|
||||||
if(this->heap.size()) {
|
if(this->heap.size()) {
|
||||||
Token &last = this->heap.min();
|
Token &last = this->heap.min();
|
||||||
int itemsize = size(&last);
|
int itemsize = size(&last);
|
||||||
|
@ -228,7 +229,7 @@ protected:
|
||||||
if(input->heap.size()) { //we need something in input to tranfer.
|
if(input->heap.size()) { //we need something in input to tranfer.
|
||||||
Token &first = input->heap.max();
|
Token &first = input->heap.max();
|
||||||
if(first.count > Token::REMOVE &&
|
if(first.count > Token::REMOVE &&
|
||||||
(!last || last->priority < first.priority)) { //if !last we already decided we want a transfer., otherwise check for a swap
|
(!last || first.priority > last->priority)) { //if !last we already decided we want a transfer., otherwise check for a swap
|
||||||
insert = input->heap.popMax(); //remove item from heap, while we transfer it.
|
insert = input->heap.popMax(); //remove item from heap, while we transfer it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
///ensure that added tokens are processed and existing ones have their priority updated.
|
///ensure that added tokens are processed and existing ones have their priority updated.
|
||||||
|
///potential bug! update is done on the heaps, if something is in transit...
|
||||||
void updatePriorities() {
|
void updatePriorities() {
|
||||||
|
|
||||||
if(tokens.size()) {
|
if(tokens.size()) {
|
||||||
|
|
|
@ -28,19 +28,18 @@ class Provider: public mt::thread {
|
||||||
bool heap_dirty;
|
bool heap_dirty;
|
||||||
///lock this before manipulating heap.
|
///lock this before manipulating heap.
|
||||||
mt::mutex heap_lock;
|
mt::mutex heap_lock;
|
||||||
///used to sincronize priorities update
|
|
||||||
mt::mutex priority_lock;
|
|
||||||
///signals (to next cache!) priorities have changed or something is available
|
///signals (to next cache!) priorities have changed or something is available
|
||||||
QDoor check_queue;
|
QDoor check_queue;
|
||||||
|
|
||||||
Provider(): max_tokens(-1), heap_dirty(false) {}
|
Provider(): max_tokens(-1), heap_dirty(false) {}
|
||||||
virtual ~Provider() {}
|
virtual ~Provider() {}
|
||||||
|
|
||||||
/// [should be protected, do not use]
|
/// [should be protected, do not use] called in controller thread!
|
||||||
void pushPriorities() {
|
void pushPriorities() {
|
||||||
mt::mutexlocker locker(&priority_lock);
|
mt::mutexlocker locker(&heap_lock);
|
||||||
for(int i = 0; i < heap.size(); i++)
|
for(int i = 0; i < heap.size(); i++)
|
||||||
heap[i].pushPriority();
|
heap[i].pushPriority();
|
||||||
|
|
||||||
heap_dirty = true;
|
heap_dirty = true;
|
||||||
check_queue.open();
|
check_queue.open();
|
||||||
}
|
}
|
||||||
|
@ -48,13 +47,8 @@ class Provider: public mt::thread {
|
||||||
void rebuild() {
|
void rebuild() {
|
||||||
if(!this->heap_dirty) return;
|
if(!this->heap_dirty) return;
|
||||||
|
|
||||||
{
|
|
||||||
mt::mutexlocker locker(&priority_lock);
|
|
||||||
for(int i = 0; i < this->heap.size(); i++)
|
|
||||||
this->heap[i].pullPriority();
|
|
||||||
this->heap_dirty = false;
|
|
||||||
}
|
|
||||||
this->heap.rebuild();
|
this->heap.rebuild();
|
||||||
|
this->heap_dirty = false;
|
||||||
|
|
||||||
//remove OUTSIDE tokens from bottom of heap
|
//remove OUTSIDE tokens from bottom of heap
|
||||||
if(max_tokens != -1) {
|
if(max_tokens != -1) {
|
||||||
|
|
|
@ -28,12 +28,10 @@ class Token {
|
||||||
enum Status { LOCKED = 1, READY = 0, CACHE = -1, REMOVE = -2, OUTSIDE = -3 };
|
enum Status { LOCKED = 1, READY = 0, CACHE = -1, REMOVE = -2, OUTSIDE = -3 };
|
||||||
///Do not access these members directly. Will be moved to private shortly.
|
///Do not access these members directly. Will be moved to private shortly.
|
||||||
///used by various cache threads to sort objects [do not use, should be private]
|
///used by various cache threads to sort objects [do not use, should be private]
|
||||||
Priority priority;
|
Priority priority;
|
||||||
///set in the main thread [do not use, should be private]
|
///set in the main thread [do not use, should be private]
|
||||||
Priority new_priority;
|
Priority new_priority;
|
||||||
///swap space used in updatePriorities [do not use, should be private]
|
///swap space used in updatePriorities [do not use, should be private]
|
||||||
Priority tmp_priority;
|
|
||||||
///reference count of locked items [do not use, should be private]
|
|
||||||
mt::atomicInt count;
|
mt::atomicInt count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -43,6 +41,7 @@ class Token {
|
||||||
void setPriority(const Priority &p) {
|
void setPriority(const Priority &p) {
|
||||||
new_priority = p;
|
new_priority = p;
|
||||||
}
|
}
|
||||||
|
//set and get are safe to call in the controller thread.
|
||||||
Priority getPriority() {
|
Priority getPriority() {
|
||||||
return new_priority;
|
return new_priority;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +52,7 @@ class Token {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
///assumes it was locked first and 1 unlock for each lock.
|
///assumes it was locked first and 1 unlock for each lock.
|
||||||
bool unlock() {
|
bool unlock() {
|
||||||
return count.deref();
|
return count.deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,11 +68,7 @@ class Token {
|
||||||
|
|
||||||
///copy priority to swap space [do not use, should be private]
|
///copy priority to swap space [do not use, should be private]
|
||||||
void pushPriority() {
|
void pushPriority() {
|
||||||
tmp_priority = new_priority;
|
priority = new_priority;
|
||||||
}
|
|
||||||
///copy priority from swap space [do not use, should be private]
|
|
||||||
void pullPriority() {
|
|
||||||
priority = tmp_priority;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Token &a) const {
|
bool operator<(const Token &a) const {
|
||||||
|
|
Loading…
Reference in New Issue