mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Use a single scheduling point for sync
This commit is contained in:
parent
d2bad33af8
commit
541665db46
3 changed files with 56 additions and 3 deletions
34
cmdline/io.c
34
cmdline/io.c
|
|
@ -489,7 +489,7 @@ static void io_write_next_outside(struct snapraid_io* io)
|
|||
*
|
||||
* It must be called inside the lock.
|
||||
*/
|
||||
static void io_write_next_inside(struct snapraid_io* io, unsigned blockcur, int skip, int* writer_error)
|
||||
static void io_write_next_inside(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
|
@ -537,6 +537,38 @@ void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* wri
|
|||
#endif
|
||||
}
|
||||
|
||||
block_off_t io_write_and_read_next(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error, void*** buffer)
|
||||
{
|
||||
block_off_t blockcur_schedule;
|
||||
block_off_t blockcur_caller;
|
||||
|
||||
io_write_next_outside(io);
|
||||
blockcur_schedule = io_read_next_outside(io);
|
||||
|
||||
/* the synchronization is protected by the io mutex */
|
||||
pthread_mutex_lock(&io->mutex);
|
||||
|
||||
io_write_next_inside(io, blockcur, skip, writer_error);
|
||||
|
||||
blockcur_caller = io_read_next_inside(io, blockcur_schedule, buffer);
|
||||
|
||||
#ifndef CHECKER
|
||||
/* without the thread checker unlock before signaling, */
|
||||
/* this reduces the number of context switches */
|
||||
pthread_mutex_unlock(&io->mutex);
|
||||
#endif
|
||||
|
||||
/* signal all the workers that there is a new pending task */
|
||||
pthread_cond_broadcast(&io->write_sched);
|
||||
pthread_cond_broadcast(&io->read_sched);
|
||||
|
||||
#ifdef CHECKER
|
||||
pthread_mutex_unlock(&io->mutex);
|
||||
#endif
|
||||
|
||||
return blockcur_caller;
|
||||
}
|
||||
|
||||
void io_refresh(struct snapraid_io* io)
|
||||
{
|
||||
unsigned i;
|
||||
|
|
|
|||
|
|
@ -365,6 +365,14 @@ void io_parity_write(struct snapraid_io* io, unsigned* levcur, unsigned* waiting
|
|||
*/
|
||||
void io_write_next(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error);
|
||||
|
||||
/**
|
||||
* Next write and read position.
|
||||
*
|
||||
* It's a combination of io_write_next() and io_read_next() that
|
||||
* locks only one time the scheduling mutex.
|
||||
*/
|
||||
block_off_t io_write_and_read_next(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error, void*** buffer);
|
||||
|
||||
/**
|
||||
* Refresh the number of cached blocks for all data and parity disks.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -686,6 +686,8 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
unsigned l;
|
||||
unsigned* waiting_map;
|
||||
unsigned waiting_mac;
|
||||
block_off_t blocknext;
|
||||
void** buffernext;
|
||||
|
||||
/* the sync process assumes that all the hashes are correct */
|
||||
/* including the ones from CHG and DELETED blocks */
|
||||
|
|
@ -754,6 +756,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
if (!state_progress_begin(state, blockstart, blockmax, countmax))
|
||||
goto end;
|
||||
|
||||
/* scheduling helper */
|
||||
buffernext = 0;
|
||||
blocknext = 0;
|
||||
|
||||
while (1) {
|
||||
unsigned failed_count;
|
||||
int error_on_this_block;
|
||||
|
|
@ -768,7 +774,14 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
int writer_error[IO_WRITER_ERROR_MAX];
|
||||
|
||||
/* go to the next block */
|
||||
blockcur = io_read_next(&io, &buffer);
|
||||
if (buffernext != 0) {
|
||||
/* if already computed, use it */
|
||||
buffer = buffernext;
|
||||
blockcur = blocknext;
|
||||
} else {
|
||||
/* otherwise do it now */
|
||||
blockcur = io_read_next(&io, &buffer);
|
||||
}
|
||||
if (blockcur >= blockmax)
|
||||
break;
|
||||
|
||||
|
|
@ -1227,7 +1240,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
}
|
||||
|
||||
/* write finished */
|
||||
io_write_next(&io, blockcur, !parity_going_to_be_updated, writer_error);
|
||||
blocknext = io_write_and_read_next(&io, blockcur, !parity_going_to_be_updated, writer_error, &buffernext);
|
||||
|
||||
/* handle errors reported */
|
||||
for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue