Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
timeshift: add 'Fit to RAM' option' to reduce disk I/O
  • Loading branch information
perexg committed Jan 4, 2016
1 parent 80a50ce commit 3b59d92
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
10 changes: 10 additions & 0 deletions src/timeshift.c
Expand Up @@ -224,6 +224,14 @@ const idclass_t timeshift_conf_class = {
.name = N_("RAM only"),
.off = offsetof(timeshift_conf_t, ram_only),
},
{
.type = PT_BOOL,
.id = "ram_fit",
.name = N_("Fit to RAM (cut rewind)"),
.desc = N_("If possible, maintain the timeshift data in the server memory only. "
"This may reduce the amount of allowed rewind time."),
.off = offsetof(timeshift_conf_t, ram_fit),
},
{}
}
};
Expand Down Expand Up @@ -431,6 +439,8 @@ streaming_target_t *timeshift_create
ts->ref_time = 0;
ts->seek.file = NULL;
ts->seek.frame = NULL;
ts->ram_segments = 0;
ts->file_segments = 0;
for (i = 0; i < TIMESHIFT_BACKLOG_MAX; i++)
TAILQ_INIT(&ts->backlog[i]);
pthread_mutex_init(&ts->state_mutex, NULL);
Expand Down
1 change: 1 addition & 0 deletions src/timeshift.h
Expand Up @@ -35,6 +35,7 @@ typedef struct timeshift_conf {
uint64_t ram_segment_size;
uint64_t total_ram_size;
int ram_only;
int ram_fit;
} timeshift_conf_t;

extern struct timeshift_conf timeshift_conf;
Expand Down
3 changes: 3 additions & 0 deletions src/timeshift/private.h
Expand Up @@ -129,6 +129,9 @@ typedef struct timeshift {

timeshift_file_list_t files; ///< List of files

int ram_segments; ///< Count of segments in RAM
int file_segments; ///< Count of segments in files

int vididx; ///< Index of (current) video stream

} timeshift_t;
Expand Down
43 changes: 32 additions & 11 deletions src/timeshift/timeshift_filemgr.c
Expand Up @@ -205,6 +205,13 @@ void timeshift_filemgr_remove
ts->id, tsf->time, (int64_t)tsf->size, (int64_t)tsf->ram_size);
}
TAILQ_REMOVE(&ts->files, tsf, link);
if (tsf->path) {
assert(ts->file_segments > 0);
ts->file_segments--;
} else {
assert(ts->ram_segments > 0);
ts->ram_segments--;
}
atomic_dec_u64(&timeshift_total_size, tsf->size);
if (tsf->ram)
atomic_dec_u64(&timeshift_total_ram_size, tsf->size);
Expand Down Expand Up @@ -310,18 +317,31 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time )
tvhtrace("timeshift", "ts %d RAM total %"PRId64" requested %"PRId64" segment %"PRId64,
ts->id, atomic_pre_add_u64(&timeshift_total_ram_size, 0),
timeshift_conf.ram_size, timeshift_conf.ram_segment_size);
if (timeshift_conf.ram_size >= 8*1024*1024 &&
atomic_pre_add_u64(&timeshift_total_ram_size, 0) <
timeshift_conf.ram_size + (timeshift_conf.ram_segment_size / 2)) {
tsf_tmp = timeshift_filemgr_file_init(ts, start_time);
tsf_tmp->ram_size = MIN(16*1024*1024, timeshift_conf.ram_segment_size);
tsf_tmp->ram = malloc(tsf_tmp->ram_size);
if (!tsf_tmp->ram) {
free(tsf_tmp);
tsf_tmp = NULL;
while (1) {
if (timeshift_conf.ram_size >= 8*1024*1024 &&
atomic_pre_add_u64(&timeshift_total_ram_size, 0) <
timeshift_conf.ram_size + (timeshift_conf.ram_segment_size / 2)) {
tsf_tmp = timeshift_filemgr_file_init(ts, start_time);
tsf_tmp->ram_size = MIN(16*1024*1024, timeshift_conf.ram_segment_size);
tsf_tmp->ram = malloc(tsf_tmp->ram_size);
if (!tsf_tmp->ram) {
free(tsf_tmp);
tsf_tmp = NULL;
} else {
tvhtrace("timeshift", "ts %d create RAM segment with %"PRId64" bytes (time %"PRId64")",
ts->id, tsf_tmp->ram_size, start_time);
ts->ram_segments++;
}
break;
} else {
tvhtrace("timeshift", "ts %d create RAM segment with %"PRId64" bytes (time %"PRId64")",
ts->id, tsf_tmp->ram_size, start_time);
tsf_hd = TAILQ_FIRST(&ts->files);
if (timeshift_conf.ram_fit && tsf_hd && !tsf_hd->refcount &&
tsf_hd->ram && ts->file_segments == 0) {
tvhtrace("timeshift", "ts %d remove RAM segment %"PRId64" (fit)", ts->id, tsf_hd->time);
timeshift_filemgr_remove(ts, tsf_hd, 0);
} else {
break;
}
}
}

Expand All @@ -340,6 +360,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time )
tsf_tmp = timeshift_filemgr_file_init(ts, start_time);
tsf_tmp->wfd = fd;
tsf_tmp->path = strdup(path);
ts->file_segments++;
}
}

Expand Down

0 comments on commit 3b59d92

Please sign in to comment.