hopefully fixed race condition updating priorities

This commit is contained in:
Federico Ponchio 2011-12-20 18:25:13 +00:00
parent b853e5fd3f
commit 17fbc7d1ca
4 changed files with 12 additions and 21 deletions

View File

@ -169,6 +169,7 @@ protected:
mt::mutexlocker locker(&(this->heap_lock));
//2 we have some element not in the upper caches (heap.size() > 0
assert(this->heap.size());
if(this->heap.size()) {
Token &last = this->heap.min();
int itemsize = size(&last);
@ -228,7 +229,7 @@ protected:
if(input->heap.size()) { //we need something in input to tranfer.
Token &first = input->heap.max();
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.
}
}

View File

@ -64,6 +64,7 @@ class Controller {
}
///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() {
if(tokens.size()) {

View File

@ -28,19 +28,18 @@ class Provider: public mt::thread {
bool heap_dirty;
///lock this before manipulating heap.
mt::mutex heap_lock;
///used to sincronize priorities update
mt::mutex priority_lock;
///signals (to next cache!) priorities have changed or something is available
QDoor check_queue;
Provider(): max_tokens(-1), heap_dirty(false) {}
virtual ~Provider() {}
/// [should be protected, do not use]
/// [should be protected, do not use] called in controller thread!
void pushPriorities() {
mt::mutexlocker locker(&priority_lock);
mt::mutexlocker locker(&heap_lock);
for(int i = 0; i < heap.size(); i++)
heap[i].pushPriority();
heap_dirty = true;
check_queue.open();
}
@ -48,13 +47,8 @@ class Provider: public mt::thread {
void rebuild() {
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_dirty = false;
//remove OUTSIDE tokens from bottom of heap
if(max_tokens != -1) {

View File

@ -28,12 +28,10 @@ class Token {
enum Status { LOCKED = 1, READY = 0, CACHE = -1, REMOVE = -2, OUTSIDE = -3 };
///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]
Priority priority;
Priority priority;
///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]
Priority tmp_priority;
///reference count of locked items [do not use, should be private]
mt::atomicInt count;
public:
@ -43,6 +41,7 @@ class Token {
void setPriority(const Priority &p) {
new_priority = p;
}
//set and get are safe to call in the controller thread.
Priority getPriority() {
return new_priority;
}
@ -53,7 +52,7 @@ class Token {
return false;
}
///assumes it was locked first and 1 unlock for each lock.
bool unlock() {
bool unlock() {
return count.deref();
}
@ -69,11 +68,7 @@ class Token {
///copy priority to swap space [do not use, should be private]
void pushPriority() {
tmp_priority = new_priority;
}
///copy priority from swap space [do not use, should be private]
void pullPriority() {
priority = tmp_priority;
priority = new_priority;
}
bool operator<(const Token &a) const {