Skip to content

Commit

Permalink
Concurrency control on multi-cache additions.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed May 4, 2015
1 parent 052aca0 commit 6c9ee55
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
24 changes: 19 additions & 5 deletions src/6model/reprs/MVMMultiCache.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,32 @@ MVMObject * MVM_multi_cache_add(MVMThreadContext *tc, MVMObject *cache_obj, MVMO
MVM_exception_throw_adhoc(tc, "Multi cache addition requires an MVMCallCapture");
}

/* If we're in a multi-threaded context, obtain the cache additions
* lock, and then do another lookup to ensure nobody beat us to
* making this entry. */
if (MVM_instance_have_user_threads(tc)) {
uv_mutex_lock(&(tc->instance->mutex_multi_cache_add));
if (MVM_multi_cache_find(tc, cache_obj, capture))
goto DONE;
}

/* If it's zero arity, just stick it in that slot. */
if (num_args == 0) {
/* Can only be added if there are no named args */
if (!has_nameds)
MVM_ASSIGN_REF(tc, &(cache_obj->header), cache->zero_arity, result);
return cache_obj;
goto DONE;
}

/* If there's more args than the maximum, we can't cache it. */
if (num_args > MVM_MULTICACHE_MAX_ARITY)
return cache_obj;
goto DONE;

/* If the cache is saturated, don't do anything (we could instead do a random
* replacement). */
entries = cache->arity_caches[num_args - 1].num_entries;
if (entries == MVM_MULTICACHE_MAX_ENTRIES)
return cache_obj;
goto DONE;

/* Create arg tuple. */
for (i = 0; i < num_args; i++) {
Expand All @@ -164,13 +173,13 @@ MVMObject * MVM_multi_cache_add(MVMThreadContext *tc, MVMObject *cache_obj, MVMO
}
}
else {
return cache_obj;
goto DONE;
}
}
arg_tup[i] = STABLE(arg)->type_cache_id | (IS_CONCRETE(arg) ? 1 : 0);
}
else {
return cache_obj;
goto DONE;
}
}
else {
Expand All @@ -193,6 +202,11 @@ MVMObject * MVM_multi_cache_add(MVMThreadContext *tc, MVMObject *cache_obj, MVMO
cache->arity_caches[num_args - 1].named_ok[entries] = has_nameds;
cache->arity_caches[num_args - 1].num_entries = entries + 1;

/* Release lock if needed. */
DONE:
if (MVM_instance_have_user_threads(tc))
uv_mutex_unlock(&(tc->instance->mutex_multi_cache_add));

/* Hand back the created/updated cache. */
return cache_obj;
}
Expand Down
6 changes: 4 additions & 2 deletions src/core/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ struct MVMInstance {
/* int -> str cache */
MVMString **int_to_str_cache;

/* Specialization installation mutex (global, as it's low contention, so
* no real motivation to have it more fine-grained at present). */
/* Multi-dispatch cache and specialization installation mutexes
* (global, as the additions are quite low contention, so no
* real motivation to have it more fine-grained at present). */
uv_mutex_t mutex_multi_cache_add;
uv_mutex_t mutex_spesh_install;

/* Log file for specializations, if we're to log them. */
Expand Down
7 changes: 7 additions & 0 deletions src/moar.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ MVMInstance * MVM_vm_create_instance(void) {
* them, so that spesh may end up optimizing more "internal" stuff. */
MVM_callsite_initialize_common(instance->main_thread);

/* Multi-cache additions mutex. */
init_mutex(instance->mutex_multi_cache_add, "multi-cache addition");

/* Mutex for spesh installations, and check if we've a file we
* should log specializations to. */
init_mutex(instance->mutex_spesh_install, "spesh installations");
Expand All @@ -136,6 +139,7 @@ MVMInstance * MVM_vm_create_instance(void) {
instance->spesh_osr_enabled = 1;
}

/* JIT environment/logging setup. */
jit_disable = getenv("MVM_JIT_DISABLE");
if (!jit_disable || strlen(jit_disable) == 0)
instance->jit_enabled = 1;
Expand Down Expand Up @@ -298,6 +302,9 @@ void MVM_vm_destroy_instance(MVMInstance *instance) {
/* Clean up Hash of hashes of symbol tables per hll. */
uv_mutex_destroy(&instance->mutex_hll_syms);

/* Clean up multi cache addition mutex. */
uv_mutex_destroy(&instance->mutex_multi_cache_add);

/* Clean up spesh install mutex and close any log. */
uv_mutex_destroy(&instance->mutex_spesh_install);
if (instance->spesh_log_fh)
Expand Down

0 comments on commit 6c9ee55

Please sign in to comment.