mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -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.
|
* 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;
|
unsigned i;
|
||||||
|
|
||||||
|
|
@ -537,6 +537,38 @@ void io_write_next(struct snapraid_io* io, unsigned blockcur, int skip, int* wri
|
||||||
#endif
|
#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)
|
void io_refresh(struct snapraid_io* io)
|
||||||
{
|
{
|
||||||
unsigned i;
|
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);
|
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.
|
* 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 l;
|
||||||
unsigned* waiting_map;
|
unsigned* waiting_map;
|
||||||
unsigned waiting_mac;
|
unsigned waiting_mac;
|
||||||
|
block_off_t blocknext;
|
||||||
|
void** buffernext;
|
||||||
|
|
||||||
/* the sync process assumes that all the hashes are correct */
|
/* the sync process assumes that all the hashes are correct */
|
||||||
/* including the ones from CHG and DELETED blocks */
|
/* 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))
|
if (!state_progress_begin(state, blockstart, blockmax, countmax))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
/* scheduling helper */
|
||||||
|
buffernext = 0;
|
||||||
|
blocknext = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
unsigned failed_count;
|
unsigned failed_count;
|
||||||
int error_on_this_block;
|
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];
|
int writer_error[IO_WRITER_ERROR_MAX];
|
||||||
|
|
||||||
/* go to the next block */
|
/* 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)
|
if (blockcur >= blockmax)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1227,7 +1240,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write finished */
|
/* 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 */
|
/* handle errors reported */
|
||||||
for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
|
for (j = 0; j < IO_WRITER_ERROR_MAX; ++j) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue