linear iteration goes into infinite loop on recording new values
Closed this issue · 1 comments
During the course of iteration if a new value gets inserted in a bucket that the iterator has already passed then the iteration never ends (hdr_iter_next continues to return true).
I made a quick change to one of the test cases to reproduce the issue.
I am not sure if this is proper usage of the api, but an infinite loop seems to be a very bad outcome.
static char* test_linear_iter_buckets_correctly()
{
struct hdr_histogram *h;
hdr_init(1, 255, 2, &h);
hdr_record_value(h, 193);
hdr_record_value(h, 255);
hdr_record_value(h, 0);
hdr_record_value(h, 1);
hdr_record_value(h, 64);
hdr_record_value(h, 128);
struct hdr_iter iter;
hdr_iter_linear_init(&iter, h, 64);
int step_count = 0;
int64_t total_count = 0;
while (hdr_iter_next(&iter))
{
total_count += iter.specifics.linear.count_added_in_this_iteration_step;
// start - changes to reproduce issue
if (step_count == 0)
{
hdr_record_value(h, 2);
}
// end - changes to reproduce issue
step_count++;
}
mu_assert("Number of steps", compare_int64(4, step_count));
mu_assert("Total count", compare_int64(6, total_count));
return 0;
}
In our application the issue was caused due to unsynchronized access from multiple threads. One thread was computing the hdr_value_at_percentile which another threaded called hdr_record_value (guessing this). The hdr_value_at_percentile call went into an infinite loop.
0x0081bf8e: has_next + 0x1e (7fff27779da0, 7f113380f040, 7fff27779de8, 1007fff27779ef0)
0x0081bf35: _basic_iter_next + 0x15 (81bf20, 7fff27779de8)
0x0081ba05: hdr_iter_next + 0x25 (7fff27779df0, 3635503b6, 4058c00000000000, 19, 26c17d008, 3635503b6) + 80
0x0081bb84: hdr_value_at_percentile + 0x114 (3fe, 4bb, 5a0, 709, c57, 196bff) + ffffff12161d1650
I've fixed this now, thank you. I'll need to check ABI compatibility before I push out a new release, but the head of the git repo has the fix and is stable if you need it immediately.