mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Protect rate limiter state updates with a mutex to prevent data races
This commit is contained in:
parent
b4a694bb10
commit
eebb3943e5
4 changed files with 34 additions and 1 deletions
23
cmdline/bw.c
23
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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue