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);
}
Esempio n. 3
0
void stats_record(stats *stats, uint64_t x) {
    if (x < stats->min) stats->min = x;
    if (x > stats->max) stats->max = x;
    if (stats->histogram != NULL) {
        hdr_record_value(stats->histogram, x);
        return;
    }

    stats->data[stats->index++] = x;
    if (stats->limit < stats->samples)  stats->limit++;
    if (stats->index == stats->samples) stats->index = 0;
}
Esempio n. 4
0
int process_msg(struct msghdr *msg, char *buffer, struct hdr_histogram *hist)
{
    struct timeval tx_timestamp;
    struct timeval rx_timestamp;
    int tx_rx = 0;

    for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
         cmsg;
         cmsg = CMSG_NXTHDR(msg, cmsg))
    {
        switch (cmsg->cmsg_level)
        {
        case SOL_SOCKET:
            switch (cmsg->cmsg_type)
            {
            case SO_TIMESTAMPNS:
            {
                struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
                rx_timestamp.tv_sec = stamp->tv_sec;
                rx_timestamp.tv_usec = stamp->tv_nsec / 1000;
                tx_rx += 1;
                break;
            }
            default:
                break;
            }
        case IPPROTO_IP:
            if (pktgen_packet(buffer, &tx_timestamp)) {
                tx_rx += 1;
                break;
            } else {
                return 0;
            }
        default:
            break;
        }
    }

    if (tx_rx == 2) {
        uint64_t latency = ((rx_timestamp.tv_sec - tx_timestamp.tv_sec) / 1000000) +
                           (rx_timestamp.tv_usec - tx_timestamp.tv_usec);
        hdr_record_value(hist, latency);
        return 1;
    }
    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;
}
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;
}
Esempio n. 8
0
static bool disk_scan_part(disk_t *disk, uint64_t offset, void *data, int data_size, struct scan_state *state)
{
	ssize_t ret;
	struct timespec t_start;
	struct timespec t_end;
	uint64_t t;
	int error = 0;
	io_result_t io_res;

	clock_gettime(CLOCK_MONOTONIC, &t_start);
	ret = disk_dev_read(&disk->dev, offset, data_size, data, &io_res);
	clock_gettime(CLOCK_MONOTONIC, &t_end);

	t = (t_end.tv_sec - t_start.tv_sec) * 1000000000 +
		t_end.tv_nsec - t_start.tv_nsec;
	const uint64_t t_msec = t / 1000000;

	// Perform logging
	data_log_raw(&disk->data_raw, offset/disk->sector_size, data_size/disk->sector_size, &io_res, t);
	data_log(&disk->data_log, offset/disk->sector_size, data_size/disk->sector_size, &io_res, t);

	// Handle error or incomplete data
	if (io_res.data != DATA_FULL || io_res.error != ERROR_NONE) {
		int s_errno = errno;
		ERROR("Error when reading at offset %" PRIu64 " size %d read %zd, errno=%d: %s", offset, data_size, ret, errno, strerror(errno));
		ERROR("Details: error=%s data=%s %02X/%02X/%02X", error_to_str(io_res.error), data_to_str(io_res.data),
				io_res.info.sense_key, io_res.info.asc, io_res.info.ascq);
		report_scan_error(disk, offset, data_size, t);
		disk->num_errors++;
		error = 1;
		if (io_res.error == ERROR_FATAL) {
			ERROR("Fatal error occurred, bailing out.");
			return false;
		}
		if (io_res.error == ERROR_UNKNOWN) {
			if (state->num_unknown_errors++ > 500) {
				ERROR("%u unknown errors occurred, assuming fatal issue.", state->num_unknown_errors);
				return false;
			}
			ERROR("Unknown error occurred, possibly untranslated error by storage layers, trying to continue.");

		}

		if (s_errno != EIO && s_errno != 0)
			abort();
		// TODO: What to do when no everything was read but errno is zero?
	}
	else {
		state->num_unknown_errors = 0; // Clear non-consecutive unknown errors
		report_scan_success(disk, offset, data_size, t);
	}

	hdr_record_value(disk->histogram, t / 1000);
	latency_bucket_add(disk, t_msec, state);

	if (t_msec > 1000) {
		VERBOSE("Scanning at offset %" PRIu64 " took %"PRIu64" msec", offset, t_msec);
	}

	if (disk->fix && (t_msec > 3000 || error)) {
		if (io_res.error != ERROR_UNCORRECTED) {
			INFO("Fixing region by rewriting, offset=%"PRIu64" size=%d", offset, data_size);
			ret = disk_dev_write(&disk->dev, offset, data_size, data, &io_res);
			if (ret != data_size) {
				ERROR("Error while attempting to rewrite the data! ret=%zd errno=%d: %s", ret, errno, strerror(errno));
			}
		} else {
			// When we correct uncorrectable errors we want to zero it out, this should reduce any confusion later on when the data is read
			unsigned fix_offset = 0;
			int fix_size = 4096;

			if (data_size < fix_size)
				fix_size = data_size;

			for (; data_size >= (int)(fix_offset + fix_size); fix_offset += fix_size) {
				disk_dev_read(&disk->dev, offset+fix_offset, fix_size, data, &io_res);
				if (io_res.error == ERROR_UNCORRECTED) {
					INFO("Fixing uncorrectable region by writing zeros, offset=%"PRIu64" size=%d", offset+fix_offset, fix_size);
					memset(data, 0, fix_size);
					ret = disk_dev_write(&disk->dev, offset+fix_offset, fix_size, data, &io_res);
					if (ret != data_size) {
						ERROR("Error while attempting to overwrite uncorrectable data! ret=%zd errno=%d: %s", ret, errno, strerror(errno));
					}
				}
			}
		}
	}

	return true;
}
Esempio n. 9
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);
} 
Esempio n. 10
0
 void record_value(int64_t value) {
   int64_t critical_value_enter = phaser_.writer_critical_section_enter();
   hdr_histogram* h = histograms_[active_index_.load()];
   hdr_record_value(h, value);
   phaser_.writer_critical_section_end(critical_value_enter);
 }
Esempio n. 11
0
      void record_value(int64_t value) {
        hdr_record_value(histogram_, value);

      }