lock-free argument lookup

Since we know these ids are always early and up to a fixed index,
we can have a separate, fixed mapping for them, which is only
initialized once during state creation, and never changes.
This commit is contained in:
Daniel Kolesa 2022-04-20 05:00:05 +02:00
parent 4627321e23
commit 2406324a96
3 changed files with 13 additions and 6 deletions

View file

@ -45,11 +45,17 @@ static void *default_alloc(void *, void *p, size_t, size_t ns) {
}
ident *internal_state::lookup_ident(std::size_t idx) {
if (idx < MAX_ARGUMENTS) {
return argmap[idx];
}
std::lock_guard<std::mutex> l{ident_mtx};
return identmap[idx];
}
ident const *internal_state::lookup_ident(std::size_t idx) const {
if (idx < MAX_ARGUMENTS) {
return argmap[idx];
}
std::lock_guard<std::mutex> l{ident_mtx};
return identmap[idx];
}
@ -141,7 +147,7 @@ state::state(alloc_func func, void *data) {
for (std::size_t i = 0; i < MAX_ARGUMENTS; ++i) {
char buf[16];
snprintf(buf, sizeof(buf), "arg%zu", i + 1);
statep->new_ident(
statep->argmap[i] = &statep->new_ident(
*this, static_cast<char const *>(buf), IDENT_FLAG_ARG
);
}

View file

@ -50,6 +50,7 @@ struct internal_state {
allocator_type
> idents;
std::vector<ident *, std_allocator<ident *>> identmap;
std::array<ident *, MAX_ARGUMENTS> argmap;
mutable std::mutex ident_mtx;
string_pool *strman;

View file

@ -133,7 +133,7 @@ any_value exec_alias(
std::size_t noff = ts.idstack.size();
for(std::size_t i = 0; i < callargs; i++) {
auto &ast = ts.get_astack(
static_cast<alias *>(ts.istate->lookup_ident(i))
static_cast<alias *>(ts.istate->argmap[i])
);
auto &st = ts.idstack.emplace_back();
ast.push(st);
@ -167,14 +167,14 @@ any_value exec_alias(
tss.ident_flags = oflags;
for (std::size_t i = 0; i < cargs; i++) {
tss.get_astack(
static_cast<alias *>(tss.istate->lookup_ident(i))
static_cast<alias *>(tss.istate->argmap[i])
).pop();
amask[i] = false;
}
for (; amask.any(); ++cargs) {
if (amask[cargs]) {
tss.get_astack(
static_cast<alias *>(tss.istate->lookup_ident(cargs))
static_cast<alias *>(tss.istate->argmap[cargs])
).pop();
amask[cargs] = false;
}
@ -202,7 +202,7 @@ any_value exec_code_with_args(thread_state &ts, bcode_ref const &body) {
for (std::size_t i = 0; mask.any(); ++i) {
if (mask[0]) {
auto &ast = ts.get_astack(
static_cast<alias *>(ts.istate->lookup_ident(i))
static_cast<alias *>(ts.istate->argmap[i])
);
auto &st = ts.idstack.emplace_back();
st.next = ast.node;
@ -229,7 +229,7 @@ any_value exec_code_with_args(thread_state &ts, bcode_ref const &body) {
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
if (mask2[0]) {
tss.get_astack(
static_cast<alias *>(tss.istate->lookup_ident(i))
static_cast<alias *>(tss.istate->argmap[i])
).node = tss.idstack[offn + nredo++].next;
}
mask2 >>= 1;