static void load_histograms()
{
    int i;
    if (raw_histogram)
    {
        free(raw_histogram);
    }

    hdr_alloc(3600L * 1000 * 1000, 3, &raw_histogram);

    if (cor_histogram)
    {
        free(cor_histogram);
    }

    hdr_alloc(3600L * 1000 * 1000, 3, &cor_histogram);

    for (i = 0; i < 10000; i++)
    {
        hdr_record_value(raw_histogram, 1000L);
        hdr_record_corrected_value(cor_histogram, 1000L, 10000L);
    }

    hdr_record_value(raw_histogram, 100000000L);
    hdr_record_corrected_value(cor_histogram, 100000000L, 10000L);
}
static void load_histograms()
{
    const int64_t highest_trackable_value = 3600L * 1000 * 1000;
    const int32_t significant_figures = 3;
    const int64_t interval = 10000L;
    const int64_t scale = 512;
    const int64_t scaled_interval = interval * scale;

    int i;
    if (raw_histogram)
    {
        free(raw_histogram);
    }

    hdr_alloc(highest_trackable_value, significant_figures, &raw_histogram);

    if (cor_histogram)
    {
        free(cor_histogram);
    }

    hdr_alloc(highest_trackable_value, significant_figures, &cor_histogram);

    if (scaled_raw_histogram)
    {
        free(scaled_raw_histogram);
    }

    hdr_init(1000, highest_trackable_value * 512, significant_figures, &scaled_raw_histogram);

    if (scaled_cor_histogram)
    {
        free(scaled_cor_histogram);
    }

    hdr_init(1000, highest_trackable_value * 512, significant_figures, &scaled_cor_histogram);

    for (i = 0; i < 10000; i++)
    {
        hdr_record_value(raw_histogram, 1000L);
        hdr_record_corrected_value(cor_histogram, 1000L, interval);

        hdr_record_value(scaled_raw_histogram, 1000L * scale);
        hdr_record_corrected_value(scaled_cor_histogram, 1000L * scale, scaled_interval);
    }

    hdr_record_value(raw_histogram, 100000000L);
    hdr_record_corrected_value(cor_histogram, 100000000L, 10000L);

    hdr_record_value(scaled_raw_histogram, 100000000L * scale);
    hdr_record_corrected_value(scaled_cor_histogram, 100000000L * scale, scaled_interval);
}
static char* test_invalid_significant_figures()
{
    struct hdr_histogram* h = NULL;

    int r = hdr_alloc(36000000, -1, &h);
    mu_assert("Result was not EINVAL", r == EINVAL);
    mu_assert("Histogram was not null", h == 0);

    r = hdr_alloc(36000000, 6, &h);
    mu_assert("Result was not EINVAL", r == EINVAL);
    mu_assert("Histogram was not null", h == 0);

    return 0;
}
int main(int argc, char **argv)
{
    struct hdr_histogram* histogram;
    int64_t max_value = 24 * 60 * 60 * 1000000L;
    int result = hdr_alloc(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++)
    {
        clock_gettime(CLOCK_MONOTONIC_RAW, &t0);
        for (int64_t j = 1; j < iterations; j++)
        {
            hdr_record_value(histogram, j);
        }
        clock_gettime(CLOCK_MONOTONIC_RAW, &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;
}
static void load_histograms()
{
    free(raw_histogram);
    free(cor_histogram);

    hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &raw_histogram);
    hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &cor_histogram);

    for (int i = 0; i < 10000; i++)
    {
        hdr_record_value(raw_histogram, 1000);
        hdr_record_corrected_value(cor_histogram, 1000, 10000);
    }

    hdr_record_value(raw_histogram, 100000000);
    hdr_record_corrected_value(cor_histogram, 100000000, 10000);
}
int main(int argc, char **argv)
{
    int i;
    struct hdr_histogram* raw_histogram = NULL;
    struct hdr_histogram* cor_histogram = NULL;
    hdr_alloc(100000000, 3, &raw_histogram);
    hdr_alloc(100000000, 3, &cor_histogram);

    for (i = 0; i < 10000; i++)
    {
        hdr_record_value(raw_histogram, 1000L);
        hdr_record_corrected_value(cor_histogram, 1000L, 10000L);
    }

    hdr_record_value(raw_histogram, 100000000L);
    hdr_record_corrected_value(cor_histogram, 100000000L, 10000L);

    hdr_percentiles_print(raw_histogram, stdout, 5, 1.0, CSV);
    hdr_percentiles_print(cor_histogram, stdout, 5, 1.0, CSV);
}
static char* test_create()
{
    struct hdr_histogram* h = NULL;
    int r = hdr_alloc(36000000, 4, &h);
    size_t s = hdr_get_memory_size(h);

    mu_assert("Failed to allocate hdr_histogram", r == 0);
    mu_assert("Failed to allocate hdr_histogram", h != NULL);
    mu_assert("Size is incorrect", s == 1704008);

    free(h);

    return 0;
}
ERL_NIF_TERM _hh_rotate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    hh_ctx_t* ctx = NULL;
    hh_ctx_t* to = NULL;
    ErlNifBinary target;

    ErlNifResourceType* ctx_type = get_hh_ctx_type(env);
    if (argc != 2 ||
        ctx_type == NULL ||
        !enif_get_resource(env, argv[0], ctx_type, (void **)&ctx) ||
        ctx->data == NULL ||
        !enif_get_resource(env, argv[1], ctx_type, (void **)&to) ||
        to->data == NULL)
    {
        return enif_make_badarg(env);
    }

    hdr_histogram_t* diff_histogram;
    int rc = 0;
    rc = hdr_alloc(ctx->highest_trackable_value, ctx->significant_figures, &diff_histogram);

    if (ENOMEM == rc)
    {
        return make_error(env, "not_enough_memory");
    }

    hdr_rotate(ctx->data, to->data, diff_histogram);

    int size = 0;
    uint8_t* data = NULL;
    int success = hdr_encode_uncompressed(diff_histogram, &data, &size);

    if (!enif_alloc_binary(size, &target))
    {
        return make_error(env, "bad_hdr_binary_alloc");
    }
    target.size = size;
    memcpy(target.data, data, size);
    free(data);
    free(diff_histogram);

    if (success != 0)
    {
        return make_error(env, "bad_hdr_binary");
    }

    return enif_make_binary(env, &target);
}
static char* test_encode_decode_empty()
{
    struct hdr_histogram *histogram, *hdr_new = NULL;
    hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram);

    char *data;

    mu_assert("Failed to encode histogram data", hdr_log_encode(histogram, &data) == 0);
    mu_assert("Failed to decode histogram data", hdr_log_decode(&hdr_new, data, strlen(data)) == 0);
    mu_assert("Histograms should be the same", compare_histogram(histogram, hdr_new));
    // mu_assert("Mean different after encode/decode", compare_double(hdr_mean(histogram), hdr_mean(hdr_new), 0.001));
    free(histogram);
    free(hdr_new);
    free(data);
    return 0;
}
static char* test_string_encode_decode()
{
    struct hdr_histogram *histogram, *hdr_new = NULL;
    hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram);

    for (int i = 1; i < 100; i++)
    {
        hdr_record_value(histogram, i*i);
    }

    char *data;

    mu_assert("Failed to encode histogram data", hdr_log_encode(histogram, &data) == 0);
    mu_assert("Failed to decode histogram data", hdr_log_decode(&hdr_new, data, strlen(data)) == 0);
    mu_assert("Histograms should be the same", compare_histogram(histogram, hdr_new));
    mu_assert("Mean different after encode/decode", compare_double(hdr_mean(histogram), hdr_mean(hdr_new), 0.001));

    return 0;
}
static char* test_string_encode_decode_2()
{
    struct hdr_histogram *histogram, *hdr_new = NULL;
    hdr_alloc(1000, 3, &histogram);

    int i;
    for (i = 1; i < histogram->highest_trackable_value; i++)
    {
        hdr_record_value(histogram, i);
    }

    char *data;

    mu_assert(
        "Failed to encode histogram data", validate_return_code(hdr_log_encode(histogram, &data)));
    mu_assert(
        "Failed to decode histogram data", validate_return_code(hdr_log_decode(&hdr_new, data, strlen(data))));
    mu_assert("Histograms should be the same", compare_histogram(histogram, hdr_new));
    mu_assert("Mean different after encode/decode", compare_double(hdr_mean(histogram), hdr_mean(hdr_new), 0.001));

    return 0;
}
ERL_NIF_TERM _hh_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    long highest_trackable_value = 0;
    int significant_figures = 0;
    if (argc != 2 ||
        !enif_get_int64(env, argv[0], &highest_trackable_value) ||
        !enif_get_int(env, argv[1], &significant_figures))
    {
        return enif_make_badarg(env);
    }

    hdr_histogram_t* raw_histogram;

    int rc = 0;
    rc = hdr_alloc(highest_trackable_value, significant_figures, &raw_histogram);

    if (EINVAL == rc)
    {
        return make_error(env, "bad_significant_factor");
    }

    if (ENOMEM == rc)
    {
        return make_error(env, "not_enough_memory");
    }

    ErlNifResourceType* ctx_type = get_hh_ctx_type(env);
    hh_ctx_t* ctx = (hh_ctx_t*)enif_alloc_resource(ctx_type, sizeof(hh_ctx_t));

    ctx->data = raw_histogram; 
    ctx->highest_trackable_value = highest_trackable_value;
    ctx->significant_figures = significant_figures;

    ERL_NIF_TERM result = enif_make_resource(env, ctx);
    enif_release_resource(ctx);

    return enif_make_tuple2(env, ATOM_OK, result);
}
static char* log_reader_aggregates_into_single_histogram()
{
    const char* file_name = "histogram.log";
    hdr_timespec timestamp;
    hdr_timespec interval;

    hdr_gettime(&timestamp);
    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", &timestamp);
    hdr_log_write(&writer, log_file, &timestamp, &interval, cor_histogram);
    hdr_log_write(&writer, log_file, &timestamp, &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;
}
示例#14
0
int main ( int argc, char *argv[] )
{
     unsigned long int microdelta, interval_length, interval_diff, sample_desired_wait_time;
     int nfds,return_value, delay_microseconds, run_seconds, total_runtime_seconds;
     int fd, opt, quit=0;
     char buffer[128];
     char identifier[IDENTIFIER_SIZE];

     struct pollfd poll_list[256];
     struct itimerspec timeout;     
     struct timespec sample_start_time, sample_end_time, interval_start;
     struct timeval end;

     struct hdr_histogram *interval_histogram, *cumulative_histogram;
     
     // 10 seconds worth of microseconds 
     if (hdr_alloc(10000000, 3, &interval_histogram) == -1) {
	  printf("unable to allocate interval histogram\n");
	  exit (1);
     }
     if (hdr_alloc(10000000, 3, &cumulative_histogram) == -1) {
	  printf("unable to allocate cumulative histogram\n");
	  exit (1);
     }

     memset (buffer, 0, 128);
     memset (identifier, 0, IDENTIFIER_SIZE);
     
     // Timing and names
     // 
     // interval_length 		- this is the length of time between successive histogram line printouts
     // 
     // sample_desired_wait_time 	- this is the amount of time we set the timer to wait for. This should be 
     //               			  less than the jitter we're attempting to measure. Given the nature of this 
     //               			  program, this should always be less than 1 second. If it is not, you'll need to 
     //               			  modify the code below where we set the interval timer.  
     // sample_start_time, 
     // sample_end_time 		- The times associated with a single pass through the timing loop.
     // 
     // delay_microseconds	       	- An arbitrary amount of time we wait before starting anything. This is useful if
     // 				  you want to catch something, and there's a warm up period.
     // 				  For compatibility with jHiccup this is specified on the command line as millis. 
     // 
     // run_seconds			- The time we spend running the timing loops. 
     // 
     
     interval_length = 5;  			// 5 seconds per reporting interval 
     sample_desired_wait_time = 1000000; 	// 1 millisecond in nanoseconds.
     delay_microseconds = 0;
     run_seconds = 100000000;                   // forever, or near enough - 3 years. 
     
     while ( (opt = getopt(argc, argv, "d:l:r:vh"))  != -1) {
	  switch (opt) {
	  case 'd':
	       delay_microseconds = atoi(optarg) * 1000;
	       break;
	  case 'l':
	       strncpy(identifier, optarg, IDENTIFIER_SIZE-1);
	       break;
	  case 'r':
	       run_seconds = atoi(optarg);
	       break;
	  case 'v':
	       verbose_flag = 1;
	       break;
	  case 'h':
	  default:
	       usage();
	       exit(-1);
	  }
     }
     
     total_runtime_seconds = run_seconds + (delay_microseconds/1000000);
     
     open_files(identifier);
     
     if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC)) < 0) {
	  perror("timerfd_create; failed to create timer");
	  return -1;
     }
     
     zero_timeout(&timeout);
     interval_length = interval_length * 1000000000;  // convert to nanoseconds

     // set up the poll list structure. 
     memset (&poll_list, 0, (256*sizeof(struct pollfd)));
 
     poll_list[0].fd=fd;
     poll_list[0].events=POLLIN|POLLPRI|POLLRDHUP;
     poll_list[0].revents=0;
     nfds = 1;

     // get wall clock start time and push out a header 
     gettimeofday(&start,NULL);   
     print_header_line(log_file, &start);
     if (verbose_flag) print_header_line(stdout, &start);
     
     // we wait a set number of seconds before starting the test. 
     usleep(delay_microseconds);
     // get start of our delta interval measurement
     clock_gettime(CLOCK_MONOTONIC, &interval_start);
     
     while (!quit) {
	  timeout.it_value.tv_sec = 0;
	  timeout.it_value.tv_nsec = sample_desired_wait_time;
	  
	  // We arm the timer first (timerfd_settime), then get the time as quickly as possible. 
	  // We don't want to measure the time that timerfd_settime takes, so its a choice between
	  // under or over reporting the time, as clock_gettime is expected to be fast. 
	  timerfd_settime(fd, 0, &timeout, NULL);
	  clock_gettime(CLOCK_MONOTONIC,&sample_start_time);
	  return_value = poll(poll_list,nfds,-1);
	  clock_gettime(CLOCK_MONOTONIC,&sample_end_time);

	  // the the error value is anything other than EINTR we have a real problem. 
	  if ((return_value < 0) && (errno != EINTR))  {
	       perror("poll problem");
	       exit(-1);
	  }
	  
	  // read the timer to clear the event.
	  read(fd,buffer,8);
	  
	  // record the delta for both the interval and cumulative histograms. 
	  microdelta = nano_difftime(sample_start_time, sample_end_time)/1000;
	  
	  hdr_record_value(interval_histogram, microdelta);
	  hdr_record_value(cumulative_histogram, microdelta);

	  // See if we're due to print out an interval update. 
	  interval_diff = nano_difftime(interval_start, sample_end_time);
	  
	  if (interval_diff >= interval_length) {
	       // print progress
	       print_histogram_line(log_file, interval_histogram, cumulative_histogram);
	       if (verbose_flag) print_histogram_line(stdout, interval_histogram, cumulative_histogram);
	       print_full_histogram(histogram_file,cumulative_histogram);
	       // are we done?
	       gettimeofday(&end, NULL);
	       if (end.tv_sec >= (start.tv_sec + total_runtime_seconds)) quit++;
	       // reset the interval histogram.
	       hdr_reset(interval_histogram);
	       // reset the interval start timer. 
	       clock_gettime(CLOCK_MONOTONIC, &interval_start);
	  }
     }
     
     close(fd);
     
     exit (0);
}