summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2011-09-10 00:55:39 +0000
committerVincent Sanders <vince@netsurf-browser.org>2011-09-10 00:55:39 +0000
commit2d33a8f85a83ceaf55dd5ab6a9e363191bfe3c08 (patch)
treec470aa1525dc7835bf2918ccab4138f956f7f828
parentcbeffd4c5f4ac2ecbb2cfc97a705441a20ec8f23 (diff)
downloadnetsurf-2d33a8f85a83ceaf55dd5ab6a9e363191bfe3c08.tar.gz
netsurf-2d33a8f85a83ceaf55dd5ab6a9e363191bfe3c08.tar.bz2
Make high level cache, low level cache and image cache all be initialised from passed parameters
Calculate all cache sizes from single memory cache size option and sanity check have a single global struct to hold all parameters instead of several individual variables svn path=/trunk/netsurf/; revision=12784
-rw-r--r--content/hlcache.c143
-rw-r--r--content/llcache.c89
-rw-r--r--content/llcache.h2
-rw-r--r--desktop/netsurf.c29
-rw-r--r--image/image_cache.c12
5 files changed, 161 insertions, 114 deletions
diff --git a/content/hlcache.c b/content/hlcache.c
index 6dccc6f88..db25f08ad 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -42,7 +42,7 @@ typedef struct hlcache_retrieval_ctx hlcache_retrieval_ctx;
struct hlcache_retrieval_ctx {
struct hlcache_retrieval_ctx *r_prev; /**< Previous retrieval context in the ring */
struct hlcache_retrieval_ctx *r_next; /**< Next retrieval context in the ring */
-
+
llcache_handle *llcache; /**< Low-level cache handle */
hlcache_handle *handle; /**< High-level handle for object */
@@ -70,7 +70,7 @@ struct hlcache_entry {
hlcache_entry *prev; /**< Previous sibling */
};
-/** Current state of the cache.
+/** Current state of the cache.
*
* Global state of the cache.
*/
@@ -84,6 +84,8 @@ struct hlcache_s {
hlcache_retrieval_ctx *retrieval_ctx_ring;
/* statsistics */
+ unsigned int hit_count;
+ unsigned int miss_count;
};
/** high level cache state */
@@ -96,7 +98,7 @@ static nserror hlcache_llcache_callback(llcache_handle *handle,
const llcache_event *event, void *pw);
static nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
lwc_string *effective_type);
-static bool hlcache_type_is_acceptable(lwc_string *mime_type,
+static bool hlcache_type_is_acceptable(lwc_string *mime_type,
content_type accepted_types, content_type *computed_type);
static nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
lwc_string *effective_type);
@@ -117,8 +119,9 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
return NSERROR_NOMEM;
}
- ret = llcache_initialise(hlcache_parameters->cb,
- hlcache_parameters->cb_ctx);
+ ret = llcache_initialise(hlcache_parameters->cb,
+ hlcache_parameters->cb_ctx,
+ hlcache_parameters->limit);
if (ret != NSERROR_OK) {
free(hlcache);
hlcache = NULL;
@@ -126,10 +129,10 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters)
}
hlcache->params = *hlcache_parameters;
-
+
/* Schedule the cache cleanup */
schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL);
-
+
return NSERROR_OK;
}
@@ -146,22 +149,22 @@ void hlcache_finalise(void)
uint32_t num_contents, prev_contents;
hlcache_entry *entry;
hlcache_retrieval_ctx *ctx, *next;
-
+
/* Obtain initial count of contents remaining */
- for (num_contents = 0, entry = hlcache->content_list;
+ for (num_contents = 0, entry = hlcache->content_list;
entry != NULL; entry = entry->next) {
num_contents++;
}
LOG(("%d contents remain before cache drain", num_contents));
-
+
/* Drain cache */
do {
prev_contents = num_contents;
hlcache_clean(NULL);
- for (num_contents = 0, entry = hlcache->content_list;
+ for (num_contents = 0, entry = hlcache->content_list;
entry != NULL; entry = entry->next) {
num_contents++;
}
@@ -172,7 +175,7 @@ void hlcache_finalise(void)
hlcache_handle entry_handle = { entry, NULL, NULL };
if (entry->content != NULL) {
- LOG((" %p : %s (%d users)", entry,
+ LOG((" %p : %s (%d users)", entry,
content_get_url(&entry_handle), content_count_users(entry->content)));
} else {
LOG((" %p", entry));
@@ -203,9 +206,13 @@ void hlcache_finalise(void)
hlcache->retrieval_ctx_ring = NULL;
}
+ LOG(("hit/miss %d/%d", hlcache->hit_count, hlcache->miss_count));
+
free(hlcache);
hlcache = NULL;
+ LOG(("Finalising low-level cache"));
+ llcache_finalise();
}
/* See hlcache.h for documentation */
@@ -221,7 +228,7 @@ nserror hlcache_poll(void)
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
const char *referer, llcache_post_data *post,
hlcache_handle_callback cb, void *pw,
- hlcache_child_context *child,
+ hlcache_child_context *child,
content_type accepted_types, hlcache_handle **result)
{
hlcache_retrieval_ctx *ctx;
@@ -257,8 +264,8 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
ctx->handle->cb = cb;
ctx->handle->pw = pw;
- error = llcache_handle_retrieve(url, flags, referer, post,
- hlcache_llcache_callback, ctx,
+ error = llcache_handle_retrieve(url, flags, referer, post,
+ hlcache_llcache_callback, ctx,
&ctx->llcache);
if (error != NSERROR_OK) {
free((char *) ctx->child.charset);
@@ -266,9 +273,9 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
free(ctx);
return error;
}
-
+
RING_INSERT(hlcache->retrieval_ctx_ring, ctx);
-
+
*result = ctx->handle;
return NSERROR_OK;
@@ -278,14 +285,14 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
nserror hlcache_handle_release(hlcache_handle *handle)
{
if (handle->entry != NULL) {
- content_remove_user(handle->entry->content,
+ content_remove_user(handle->entry->content,
hlcache_content_callback, handle);
} else {
RING_ITERATE_START(struct hlcache_retrieval_ctx,
hlcache->retrieval_ctx_ring,
ictx) {
if (ictx->handle == handle) {
- /* This is the nascent context for us,
+ /* This is the nascent context for us,
* so abort the fetch */
llcache_handle_abort(ictx->llcache);
llcache_handle_release(ictx->llcache);
@@ -295,7 +302,7 @@ nserror hlcache_handle_release(hlcache_handle *handle)
free((char *) ictx->child.charset);
free(ictx);
/* And stop */
- RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
+ RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
ictx);
}
} RING_ITERATE_END(hlcache->retrieval_ctx_ring, ictx);
@@ -325,18 +332,18 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
{
struct hlcache_entry *entry = handle->entry;
struct content *c;
-
+
if (entry == NULL) {
/* This handle is not yet associated with a cache entry.
* The implication is that the fetch for the handle has
* not progressed to the point where the entry can be
* created. */
-
+
RING_ITERATE_START(struct hlcache_retrieval_ctx,
hlcache->retrieval_ctx_ring,
ictx) {
if (ictx->handle == handle) {
- /* This is the nascent context for us,
+ /* This is the nascent context for us,
* so abort the fetch */
llcache_handle_abort(ictx->llcache);
llcache_handle_release(ictx->llcache);
@@ -346,39 +353,39 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
free((char *) ictx->child.charset);
free(ictx);
/* And stop */
- RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
+ RING_ITERATE_STOP(hlcache->retrieval_ctx_ring,
ictx);
}
} RING_ITERATE_END(hlcache->retrieval_ctx_ring, ictx);
-
+
return NSERROR_OK;
}
c = entry->content;
-
+
if (content_count_users(c) > 1) {
/* We are not the only user of 'c' so clone it. */
struct content *clone = content_clone(c);
-
+
if (clone == NULL)
return NSERROR_NOMEM;
-
+
entry = calloc(sizeof(struct hlcache_entry), 1);
-
+
if (entry == NULL) {
content_destroy(clone);
return NSERROR_NOMEM;
}
-
- if (content_add_user(clone,
+
+ if (content_add_user(clone,
hlcache_content_callback, handle) == false) {
content_destroy(clone);
free(entry);
return NSERROR_NOMEM;
}
-
+
content_remove_user(c, hlcache_content_callback, handle);
-
+
entry->content = clone;
handle->entry = entry;
entry->prev = NULL;
@@ -386,10 +393,10 @@ nserror hlcache_handle_abort(hlcache_handle *handle)
if (hlcache->content_list != NULL)
hlcache->content_list->prev = entry;
hlcache->content_list = entry;
-
+
c = clone;
}
-
+
return content_abort(c);
}
@@ -426,17 +433,17 @@ void hlcache_clean(void *ignored)
if (entry->content == NULL)
continue;
- if (content__get_status(entry->content) ==
+ if (content__get_status(entry->content) ==
CONTENT_STATUS_LOADING)
continue;
if (content_count_users(entry->content) != 0)
continue;
- /** \todo This is over-zealous: all unused contents
- * will be immediately destroyed. Ideally, we want to
- * purge all unused contents that are using stale
- * source data, and enough fresh contents such that
+ /** \todo This is over-zealous: all unused contents
+ * will be immediately destroyed. Ideally, we want to
+ * purge all unused contents that are using stale
+ * source data, and enough fresh contents such that
* the cache fits in the configured cache size limit.
*/
@@ -455,10 +462,10 @@ void hlcache_clean(void *ignored)
/* Destroy entry */
free(entry);
}
-
+
/* Attempt to clean the llcache */
llcache_clean();
-
+
/* Re-schedule ourselves */
schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL);
}
@@ -483,11 +490,11 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
switch (event->type) {
case LLCACHE_EVENT_HAD_HEADERS:
error = mimesniff_compute_effective_type(handle, NULL, 0,
- ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
+ ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
&effective_type);
if (error == NSERROR_OK || error == NSERROR_NOT_FOUND) {
- /* If the sniffer was successful or failed to find
- * a Content-Type header when sniffing was
+ /* If the sniffer was successful or failed to find
+ * a Content-Type header when sniffing was
* prohibited, we must migrate the retrieval context. */
error = hlcache_migrate_ctx(ctx, effective_type);
@@ -495,7 +502,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
lwc_string_unref(effective_type);
}
- /* No need to report that we need data:
+ /* No need to report that we need data:
* we'll get some anyway if there is any */
if (error == NSERROR_NEED_DATA)
error = NSERROR_OK;
@@ -504,7 +511,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
break;
case LLCACHE_EVENT_HAD_DATA:
- error = mimesniff_compute_effective_type(handle,
+ error = mimesniff_compute_effective_type(handle,
event->data.data.buf, event->data.data.len,
ctx->flags & HLCACHE_RETRIEVE_SNIFF_TYPE,
&effective_type);
@@ -549,7 +556,7 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
hlevent.data.error = event->data.msg;
ctx->handle->cb(ctx->handle, &hlevent, ctx->handle->pw);
- }
+ }
break;
case LLCACHE_EVENT_PROGRESS:
break;
@@ -563,11 +570,11 @@ nserror hlcache_llcache_callback(llcache_handle *handle,
*
* \param ctx Context to migrate
* \param effective_type The effective MIME type of the content, or NULL
- * \return NSERROR_OK on success,
+ * \return NSERROR_OK on success,
* NSERROR_NEED_DATA on success where data is needed,
* appropriate error otherwise
*/
-nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
+nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
lwc_string *effective_type)
{
content_type type = CONTENT_NONE;
@@ -575,8 +582,8 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
/* Unlink the context to prevent recursion */
RING_REMOVE(hlcache->retrieval_ctx_ring, ctx);
-
- if (effective_type != NULL &&
+
+ if (effective_type != NULL &&
hlcache_type_is_acceptable(effective_type,
ctx->accepted_types, &type)) {
error = hlcache_find_content(ctx, effective_type);
@@ -586,13 +593,13 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
hlevent.type = CONTENT_MSG_ERROR;
hlevent.data.error = messages_get("MiscError");
- ctx->handle->cb(ctx->handle, &hlevent,
+ ctx->handle->cb(ctx->handle, &hlevent,
ctx->handle->pw);
-
+
llcache_handle_abort(ctx->llcache);
llcache_handle_release(ctx->llcache);
}
- } else if (type == CONTENT_NONE &&
+ } else if (type == CONTENT_NONE &&
(ctx->flags & HLCACHE_RETRIEVE_MAY_DOWNLOAD)) {
/* Unknown type, and we can download, so convert */
llcache_handle_force_stream(ctx->llcache);
@@ -620,7 +627,7 @@ nserror hlcache_migrate_ctx(hlcache_retrieval_ctx *ctx,
hlevent.type = CONTENT_MSG_ERROR;
hlevent.data.error = messages_get("BadType");
- ctx->handle->cb(ctx->handle, &hlevent,
+ ctx->handle->cb(ctx->handle, &hlevent,
ctx->handle->pw);
}
}
@@ -657,7 +664,7 @@ bool hlcache_type_is_acceptable(lwc_string *mime_type,
*
* \param ctx High-level cache retrieval context
* \param effective_type Effective MIME type of content
- * \return NSERROR_OK on success,
+ * \return NSERROR_OK on success,
* NSERROR_NEED_DATA on success where data is needed,
* appropriate error otherwise
*
@@ -694,11 +701,11 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
ctx->child.quirks) == false)
continue;
- /* Ensure that content uses same low-level object as
+ /* Ensure that content uses same low-level object as
* low-level handle */
entry_llcache = content_get_llcache_handle(entry->content);
- if (llcache_handle_references_same_object(entry_llcache,
+ if (llcache_handle_references_same_object(entry_llcache,
ctx->llcache))
break;
}
@@ -710,7 +717,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
return NSERROR_NOMEM;
/* Create content using llhandle */
- entry->content = content_factory_create_content(ctx->llcache,
+ entry->content = content_factory_create_content(ctx->llcache,
ctx->child.charset, ctx->child.quirks,
effective_type);
if (entry->content == NULL) {
@@ -727,13 +734,16 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
/* Signal to caller that we created a content */
error = NSERROR_NEED_DATA;
+
+ hlcache->miss_count++;
} else {
/* Found a suitable content: no longer need low-level handle */
- llcache_handle_release(ctx->llcache);
+ llcache_handle_release(ctx->llcache);
+ hlcache->hit_count++;
}
/* Associate handle with content */
- if (content_add_user(entry->content,
+ if (content_add_user(entry->content,
hlcache_content_callback, ctx->handle) == false)
return NSERROR_NOMEM;
@@ -753,7 +763,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
if (ctx->handle->cb != NULL) {
event.type = CONTENT_MSG_READY;
- ctx->handle->cb(ctx->handle, &event,
+ ctx->handle->cb(ctx->handle, &event,
ctx->handle->pw);
}
} else if (status == CONTENT_STATUS_DONE) {
@@ -762,13 +772,13 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
if (ctx->handle->cb != NULL) {
event.type = CONTENT_MSG_READY;
- ctx->handle->cb(ctx->handle, &event,
+ ctx->handle->cb(ctx->handle, &event,
ctx->handle->pw);
}
if (ctx->handle->cb != NULL) {
event.type = CONTENT_MSG_DONE;
- ctx->handle->cb(ctx->handle, &event,
+ ctx->handle->cb(ctx->handle, &event,
ctx->handle->pw);
}
}
@@ -785,7 +795,7 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx,
* \param data Data for message
* \param pw Pointer to private data (hlcache_handle)
*/
-void hlcache_content_callback(struct content *c, content_msg msg,
+void hlcache_content_callback(struct content *c, content_msg msg,
union content_msg_data data, void *pw)
{
hlcache_handle *handle = pw;
@@ -801,4 +811,3 @@ void hlcache_content_callback(struct content *c, content_msg msg,
if (error != NSERROR_OK)
LOG(("Error in callback: %d", error));
}
-
diff --git a/content/llcache.c b/content/llcache.c
index 3862cb467..d4a6c9168 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -29,7 +29,6 @@
#include "content/fetch.h"
#include "content/llcache.h"
#include "content/urldb.h"
-#include "desktop/options.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/url.h"
@@ -142,15 +141,23 @@ struct llcache_object {
size_t num_headers; /**< Number of fetch headers */
};
-/** Handler for fetch-related queries */
-static llcache_query_callback query_cb;
-/** Data for fetch-related query handler */
-static void *query_cb_pw;
+struct llcache_s {
+ /** Handler for fetch-related queries */
+ llcache_query_callback query_cb;
+ /** Data for fetch-related query handler */
+ void *query_cb_pw;
-/** Head of the low-level cached object list */
-static llcache_object *llcache_cached_objects;
-/** Head of the low-level uncached object list */
-static llcache_object *llcache_uncached_objects;
+ /** Head of the low-level cached object list */
+ llcache_object *cached_objects;
+
+ /** Head of the low-level uncached object list */
+ llcache_object *uncached_objects;
+
+ uint32_t limit;
+};
+
+/** low level cache state */
+static struct llcache_s *llcache = NULL;
static nserror llcache_object_user_new(llcache_handle_callback cb, void *pw,
llcache_object_user **user);
@@ -246,10 +253,19 @@ static inline void llcache_invalidate_cache_control_data(llcache_object *object)
******************************************************************************/
/* See llcache.h for documentation */
-nserror llcache_initialise(llcache_query_callback cb, void *pw)
+nserror
+llcache_initialise(llcache_query_callback cb, void *pw, uint32_t llcache_limit)
{
- query_cb = cb;
- query_cb_pw = pw;
+ llcache = calloc(1, sizeof(struct llcache_s));
+ if (llcache == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ llcache->query_cb = cb;
+ llcache->query_cb_pw = pw;
+ llcache->limit = llcache_limit;
+
+ LOG(("llcache initialised with a limit of %d bytes", llcache_limit));
return NSERROR_OK;
}
@@ -260,7 +276,7 @@ void llcache_finalise(void)
llcache_object *object, *next;
/* Clean uncached objects */
- for (object = llcache_uncached_objects; object != NULL; object = next) {
+ for (object = llcache->uncached_objects; object != NULL; object = next) {
llcache_object_user *user, *next_user;
next = object->next;
@@ -281,7 +297,7 @@ void llcache_finalise(void)
}
/* Clean cached objects */
- for (object = llcache_cached_objects; object != NULL; object = next) {
+ for (object = llcache->cached_objects; object != NULL; object = next) {
llcache_object_user *user, *next_user;
next = object->next;
@@ -300,6 +316,9 @@ void llcache_finalise(void)
llcache_object_destroy(object);
}
+
+ free(llcache);
+ llcache = NULL;
}
/* See llcache.h for documentation */
@@ -310,12 +329,12 @@ nserror llcache_poll(void)
fetch_poll();
/* Catch new users up with state of objects */
- for (object = llcache_cached_objects; object != NULL;
+ for (object = llcache->cached_objects; object != NULL;
object = object->next) {
llcache_object_notify_users(object);
}
- for (object = llcache_uncached_objects; object != NULL;
+ for (object = llcache->uncached_objects; object != NULL;
object = object->next) {
llcache_object_notify_users(object);
}
@@ -453,7 +472,7 @@ nserror llcache_handle_abort(llcache_handle *handle)
/* Add new object to uncached list */
llcache_object_add_to_list(newobject,
- &llcache_uncached_objects);
+ &llcache->uncached_objects);
} else {
/* We're the only user, so abort any fetch in progress */
if (object->fetch.fetch != NULL) {
@@ -481,10 +500,10 @@ nserror llcache_handle_force_stream(llcache_handle *handle)
return NSERROR_OK;
/* Forcibly uncache this object */
- if (llcache_object_in_list(object, llcache_cached_objects)) {
+ if (llcache_object_in_list(object, llcache->cached_objects)) {
llcache_object_remove_from_list(object,
- &llcache_cached_objects);
- llcache_object_add_to_list(object, &llcache_uncached_objects);
+ &llcache->cached_objects);
+ llcache_object_add_to_list(object, &llcache->uncached_objects);
}
object->fetch.flags |= LLCACHE_RETRIEVE_STREAM_DATA;
@@ -717,7 +736,7 @@ nserror llcache_object_retrieve(const char *url, uint32_t flags,
}
/* Add new object to uncached list */
- llcache_object_add_to_list(obj, &llcache_uncached_objects);
+ llcache_object_add_to_list(obj, &llcache->uncached_objects);
} else {
error = llcache_object_retrieve_from_cache(defragmented_url, flags, referer,
post, redirect_count, &obj);
@@ -765,7 +784,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
#endif
/* Search for the most recently fetched matching object */
- for (obj = llcache_cached_objects; obj != NULL; obj = obj->next) {
+ for (obj = llcache->cached_objects; obj != NULL; obj = obj->next) {
bool match;
if ((newest == NULL ||
@@ -821,7 +840,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
}
/* Add new object to cache */
- llcache_object_add_to_list(obj, &llcache_cached_objects);
+ llcache_object_add_to_list(obj, &llcache->cached_objects);
} else {
/* No object found; create a new one */
/* Create new object */
@@ -842,7 +861,7 @@ nserror llcache_object_retrieve_from_cache(const char *url, uint32_t flags,
}
/* Add new object to cache */
- llcache_object_add_to_list(obj, &llcache_cached_objects);
+ llcache_object_add_to_list(obj, &llcache->cached_objects);
}
*result = obj;
@@ -1643,7 +1662,7 @@ void llcache_clean(void)
*/
/* 1) Uncacheable objects with no users or fetches */
- for (object = llcache_uncached_objects; object != NULL; object = next) {
+ for (object = llcache->uncached_objects; object != NULL; object = next) {
next = object->next;
/* The candidate count of uncacheable objects is always 0 */
@@ -1654,7 +1673,7 @@ void llcache_clean(void)
LOG(("Found victim %p", object));
#endif
llcache_object_remove_from_list(object,
- &llcache_uncached_objects);
+ &llcache->uncached_objects);
llcache_object_destroy(object);
} else {
llcache_size += object->source_len + sizeof(*object);
@@ -1662,7 +1681,7 @@ void llcache_clean(void)
}
/* 2) Stale cacheable objects with no users or pending fetches */
- for (object = llcache_cached_objects; object != NULL; object = next) {
+ for (object = llcache->cached_objects; object != NULL; object = next) {
next = object->next;
if (object->users == NULL && object->candidate_count == 0 &&
@@ -1673,17 +1692,17 @@ void llcache_clean(void)
LOG(("Found victim %p", object));
#endif
llcache_object_remove_from_list(object,
- &llcache_cached_objects);
+ &llcache->cached_objects);
llcache_object_destroy(object);
} else {
llcache_size += object->source_len + sizeof(*object);
}
}
- if ((uint32_t) option_memory_cache_size < llcache_size) {
+ if (llcache->limit < llcache_size) {
/* 3) Fresh cacheable objects with
* no users or pending fetches */
- for (object = llcache_cached_objects; object != NULL;
+ for (object = llcache->cached_objects; object != NULL;
object = next) {
next = object->next;
@@ -1699,7 +1718,7 @@ void llcache_clean(void)
object->source_len + sizeof(*object);
llcache_object_remove_from_list(object,
- &llcache_cached_objects);
+ &llcache->cached_objects);
llcache_object_destroy(object);
}
}
@@ -2459,7 +2478,7 @@ nserror llcache_fetch_auth(llcache_object *object, const char *realm)
/* No authentication details, or tried what we had, so ask */
object->fetch.tried_with_auth = false;
- if (query_cb != NULL) {
+ if (llcache->query_cb != NULL) {
llcache_query query;
/* Emit query for authentication details */
@@ -2469,7 +2488,7 @@ nserror llcache_fetch_auth(llcache_object *object, const char *realm)
object->fetch.outstanding_query = true;
- error = query_cb(&query, query_cb_pw,
+ error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
} else {
llcache_event event;
@@ -2513,7 +2532,7 @@ nserror llcache_fetch_cert_error(llcache_object *object,
/* Invalidate cache-control data */
llcache_invalidate_cache_control_data(object);
- if (query_cb != NULL) {
+ if (llcache->query_cb != NULL) {
llcache_query query;
/* Emit query for TLS */
@@ -2524,7 +2543,7 @@ nserror llcache_fetch_cert_error(llcache_object *object,
object->fetch.outstanding_query = true;
- error = query_cb(&query, query_cb_pw,
+ error = llcache->query_cb(&query, llcache->query_cb_pw,
llcache_query_handle_response, object);
} else {
llcache_event event;
diff --git a/content/llcache.h b/content/llcache.h
index e6584e165..8070db90d 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -156,7 +156,7 @@ typedef nserror (*llcache_query_callback)(const llcache_query *query, void *pw,
* \param pw Pointer to query handler data
* \return NSERROR_OK on success, appropriate error otherwise.
*/
-nserror llcache_initialise(llcache_query_callback cb, void *pw);
+nserror llcache_initialise(llcache_query_callback cb, void *pw, uint32_t llcache_limit);
/**
* Finalise the low-level cache
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 37e06a330..cb63e7d6b 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -70,7 +70,7 @@
/* the time between cache clean runs in ms */
#define IMAGE_CACHE_CLEAN_TIME (10 * 1000)
-#define HL_CACHE_CLEAN_TIME (5 * 1000)
+#define HL_CACHE_CLEAN_TIME (2 * IMAGE_CACHE_CLEAN_TIME)
bool netsurf_quit = false;
bool verbose_log = false;
@@ -109,6 +109,8 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query,
return NSERROR_OK;
}
+#define MINIMUM_MEMORY_CACHE_SIZE (2 * 1024 * 1024)
+
/**
* Initialise components used by gui NetSurf.
*/
@@ -127,11 +129,9 @@ nserror netsurf_init(int *pargc,
};
struct image_cache_parameters image_cache_parameters = {
.bg_clean_time = IMAGE_CACHE_CLEAN_TIME,
- .limit = (8 * 1024 * 1024),
- .hysteresis = (2 * 1024 * 1024),
.speculative_small = SPECULATE_SMALL
};
-
+
#ifdef HAVE_SIGPIPE
/* Ignore SIGPIPE - this is necessary as OpenSSL can generate these
* and the default action is to terminate the app. There's no easy
@@ -169,6 +169,24 @@ nserror netsurf_init(int *pargc,
messages_load(messages);
+ /* set up cache limits based on the memory cache size option */
+ hlcache_parameters.limit = option_memory_cache_size;
+
+ if (hlcache_parameters.limit < MINIMUM_MEMORY_CACHE_SIZE) {
+ hlcache_parameters.limit = MINIMUM_MEMORY_CACHE_SIZE;
+ LOG(("Setting minimum memory cache size to %d",
+ hlcache_parameters.limit));
+ }
+
+ /* image cache is 25% of total memory cache size */
+ image_cache_parameters.limit = (hlcache_parameters.limit * 25) / 100;
+
+ /* image cache hysteresis is 20% of teh image cache size */
+ image_cache_parameters.hysteresis = (image_cache_parameters.limit * 20) / 100;
+
+ /* account for image cache use from total */
+ hlcache_parameters.limit -= image_cache_parameters.limit;
+
/* image handler bitmap cache */
error = image_cache_init(&image_cache_parameters);
if (error != NSERROR_OK)
@@ -244,9 +262,6 @@ void netsurf_exit(void)
LOG(("Finalising high-level cache"));
hlcache_finalise();
- LOG(("Finalising low-level cache"));
- llcache_finalise();
-
LOG(("Closing fetches"));
fetch_quit();
diff --git a/image/image_cache.c b/image/image_cache.c
index a9f810426..f09db2d66 100644
--- a/image/image_cache.c
+++ b/image/image_cache.c
@@ -89,20 +89,20 @@ struct image_cache_s {
/** Maximum count of bitmaps allocated at any one time */
int max_bitmap_count;
- /** The size of the bitmaps when teh max count occoured */
+ /** The size of the bitmaps when the max count occoured */
size_t max_bitmap_count_size;
/** Bitmap was not available at plot time required conversion */
int miss_count;
- size_t miss_size;
+ uint64_t miss_size;
/** Bitmap was available at plot time required no conversion */
int hit_count;
- size_t hit_size;
+ uint64_t hit_size;
/** Bitmap was not available at plot time and required
* conversion which failed.
*/
int fail_count;
- size_t fail_size;
+ uint64_t fail_size;
/* Cache entry freed without ever being redrawn */
int total_unrendered;
@@ -120,6 +120,7 @@ struct image_cache_s {
unsigned int peak_conversions_size;
};
+/** image cache state */
static struct image_cache_s *image_cache = NULL;
@@ -357,6 +358,9 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters)
image_cache__background_update,
image_cache);
+ LOG(("Image cache initilised with a limit of %d hysteresis of %d",
+ image_cache->params.limit, image_cache->params.hysteresis));
+
return NSERROR_OK;
}