fix thrashing bug

This commit is contained in:
David Rose 2008-09-05 01:12:04 +00:00
parent c0b1f01a70
commit 9dbf584092
6 changed files with 72 additions and 22 deletions

View File

@ -117,10 +117,10 @@ do_partial_lru_update(int num_updates) {
void AdaptiveLru::
update_page(AdaptiveLruPage *page) {
int target_priority = page->_priority;
int lifetime_frames = _current_frame_identifier - page->_first_frame_identifier;
if (lifetime_frames >= 1) {
unsigned int lifetime_frames = _current_frame_identifier - page->_first_frame_identifier;
if (lifetime_frames > 0) {
if (page->_update_frame_identifier) {
int update_frames;
unsigned int update_frames;
update_frames = (_current_frame_identifier - page->_update_frame_identifier);
if (update_frames > 0) {
@ -197,7 +197,7 @@ enqueue_lru(AdaptiveLru *lru) {
_priority = AdaptiveLru::LPP_New;
_first_frame_identifier = _lru->_current_frame_identifier;
_last_frame_identifier = _lru->_current_frame_identifier;
_current_frame_identifier = _lru->_current_frame_identifier;
_lru->do_add_page(this);
}
}
@ -212,12 +212,10 @@ size_t AdaptiveLru::
count_active_size() const {
size_t counted_size = 0;
int minimum_frame_identifier = _current_frame_identifier - 1;
AdaptiveLruPageStaticList *node = (AdaptiveLruPageStaticList *)_static_list._next;
while (node != &_static_list) {
AdaptiveLruPage *page = (AdaptiveLruPage *)node;
if (page->_current_frame_identifier >= minimum_frame_identifier) {
if (page->_current_frame_identifier + 1 >= _current_frame_identifier) {
counted_size += page->_lru_size;
}
node = (AdaptiveLruPageStaticList *)node->_next;
@ -272,8 +270,6 @@ write(ostream &out, int indent_level) const {
MutexHolder holder(_lock);
int minimum_frame_identifier = _current_frame_identifier - 1;
int index;
for (index = 0; index < LPP_TotalPriorities; ++index) {
AdaptiveLruPageDynamicList *node = (AdaptiveLruPageDynamicList *)_page_array[index]._prev;
@ -283,7 +279,7 @@ write(ostream &out, int indent_level) const {
AdaptiveLruPage *page = (AdaptiveLruPage *)node;
indent(out, indent_level + 4) << *page;
if (page->_current_frame_identifier >= minimum_frame_identifier) {
if (page->_current_frame_identifier + 1 >= _current_frame_identifier) {
out << " (active)";
}
out << "\n";
@ -292,6 +288,10 @@ write(ostream &out, int indent_level) const {
}
}
}
#ifndef NDEBUG
((AdaptiveLru *)this)->do_validate();
#endif
}
////////////////////////////////////////////////////////////////////
@ -341,7 +341,6 @@ do_access_page(AdaptiveLruPage *page) {
} else {
// This page has not yet been accessed this frame. Update it.
page->_last_frame_identifier = page->_current_frame_identifier;
page->_current_frame_identifier = _current_frame_identifier;
page->_last_frame_usage = page->_current_frame_usage;
page->_current_frame_usage = 1;
@ -368,8 +367,6 @@ do_evict_to(size_t target_size, bool hard_evict) {
attempts = 0;
do {
int minimum_frame_identifier = _current_frame_identifier - 1;
// page out lower priority pages first
int index;
for (index = LPP_TotalPriorities - 1; index >= 0; index--) {
@ -385,14 +382,15 @@ do_evict_to(size_t target_size, bool hard_evict) {
AdaptiveLruPageDynamicList *next = (AdaptiveLruPageDynamicList *)node->_next;
AdaptiveLruPage *page = (AdaptiveLruPage *)node;
if (attempts == 0 && (page->_current_frame_identifier >= minimum_frame_identifier)) {
if (attempts == 0 &&
(page->_current_frame_identifier + 1 >= _current_frame_identifier)) {
// avoid swapping out pages used in the current and last
// frame on the first attempt
} else {
// We must release the lock while we call evict_lru().
_lock.release();
((AdaptiveLruPage *)node)->evict_lru();
page->evict_lru();
_lock.lock();
if (_total_size <= target_size) {
@ -486,7 +484,6 @@ AdaptiveLruPage(size_t lru_size) :
_lru_size(lru_size),
_priority(0),
_first_frame_identifier(0),
_last_frame_identifier(0),
_current_frame_identifier(0),
_update_frame_identifier(0),
_current_frame_usage(0),
@ -508,7 +505,6 @@ AdaptiveLruPage(const AdaptiveLruPage &copy) :
_lru_size(copy._lru_size),
_priority(0),
_first_frame_identifier(0),
_last_frame_identifier(0),
_current_frame_identifier(0),
_update_frame_identifier(0),
_current_frame_usage(0),
@ -581,6 +577,37 @@ write(ostream &out, int indent_level) const {
indent(out, indent_level) << *this << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: AdaptiveLruPage::get_num_frames
// Access: Published
// Description: Returns the number of frames since the page was first
// added to its LRU. Returns 0 if it does not have an
// LRU.
////////////////////////////////////////////////////////////////////
unsigned int AdaptiveLruPage::
get_num_frames() const {
if (_lru == (AdaptiveLru *)NULL) {
return 0;
}
return _lru->_current_frame_identifier - _first_frame_identifier;
}
////////////////////////////////////////////////////////////////////
// Function: AdaptiveLruPage::get_num_inactive_frames
// Access: Published
// Description: Returns the number of frames since the page was last
// accessed on its LRU. Returns 0 if it does not have
// an LRU.
////////////////////////////////////////////////////////////////////
unsigned int AdaptiveLruPage::
get_num_inactive_frames() const {
if (_lru == (AdaptiveLru *)NULL) {
return 0;
}
return _lru->_current_frame_identifier - _current_frame_identifier;
}
#if 0
////////////////////////////////////////////////////////////////////

View File

@ -76,6 +76,7 @@ PUBLISHED:
INLINE int get_max_updates_per_frame() const;
private:
public: // temp hack
enum LruPagePriority {
LPP_Highest = 0,
LPP_High = 10,
@ -103,7 +104,7 @@ private:
size_t _total_size;
size_t _max_size;
int _current_frame_identifier;
unsigned int _current_frame_identifier;
double _weight;
int _max_updates_per_frame;
@ -165,16 +166,19 @@ PUBLISHED:
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;
// Not defined in SimpleLruPage.
unsigned int get_num_frames() const;
unsigned int get_num_inactive_frames() const;
private:
AdaptiveLru *_lru;
size_t _lru_size;
int _priority;
int _first_frame_identifier; // creation time
int _last_frame_identifier; // last time page used
int _current_frame_identifier;
int _update_frame_identifier;
unsigned int _first_frame_identifier; // Frame first added.
unsigned int _current_frame_identifier; // Frame last accessed.
unsigned int _update_frame_identifier; // Frame last updated.
int _current_frame_usage;
int _last_frame_usage;

View File

@ -79,6 +79,11 @@ private:
friend class PreparedGraphicsObjects;
};
inline ostream &operator << (ostream &out, const IndexBufferContext &context) {
context.output(out);
return out;
}
#include "indexBufferContext.I"
#endif

View File

@ -156,6 +156,10 @@ write(ostream &out, int indent_level) const {
node = page->_prev;
}
}
#ifndef NDEBUG
((SimpleLru *)this)->do_validate();
#endif
}
////////////////////////////////////////////////////////////////////

View File

@ -85,6 +85,11 @@ private:
friend class PreparedGraphicsObjects;
};
inline ostream &operator << (ostream &out, const TextureContext &context) {
context.output(out);
return out;
}
#include "textureContext.I"
#endif

View File

@ -80,6 +80,11 @@ private:
friend class PreparedGraphicsObjects;
};
inline ostream &operator << (ostream &out, const VertexBufferContext &context) {
context.output(out);
return out;
}
#include "vertexBufferContext.I"
#endif