offset + size <= w->offset + w->size;
}
-static Window *window_add(MMapCache *m, MMapFileDescriptor *f, bool keep_always, uint64_t offset, size_t size, void *ptr) {
+static Window* window_add(MMapFileDescriptor *f, uint64_t offset, size_t size, void *ptr) {
+ MMapCache *m = mmap_cache_fd_cache(f);
Window *w;
- assert(m);
- assert(f);
-
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
-
/* Allocate a new window */
w = new(Window, 1);
if (!w)
*w = (Window) {
.cache = m,
.fd = f,
- .keep_always = keep_always,
.offset = offset,
.size = size,
.ptr = ptr,
};
- LIST_PREPEND(by_fd, f->windows, w);
-
- return w;
+ return LIST_PREPEND(by_fd, f->windows, w);
}
static void context_detach_window(MMapCache *m, Context *c) {
DEFINE_TRIVIAL_REF_UNREF_FUNC(MMapCache, mmap_cache, mmap_cache_free);
-static int try_context(
- MMapFileDescriptor *f,
- Context *c,
- bool keep_always,
- uint64_t offset,
- size_t size,
- void **ret) {
-
- assert(f);
- assert(f->cache);
- assert(f->cache->n_ref > 0);
- assert(c);
- assert(size > 0);
- assert(ret);
-
- if (!c->window)
- return 0;
-
- if (!window_matches(c->window, f, offset, size)) {
-
- /* Drop the reference to the window, since it's unnecessary now */
- context_detach_window(f->cache, c);
- return 0;
- }
-
- if (c->window->fd->sigbus)
- return -EIO;
-
- c->window->keep_always = c->window->keep_always || keep_always;
-
- *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
- f->cache->n_context_cache_hit++;
-
- return 1;
-}
-
-static int find_mmap(
- MMapFileDescriptor *f,
- Context *c,
- bool keep_always,
- uint64_t offset,
- size_t size,
- void **ret) {
-
- Window *found = NULL;
-
- assert(f);
- assert(f->cache);
- assert(f->cache->n_ref > 0);
- assert(c);
- assert(size > 0);
-
- if (f->sigbus)
- return -EIO;
-
- LIST_FOREACH(by_fd, w, f->windows)
- if (window_matches(w, f, offset, size)) {
- found = w;
- break;
- }
-
- if (!found)
- return 0;
-
- context_attach_window(f->cache, c, found);
- found->keep_always = found->keep_always || keep_always;
-
- *ret = (uint8_t*) found->ptr + (offset - found->offset);
- f->cache->n_window_list_hit++;
-
- return 1;
-}
-
static int mmap_try_harder(MMapFileDescriptor *f, void *addr, int flags, uint64_t offset, size_t size, void **ret) {
MMapCache *m = mmap_cache_fd_cache(f);
static int add_mmap(
MMapFileDescriptor *f,
- Context *c,
- bool keep_always,
uint64_t offset,
size_t size,
struct stat *st,
- void **ret) {
+ Window **ret) {
uint64_t woffset, wsize;
Window *w;
int r;
assert(f);
- assert(f->cache);
- assert(f->cache->n_ref > 0);
- assert(c);
assert(size > 0);
assert(ret);
if (r < 0)
return r;
- w = window_add(f->cache, f, keep_always, woffset, wsize, d);
- if (!w)
- goto outofmem;
-
- context_attach_window(f->cache, c, w);
-
- *ret = (uint8_t*) w->ptr + (offset - w->offset);
-
- return 1;
+ w = window_add(f, woffset, wsize, d);
+ if (!w) {
+ (void) munmap(d, wsize);
+ return -ENOMEM;
+ }
-outofmem:
- (void) munmap(d, wsize);
- return -ENOMEM;
+ *ret = w;
+ return 0;
}
int mmap_cache_fd_get(
struct stat *st,
void **ret) {
+ MMapCache *m = mmap_cache_fd_cache(f);
Context *c;
+ Window *w;
int r;
- assert(f);
- assert(f->cache);
- assert(f->cache->n_ref > 0);
+ assert(context < MMAP_CACHE_MAX_CONTEXTS);
assert(size > 0);
assert(ret);
- assert(context < MMAP_CACHE_MAX_CONTEXTS);
+
+ if (f->sigbus)
+ return -EIO;
c = &f->cache->contexts[context];
/* Check whether the current context is the right one already */
- r = try_context(f, c, keep_always, offset, size, ret);
- if (r != 0)
- return r;
+ if (window_matches(c->window, f, offset, size)) {
+ m->n_context_cache_hit++;
+ w = c->window;
+ goto found;
+ }
+
+ /* Drop the reference to the window, since it's unnecessary now */
+ context_detach_window(m, c);
/* Search for a matching mmap */
- r = find_mmap(f, c, keep_always, offset, size, ret);
- if (r != 0)
- return r;
+ LIST_FOREACH(by_fd, i, f->windows)
+ if (window_matches(i, f, offset, size)) {
+ m->n_window_list_hit++;
+ w = i;
+ goto found;
+ }
- f->cache->n_missed++;
+ m->n_missed++;
/* Create a new mmap */
- return add_mmap(f, c, keep_always, offset, size, st, ret);
+ r = add_mmap(f, offset, size, st, &w);
+ if (r < 0)
+ return r;
+
+found:
+ w->keep_always = w->keep_always || keep_always;
+ context_attach_window(m, c, w);
+ *ret = (uint8_t*) w->ptr + (offset - w->offset);
+ return 0;
}
void mmap_cache_stats_log_debug(MMapCache *m) {