void QueueLengthPolicy::update_policy(int queue_length)
{
if (queue_length < 0) { // Starvation.
- if (safe_queue_length < 5) {
+ if (been_at_safe_point_since_last_starvation && safe_queue_length < 5) {
++safe_queue_length;
fprintf(stderr, "Card %u: Starvation, increasing safe limit to %u frames\n",
card_index, safe_queue_length);
}
frames_with_at_least_one = 0;
+ been_at_safe_point_since_last_starvation = false;
return;
}
if (queue_length > 0) {
+ if (queue_length >= int(safe_queue_length)) {
+ been_at_safe_point_since_last_starvation = true;
+ }
if (++frames_with_at_least_one >= 50 && safe_queue_length > 0) {
--safe_queue_length;
fprintf(stderr, "Card %u: Spare frames for more than 50 frames, reducing safe limit to %u frames\n",
//
// N is reduced as follows: If the queue has had at least one spare frame for
// at least 50 (master) frames (ie., it's been too conservative for a second),
-// we reduce N by 1 and reset the timers.
+// we reduce N by 1 and reset the timers. TODO: Only do this if N ever actually
+// touched the limit.
//
-// Whenever the queue is starved (we needed a frame but there was none), N was
-// obviously too low, so we increment N. We will never set N above 5, though.
+// Whenever the queue is starved (we needed a frame but there was none),
+// and we've been at N since the last starvation, N was obviously too low,
+// so we increment it. We will never set N above 5, though.
class QueueLengthPolicy {
public:
QueueLengthPolicy() {}
this->card_index = card_index;
safe_queue_length = 0;
frames_with_at_least_one = 0;
+ been_at_safe_point_since_last_starvation = false;
}
void update_policy(int queue_length); // Give in -1 for starvation.
unsigned card_index; // For debugging only.
unsigned safe_queue_length = 0; // Called N in the comments.
unsigned frames_with_at_least_one = 0;
+ bool been_at_safe_point_since_last_starvation = false;
};
class Mixer {