Fix potential race condition. With the old code it would be possible
to get incorrect pair if the following sequence occured:
==inc== ==read_avg==
avgcount.inc()
avgcount.read()
A) u64.read()
u64.add()
B) u64.read()
avgcount2.inc()
avgcount2.read()
Depending on whether u64.read() is called at A) or B) we'd get the new
count with either the old value or new value. By flipping the order of
the avgcount & avgcount2 reads we're guaranteed to only get matched
values.
Signed-off-by: J. Eric Ivancich <ivancich@redhat.com>
}
}
- /// read <sum, count> safely
+ // read <sum, count> safely by making sure the post- and pre-count
+ // are identical; in other words the whole loop needs to be run
+ // without any intervening calls to inc, set, or tinc.
pair<uint64_t,uint64_t> read_avg() const {
uint64_t sum, count;
do {
- count = avgcount.read();
+ count = avgcount2.read();
sum = u64.read();
- } while (avgcount2.read() != count);
+ } while (avgcount.read() != count);
return make_pair(sum, count);
}
};