int main(int argc, char **argv) { struct hdr_histogram* histogram; int64_t max_value = 24 * 60 * 60 * 1000000L; int64_t min_value = 1; int result = -1; result = hdr_init(min_value, max_value, 4, &histogram); if (result != 0) { fprintf(stderr, "Failed to allocate histogram: %d\n", result); return -1; } struct timespec t0; struct timespec t1; setlocale(LC_NUMERIC, ""); int64_t iterations = 400000000; for (int i = 0; i < 100; i++) { hdr_gettime(&t0); for (int64_t j = 1; j < iterations; j++) { hdr_record_value(histogram, j); } hdr_gettime(&t1); struct timespec taken = diff(t0, t1); double time_taken = taken.tv_sec + taken.tv_nsec / 1000000000.0; double ops_sec = (iterations - 1) / time_taken; printf("%s - %d, ops/sec: %'.2f\n", "Iteration", i + 1, ops_sec); } return 0; }
void* record_hiccups(void* thread_context) { struct pollfd fd; struct timespec t0; struct timespec t1; struct itimerspec timeout; struct hdr_interval_recorder* r = thread_context; memset(&fd, 0, sizeof(struct pollfd)); memset(&timeout, 0, sizeof(struct itimerspec)); memset(&t0, 0, sizeof(struct timespec)); memset(&t1, 0, sizeof(struct timespec)); fd.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); fd.events = POLLIN|POLLPRI|POLLRDHUP; fd.revents = 0; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" while (true) { timeout.it_value.tv_sec = 0; timeout.it_value.tv_nsec = 1000000; timerfd_settime(fd.fd, 0, &timeout, NULL); hdr_gettime(&t0); poll(&fd, 1, -1); hdr_gettime(&t1); int64_t delta_us = diff(t0, t1) - 1000; delta_us = delta_us < 0 ? 0 : delta_us; hdr_interval_recorder_update(r, update_histogram, &delta_us); } #pragma clang diagnostic pop pthread_exit(NULL); }
static char* log_reader_aggregates_into_single_histogram() { const char* file_name = "histogram.log"; hdr_timespec timestamp; hdr_timespec interval; hdr_gettime(×tamp); interval.tv_sec = 5; interval.tv_nsec = 2000000; struct hdr_log_writer writer; struct hdr_log_reader reader; hdr_log_writer_init(&writer); hdr_log_reader_init(&reader); int rc = 0; FILE* log_file = fopen(file_name, "w+"); hdr_log_write_header(&writer, log_file, "Test log", ×tamp); hdr_log_write(&writer, log_file, ×tamp, &interval, cor_histogram); hdr_log_write(&writer, log_file, ×tamp, &interval, raw_histogram); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); struct hdr_histogram* histogram; hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram); rc = hdr_log_read_header(&reader, log_file); mu_assert("Failed header read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed corrected read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed raw read", validate_return_code(rc)); struct hdr_iter iter; hdr_iter_recorded_init(&iter, histogram); int64_t expected_total_count = raw_histogram->total_count + cor_histogram->total_count; mu_assert( "Total counts incorrect", compare_int64(histogram->total_count, expected_total_count)); while (hdr_iter_next(&iter)) { int64_t count = iter.count; int64_t value = iter.value; int64_t expected_count = hdr_count_at_value(raw_histogram, value) + hdr_count_at_value(cor_histogram, value); mu_assert("Incorrect count", compare_int64(count, expected_count)); } fclose(log_file); remove(file_name); free(histogram); return 0; }
static char* writes_and_reads_log() { const char* file_name = "histogram.log"; hdr_timespec timestamp; hdr_timespec interval; hdr_gettime(×tamp); interval.tv_sec = 5; interval.tv_nsec = 2000000; struct hdr_log_writer writer; struct hdr_log_reader reader; hdr_log_writer_init(&writer); hdr_log_reader_init(&reader); int rc = 0; FILE* log_file = fopen(file_name, "w+"); rc = hdr_log_write_header(&writer, log_file, "Test log", ×tamp); mu_assert("Failed header write", validate_return_code(rc)); hdr_log_write(&writer, log_file, ×tamp, &interval, cor_histogram); mu_assert("Failed corrected write", validate_return_code(rc)); hdr_log_write(&writer, log_file, ×tamp, &interval, raw_histogram); mu_assert("Failed raw write", validate_return_code(rc)); fprintf(log_file, "\n"); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); struct hdr_histogram* read_cor_histogram = NULL; struct hdr_histogram* read_raw_histogram = NULL; rc = hdr_log_read_header(&reader, log_file); mu_assert("Failed header read", validate_return_code(rc)); mu_assert("Incorrect major version", compare_int(reader.major_version, 1)); mu_assert("Incorrect minor version", compare_int(reader.minor_version, 2)); mu_assert( "Incorrect start timestamp", compare_timespec(&reader.start_timestamp, ×tamp)); hdr_timespec actual_timestamp; hdr_timespec actual_interval; rc = hdr_log_read( &reader, log_file, &read_cor_histogram, &actual_timestamp, &actual_interval); mu_assert("Failed corrected read", validate_return_code(rc)); mu_assert( "Incorrect first timestamp", compare_timespec(&actual_timestamp, ×tamp)); mu_assert( "Incorrect first interval", compare_timespec(&actual_interval, &interval)); rc = hdr_log_read(&reader, log_file, &read_raw_histogram, NULL, NULL); mu_assert("Failed raw read", validate_return_code(rc)); mu_assert( "Histograms do not match", compare_histogram(cor_histogram, read_cor_histogram)); mu_assert( "Histograms do not match", compare_histogram(raw_histogram, read_raw_histogram)); rc = hdr_log_read(&reader, log_file, &read_cor_histogram, NULL, NULL); mu_assert("No EOF at end of file", rc == EOF); fclose(log_file); remove(file_name); return 0; }
int main(int argc, char** argv) { struct timespec timestamp; struct timespec start_timestamp; struct timespec end_timestamp; struct hdr_interval_recorder recorder; struct hdr_log_writer log_writer; struct config_t config; pthread_t recording_thread; FILE* output = stdout; memset(&config, 0, sizeof(struct config_t)); if (!handle_opts(argc, argv, &config)) { printf("%s", USAGE); return 0; } if (config.filename) { output = fopen(config.filename, "a+"); if (!output) { fprintf( stderr, "Failed to open/create file: %s, %s", config.filename, strerror(errno)); return -1; } } if (0 != hdr_interval_recorder_init(&recorder)) { fprintf(stderr, "%s\n", "Failed to init phaser"); return -1; } if (0 != hdr_init( 1, INT64_C(24) * 60 * 60 * 1000000, 3, (struct hdr_histogram**) &recorder.active)) { fprintf(stderr, "%s\n", "Failed to init hdr_histogram"); return -1; } if (0 != hdr_init( 1, INT64_C(24) * 60 * 60 * 1000000, 3, (struct hdr_histogram**) &recorder.inactive)) { fprintf(stderr, "%s\n", "Failed to init hdr_histogram"); return -1; } if (pthread_create(&recording_thread, NULL, record_hiccups, &recorder)) { fprintf(stderr, "%s\n", "Failed to create thread"); return -1; } hdr_gettime(&start_timestamp); hdr_log_writer_init(&log_writer); hdr_log_write_header(&log_writer, output, "foobar", ×tamp); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" while (true) { sleep(config.interval); hdr_reset(recorder.inactive); struct hdr_histogram* h = hdr_interval_recorder_sample(&recorder); hdr_gettime(&end_timestamp); timestamp = start_timestamp; hdr_gettime(&start_timestamp); hdr_log_write(&log_writer, output, ×tamp, &end_timestamp, h); fflush(output); } #pragma clang diagnostic pop pthread_exit(NULL); }