struct worker_thread {
pthread_t thread;
+ volatile int done;
+
int fd;
uint64_t cur_offset;
uint64_t size;
static unsigned int dump_output;
static unsigned int odirect;
static unsigned int collision_check;
+static unsigned int print_progress = 1;
static uint64_t total_size;
static uint64_t cur_offset;
}
} while (1);
+ thread->done = 1;
fio_memfree(buf, blocksize);
return NULL;
}
static int __dedupe_check(int fd, uint64_t dev_size)
{
struct worker_thread *threads;
- unsigned long nitems;
+ unsigned long nitems, total_items;
int i, err = 0;
total_size = dev_size;
+ total_items = dev_size / blocksize;
cur_offset = 0;
size_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
threads[i].fd = fd;
threads[i].items = 0;
threads[i].err = 0;
+ threads[i].done = 0;
err = pthread_create(&threads[i].thread, NULL, thread_fn, &threads[i]);
if (err) {
}
}
+ while (print_progress) {
+ float perc;
+ int some_done;
+
+ nitems = 0;
+ for (i = 0; i < num_threads; i++) {
+ nitems += threads[i].items;
+ some_done = threads[i].done;
+ if (some_done)
+ break;
+ }
+
+ if (some_done)
+ break;
+
+ perc = (float) nitems / (float) total_items;
+ perc *= 100.0;
+ printf("%3.2f%% done\r", perc);
+ fflush(stdout);
+ usleep(200000);
+ };
+
nitems = 0;
for (i = 0; i < num_threads; i++) {
void *ret;
} while ((n = rb_next(n)) != NULL);
- printf("Chunks=%lu, Extents=%lu\n", nchunks, nextents);
+ printf("Extents=%lu, Unique extents=%lu\n", nextents, nchunks);
printf("De-dupe factor: %3.2f\n", (double) nextents / (double) nchunks);
perc = 1.00 - ((double) nchunks / (double) nextents);
perc *= 100.0;
- printf("dedupe_percentage=%u\n", (int) (perc + 0.50));
+ printf("Fio setting: dedupe_percentage=%u\n", (int) (perc + 0.50));
}
static int usage(char *argv[])
log_err("\t-d\tFull extent/chunk debug output\n");
log_err("\t-o\tUse O_DIRECT\n");
log_err("\t-c\tFull collision check\n");
+ log_err("\t-p\tPrint progress indicator\n");
return 1;
}
{
int c, ret;
- while ((c = getopt(argc, argv, "b:t:d:o:c:")) != -1) {
+ while ((c = getopt(argc, argv, "b:t:d:o:c:p:")) != -1) {
switch (c) {
case 'b':
blocksize = atoi(optarg);
case 'c':
collision_check = atoi(optarg);
break;
+ case 'p':
+ print_progress = atoi(optarg);
+ break;
case '?':
default:
return usage(argv);