diff --git a/cmdline/bw.c b/cmdline/bw.c index bb64c12e..7d857745 100644 --- a/cmdline/bw.c +++ b/cmdline/bw.c @@ -10,6 +10,18 @@ void bw_init(struct snapraid_bw* bw, uint64_t limit) bw->limit = limit; bw->total = 0; bw->start = os_tick_ms(); +#if HAVE_THREAD + thread_mutex_init(&bw->lock); +#endif +} + +void bw_done(struct snapraid_bw* bw) +{ +#if HAVE_THREAD + thread_mutex_destroy(&bw->lock); +#else + (void)bw; +#endif } void bw_limit(struct snapraid_bw* bw, uint64_t bytes) @@ -17,13 +29,18 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes) if (!bw || bw->limit == 0) return; +#if HAVE_THREAD + thread_mutex_lock(&bw->lock); +#endif + uint64_t start = bw->start; uint64_t now = os_tick_ms(); uint64_t elapsed = now - start; uint64_t done; uint64_t eta; - done = __atomic_fetch_add(&bw->total, bytes, __ATOMIC_SEQ_CST); + bw->total += bytes; + done = bw->total; eta = done * 1000 / bw->limit; @@ -39,6 +56,10 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes) elapsed = eta + 10000; } +#if HAVE_THREAD + thread_mutex_unlock(&bw->lock); +#endif + if (eta > elapsed) { eta -= elapsed; if (eta > 1000) diff --git a/cmdline/bw.h b/cmdline/bw.h index f74a4d97..9ba69e12 100644 --- a/cmdline/bw.h +++ b/cmdline/bw.h @@ -14,6 +14,9 @@ struct snapraid_bw { uint64_t limit; /**< Bandwidth limit in bytes per second */ uint64_t total; /**< Remaining bytes allowed in current second */ uint64_t start; /**< Time when to reset the bandwidth counter */ +#if HAVE_THREAD + thread_mutex_t lock; /**< Mutex protecting bw fields */ +#endif }; /** @@ -21,6 +24,11 @@ struct snapraid_bw { */ void bw_init(struct snapraid_bw* bw, uint64_t limit); +/** + * Destroy the bandwidth limit + */ +void bw_done(struct snapraid_bw* bw); + /** * Limit IO bandwidth to stay within the configured limit. * If no limit is set, returns immediately. diff --git a/cmdline/check.c b/cmdline/check.c index eb286a06..bf6fafed 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -2147,6 +2147,8 @@ bail: free(buffer_alloc); free(buffer); + bw_done(&bw); + /* fail if some error are present after the run */ if (fix) { if (state->opt.expect_unrecoverable) { diff --git a/cmdline/io.c b/cmdline/io.c index 56d7ba57..2af97c30 100644 --- a/cmdline/io.c +++ b/cmdline/io.c @@ -1138,6 +1138,8 @@ void io_done(struct snapraid_io* io) free(io->writer_map); free(io->writer_list); + bw_done(&io->bw); + #if HAVE_THREAD if (io->io_max > 1) { thread_mutex_destroy(&io->io_mutex);