make dirty_page_table_flush be reentrant; fix possible dereference of null pointer
This commit is contained in:
parent
6f0c50d861
commit
d26da056b7
1 changed files with 15 additions and 21 deletions
|
@ -41,7 +41,6 @@ struct stasis_dirty_page_table_t {
|
||||||
int flushing;
|
int flushing;
|
||||||
|
|
||||||
pthread_cond_t writebackCond;
|
pthread_cond_t writebackCond;
|
||||||
lsn_t targetLsn;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void stasis_dirty_page_table_set_dirty(stasis_dirty_page_table_t * dirtyPages, Page * p) {
|
void stasis_dirty_page_table_set_dirty(stasis_dirty_page_table_t * dirtyPages, Page * p) {
|
||||||
|
@ -93,15 +92,7 @@ void stasis_dirty_page_table_set_clean(stasis_dirty_page_table_t * dirtyPages, P
|
||||||
assert(p->dirty);
|
assert(p->dirty);
|
||||||
p->dirty = 0;
|
p->dirty = 0;
|
||||||
|
|
||||||
lsn_t targetLsn = dirtyPages->targetLsn;
|
|
||||||
if (e->lsn < targetLsn) {
|
|
||||||
const dpt_entry * e2 = rbmin(dirtyPages->tableByLsnAndPage);
|
|
||||||
|
|
||||||
if (!e2 || e2->lsn >= targetLsn) {
|
|
||||||
dirtyPages->targetLsn = 0;
|
|
||||||
pthread_cond_broadcast( &dirtyPages->writebackCond );
|
pthread_cond_broadcast( &dirtyPages->writebackCond );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirtyPages->count--;
|
dirtyPages->count--;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +138,9 @@ int stasis_dirty_page_table_flush_with_target(stasis_dirty_page_table_t * dirtyP
|
||||||
if(dirtyPages->flushing) {
|
if(dirtyPages->flushing) {
|
||||||
pthread_cond_wait(&dirtyPages->flushDone, &dirtyPages->mutex);
|
pthread_cond_wait(&dirtyPages->flushDone, &dirtyPages->mutex);
|
||||||
pthread_mutex_unlock(&dirtyPages->mutex);
|
pthread_mutex_unlock(&dirtyPages->mutex);
|
||||||
|
// We return EAGAIN here because the other flush may have begun
|
||||||
|
// before some page that this flush is interested in was
|
||||||
|
// written.
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
dirtyPages->flushing = 1;
|
dirtyPages->flushing = 1;
|
||||||
|
@ -184,14 +178,15 @@ int stasis_dirty_page_table_flush_with_target(stasis_dirty_page_table_t * dirtyP
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&dirtyPages->mutex);
|
pthread_mutex_lock(&dirtyPages->mutex);
|
||||||
|
|
||||||
|
dpt_entry * e = ((dpt_entry*)rbmin(dirtyPages->tableByLsnAndPage));
|
||||||
|
|
||||||
if (!all_flushed &&
|
if (!all_flushed &&
|
||||||
targetLsn < LSN_T_MAX &&
|
targetLsn < LSN_T_MAX &&
|
||||||
dirtyPages->count > 0 &&
|
dirtyPages->count > 0 &&
|
||||||
targetLsn > ((dpt_entry*)rbmin(dirtyPages->tableByLsnAndPage))->lsn ) {
|
e && targetLsn > e->lsn ) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
dirtyPages->targetLsn = targetLsn;
|
|
||||||
all_flushed = 1;
|
all_flushed = 1;
|
||||||
|
|
||||||
int res = gettimeofday(&tv, 0);
|
int res = gettimeofday(&tv, 0);
|
||||||
|
@ -211,11 +206,14 @@ int stasis_dirty_page_table_flush_with_target(stasis_dirty_page_table_t * dirtyP
|
||||||
ts.tv_sec = tv.tv_sec;
|
ts.tv_sec = tv.tv_sec;
|
||||||
ts.tv_nsec = 1000*tv.tv_usec;
|
ts.tv_nsec = 1000*tv.tv_usec;
|
||||||
|
|
||||||
while ( dirtyPages->targetLsn != 0 ) {
|
dpt_entry * e = ((dpt_entry*)rbmin(dirtyPages->tableByLsnAndPage));
|
||||||
|
|
||||||
|
while( e && targetLsn > e->lsn ) {
|
||||||
if (pthread_cond_timedwait(&dirtyPages->writebackCond, &dirtyPages->mutex, &ts) == ETIMEDOUT) {
|
if (pthread_cond_timedwait(&dirtyPages->writebackCond, &dirtyPages->mutex, &ts) == ETIMEDOUT) {
|
||||||
all_flushed = 0;
|
all_flushed = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
e = ((dpt_entry*)rbmin(dirtyPages->tableByLsnAndPage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(!all_flushed);
|
} while(!all_flushed);
|
||||||
|
@ -226,9 +224,6 @@ int stasis_dirty_page_table_flush_with_target(stasis_dirty_page_table_t * dirtyP
|
||||||
|
|
||||||
pthread_mutex_unlock(&dirtyPages->mutex);
|
pthread_mutex_unlock(&dirtyPages->mutex);
|
||||||
|
|
||||||
|
|
||||||
// if(strides < 5) { DEBUG("strides: %d dirtyCount = %lld\n", strides, stasis_dirty_page_table_dirty_count(dirtyPages)); }
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +303,6 @@ stasis_dirty_page_table_t * stasis_dirty_page_table_init() {
|
||||||
pthread_mutex_init(&ret->mutex, 0);
|
pthread_mutex_init(&ret->mutex, 0);
|
||||||
pthread_cond_init(&ret->flushDone, 0);
|
pthread_cond_init(&ret->flushDone, 0);
|
||||||
ret->flushing = 0;
|
ret->flushing = 0;
|
||||||
ret->targetLsn = 0;
|
|
||||||
pthread_cond_init(&ret->writebackCond, 0);
|
pthread_cond_init(&ret->writebackCond, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue