1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-21 02:50:18 +03:00

mmap-cache: embed MMapCache.contexts[]

Code simplification; no idea why the Context structs were being
heap-allocated piecemeal.  There aren't many and they're small,
and made even smaller with this commit.

This also gets rid of the Context.cache backreference by just
accompanying the Context* with MMapCache* to the few private
Context* operations, resolving the context ID to a Context* at
the single public entrypoint: mmap_cache_fd_get(), which asserts
on the value being within bounds.  The Context.id member and
checks are also removed, as there's far less opportunity for
these things to become inconsistent now.

Of course this drops all context_{add,free}() related code,
making for a tasty diffstat.
This commit is contained in:
Vito Caputo 2021-11-25 10:39:34 -08:00 committed by Yu Watanabe
parent 5ec9fbae64
commit 7580b0d869

View File

@ -38,8 +38,6 @@ struct Window {
};
struct Context {
MMapCache *cache;
unsigned id;
Window *window;
LIST_FIELDS(Context, by_window);
@ -60,10 +58,11 @@ struct MMapCache {
unsigned n_context_cache_hit, n_window_list_hit, n_missed;
Hashmap *fds;
Context *contexts[MMAP_CACHE_MAX_CONTEXTS];
LIST_HEAD(Window, unused);
Window *last_unused;
Context contexts[MMAP_CACHE_MAX_CONTEXTS];
};
#define WINDOWS_MIN 64
@ -186,9 +185,10 @@ static Window *window_add(MMapCache *m, MMapFileDescriptor *f, bool keep_always,
return w;
}
static void context_detach_window(Context *c) {
static void context_detach_window(MMapCache *m, Context *c) {
Window *w;
assert(m);
assert(c);
if (!c->window)
@ -204,29 +204,30 @@ static void context_detach_window(Context *c) {
* by SIGSEGV. */
window_free(w);
#else
LIST_PREPEND(unused, c->cache->unused, w);
if (!c->cache->last_unused)
c->cache->last_unused = w;
LIST_PREPEND(unused, m->unused, w);
if (!m->last_unused)
m->last_unused = w;
w->in_unused = true;
#endif
}
}
static void context_attach_window(Context *c, Window *w) {
static void context_attach_window(MMapCache *m, Context *c, Window *w) {
assert(m);
assert(c);
assert(w);
if (c->window == w)
return;
context_detach_window(c);
context_detach_window(m, c);
if (w->in_unused) {
/* Used again? */
if (c->cache->last_unused == w)
c->cache->last_unused = w->unused_prev;
LIST_REMOVE(unused, c->cache->unused, w);
if (m->last_unused == w)
m->last_unused = w->unused_prev;
LIST_REMOVE(unused, m->unused, w);
w->in_unused = false;
}
@ -235,49 +236,11 @@ static void context_attach_window(Context *c, Window *w) {
LIST_PREPEND(by_window, w->contexts, c);
}
static Context *context_add(MMapCache *m, unsigned id) {
Context *c;
assert(m);
c = m->contexts[id];
if (c)
return c;
c = new0(Context, 1);
if (!c)
return NULL;
c->cache = m;
c->id = id;
assert(!m->contexts[id]);
m->contexts[id] = c;
return c;
}
static void context_free(Context *c) {
assert(c);
context_detach_window(c);
if (c->cache) {
assert(c->cache->contexts[c->id] == c);
c->cache->contexts[c->id] = NULL;
}
free(c);
}
static MMapCache *mmap_cache_free(MMapCache *m) {
int i;
assert(m);
for (i = 0; i < MMAP_CACHE_MAX_CONTEXTS; i++)
if (m->contexts[i])
context_free(m->contexts[i]);
for (int i = 0; i < MMAP_CACHE_MAX_CONTEXTS; i++)
context_detach_window(m, &m->contexts[i]);
hashmap_free(m->fds);
@ -301,33 +264,26 @@ static int make_room(MMapCache *m) {
static int try_context(
MMapFileDescriptor *f,
unsigned context,
Context *c,
bool keep_always,
uint64_t offset,
size_t size,
void **ret) {
Context *c;
assert(f);
assert(f->cache);
assert(f->cache->n_ref > 0);
assert(c);
assert(size > 0);
assert(ret);
c = f->cache->contexts[context];
if (!c)
return 0;
assert(c->id == context);
if (!c->window)
return 0;
if (!window_matches_fd(c->window, f, offset, size)) {
/* Drop the reference to the window, since it's unnecessary now */
context_detach_window(c);
context_detach_window(f->cache, c);
return 0;
}
@ -344,18 +300,18 @@ static int try_context(
static int find_mmap(
MMapFileDescriptor *f,
unsigned context,
Context *c,
bool keep_always,
uint64_t offset,
size_t size,
void **ret) {
Window *w;
Context *c;
assert(f);
assert(f->cache);
assert(f->cache->n_ref > 0);
assert(c);
assert(size > 0);
if (f->sigbus)
@ -368,11 +324,7 @@ static int find_mmap(
if (!w)
return 0;
c = context_add(f->cache, context);
if (!c)
return -ENOMEM;
context_attach_window(c, w);
context_attach_window(f->cache, c, w);
w->keep_always = w->keep_always || keep_always;
*ret = (uint8_t*) w->ptr + (offset - w->offset);
@ -409,7 +361,7 @@ static int mmap_try_harder(MMapFileDescriptor *f, void *addr, int flags, uint64_
static int add_mmap(
MMapFileDescriptor *f,
unsigned context,
Context *c,
bool keep_always,
uint64_t offset,
size_t size,
@ -417,7 +369,6 @@ static int add_mmap(
void **ret) {
uint64_t woffset, wsize;
Context *c;
Window *w;
void *d;
int r;
@ -425,6 +376,7 @@ static int add_mmap(
assert(f);
assert(f->cache);
assert(f->cache->n_ref > 0);
assert(c);
assert(size > 0);
assert(ret);
@ -461,15 +413,11 @@ static int add_mmap(
if (r < 0)
return r;
c = context_add(f->cache, context);
if (!c)
goto outofmem;
w = window_add(f->cache, f, keep_always, woffset, wsize, d);
if (!w)
goto outofmem;
context_attach_window(c, w);
context_attach_window(f->cache, c, w);
*ret = (uint8_t*) w->ptr + (offset - w->offset);
@ -489,6 +437,7 @@ int mmap_cache_fd_get(
struct stat *st,
void **ret) {
Context *c;
int r;
assert(f);
@ -498,20 +447,22 @@ int mmap_cache_fd_get(
assert(ret);
assert(context < MMAP_CACHE_MAX_CONTEXTS);
c = &f->cache->contexts[context];
/* Check whether the current context is the right one already */
r = try_context(f, context, keep_always, offset, size, ret);
r = try_context(f, c, keep_always, offset, size, ret);
if (r != 0)
return r;
/* Search for a matching mmap */
r = find_mmap(f, context, keep_always, offset, size, ret);
r = find_mmap(f, c, keep_always, offset, size, ret);
if (r != 0)
return r;
f->cache->n_missed++;
/* Create a new mmap */
return add_mmap(f, context, keep_always, offset, size, st, ret);
return add_mmap(f, c, keep_always, offset, size, st, ret);
}
void mmap_cache_stats_log_debug(MMapCache *m) {