summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2014-11-29 23:56:33 +0000
committerVincent Sanders <vince@kyllikki.org>2014-11-29 23:57:15 +0000
commitd08acbc5ae45feee602307c278c8bfe3a4bd3bfd (patch)
tree8f99f660d577cbd5d23cc733a2593843a8a79318 /content
parent70e777c30d7eeeb28591ca7769100059808aada8 (diff)
downloadnetsurf-d08acbc5ae45feee602307c278c8bfe3a4bd3bfd.tar.gz
netsurf-d08acbc5ae45feee602307c278c8bfe3a4bd3bfd.tar.bz2
correctly calculate writeout bandwidth and properly impose limits
Diffstat (limited to 'content')
-rw-r--r--content/fs_backing_store.c3
-rw-r--r--content/llcache.c82
2 files changed, 66 insertions, 19 deletions
diff --git a/content/fs_backing_store.c b/content/fs_backing_store.c
index 27cd95213..b2eaf781f 100644
--- a/content/fs_backing_store.c
+++ b/content/fs_backing_store.c
@@ -1230,6 +1230,9 @@ initialise(const struct llcache_store_parameters *parameters)
/**
* Finalise the backing store.
*
+ * \todo This will cause the backing store to leak any outstanding memory
+ * allocations. This will probably best be done by a global use count.
+ *
* @return NSERROR_OK on success.
*/
static nserror
diff --git a/content/llcache.c b/content/llcache.c
index e862f901c..2f7b82b68 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -2262,7 +2262,7 @@ build_candidate_list(struct llcache_object ***lst_out, int *lst_len_out)
int lst_len = 0;
int remaining_lifetime;
-#define MAX_PERSIST_PER_RUN 512
+#define MAX_PERSIST_PER_RUN 128
lst = calloc(MAX_PERSIST_PER_RUN, sizeof(struct llcache_object *));
if (lst == NULL) {
@@ -2379,14 +2379,18 @@ write_backing_store(struct llcache_object *object,
static void llcache_persist(void *p)
{
nserror ret;
- size_t size_written;
- size_t total_written = 0;
- struct llcache_object **lst;
- int lst_count;
- int idx;
- unsigned long write_limit; /* max number of bytes to write */
- unsigned long total_elapsed = 1;
- unsigned long elapsed;
+ struct llcache_object **lst; /* candidate object list */
+ int lst_count; /* number of candidates in list */
+ int idx; /* current candidate object index in list */
+
+ unsigned long write_limit; /* max number of bytes to write in this run*/
+
+ size_t written; /* all bytes written for a single object */
+ unsigned long elapsed; /* how long writing an object took */
+
+ size_t total_written = 0; /* total bytes written in this run */
+ unsigned long total_elapsed = 1; /* total ms used to write bytes */
+ unsigned long total_bandwidth = 0; /* total bandwidth */
ret = build_candidate_list(&lst, &lst_count);
if (ret != NSERROR_OK) {
@@ -2398,28 +2402,68 @@ static void llcache_persist(void *p)
/* obtained a candidate list, make each object persistant in turn */
for (idx = 0; idx < lst_count; idx++) {
- ret = write_backing_store(lst[idx], &size_written, &elapsed);
+ ret = write_backing_store(lst[idx], &written, &elapsed);
if (ret == NSERROR_OK) {
/* sucessfully wrote object to backing store */
- total_written += size_written;
+ total_written += written;
total_elapsed += elapsed;
- LOG(("Wrote %d bytes in %dms %s",
- size_written,
- elapsed,
+ total_bandwidth = (total_written * 1000) / total_elapsed;
+ LOG(("Wrote %d bytes in %dms bw:%d %s",
+ written, elapsed, (written * 1000) / elapsed,
nsurl_access(lst[idx]->url) ));
- if (total_written > write_limit) {
- /* The bandwidth limit has been reached.
- * Writeout scheduled for the remaining objects
+ /* check to for the time quantum or the size
+ * (bandwidth) for this run being exceeded.
+ */
+ if (total_elapsed > llcache->time_quantum) {
+ /* writeout has exhausted the available time.
+ * Either the writeout is slow or the last
+ * object was very large.
*/
- guit->browser->schedule(llcache->time_quantum, llcache_persist, NULL);
+ if (total_bandwidth < llcache->minimum_bandwidth) {
+ LOG(("Cannot write minimum bandwidth"));
+ warn_user("Disc cache write bandwidth is too slow to be useful, disabling cache", 0);
+ guit->llcache->finalise();
+ break;
+ } else {
+ unsigned long next;
+ if (total_bandwidth > llcache->maximum_bandwidth) {
+ /* fast writeout of large file
+ * so calculate delay as if
+ * write happened only at max
+ * limit
+ */
+ next = ((total_written * llcache->time_quantum) / write_limit) - total_elapsed;
+ } else {
+ next = llcache->time_quantum;
+ }
+ LOG(("Overran our timeslot Rescheduling writeout in %dms", next));
+ guit->browser->schedule(next,
+ llcache_persist, NULL);
+ break;
+ }
+ } else if (total_written > write_limit) {
+ /* The bandwidth limit has been reached. */
+ unsigned long next;
+ if (total_bandwidth > llcache->maximum_bandwidth) {
+ /* fast writeout of large file so
+ * calculate delay as if write
+ * happened only at max limit
+ */
+ next = ((total_written * llcache->time_quantum) / write_limit) - total_elapsed;
+ } else {
+ next = llcache->time_quantum - total_elapsed;
+ }
+ LOG(("Rescheduling writeout in %dms", next));
+ guit->browser->schedule(next, llcache_persist,
+ NULL);
break;
}
}
}
LOG(("writeout size:%d time:%d bandwidth:%dbytes/s",
- total_written, total_elapsed, (total_written * 1000) / total_elapsed));
+ total_written, total_elapsed, total_bandwidth));
free(lst);
}