diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 38fe33c24..746a29ce0 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -440,11 +440,11 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E auto *found = map_get(&info->gen_procs, base_entity->identifier.load()); if (found) { gen_procs = *found; - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex // @@GPM //////////////////////////// mutex_unlock(&info->gen_procs_mutex); ///////////////////////////////////// @@ -455,7 +455,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex } else { gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData); gen_procs->procs.allocator = heap_allocator(); @@ -481,11 +481,11 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return false; } - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex for (Entity *other : gen_procs->procs) { Type *pt = base_type(other->type); if (are_types_identical(pt, final_proc_type)) { - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex if (poly_proc_data) { poly_proc_data->gen_entity = other; @@ -509,7 +509,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E return true; } } - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex } @@ -569,9 +569,9 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } } - mutex_lock(&gen_procs->mutex); // @local-mutex + rw_mutex_lock(&gen_procs->mutex); // @local-mutex array_add(&gen_procs->procs, entity); - mutex_unlock(&gen_procs->mutex); // @local-mutex + rw_mutex_unlock(&gen_procs->mutex); // @local-mutex ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); proc_info->file = file; diff --git a/src/checker.cpp b/src/checker.cpp index fd80d07de..3f5c2892f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1356,9 +1356,9 @@ gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { } return nullptr; } else { - mutex_lock(&c->info->global_untyped_mutex); - defer (mutex_unlock(&c->info->global_untyped_mutex)); + rw_mutex_shared_lock(&c->info->global_untyped_mutex); ExprInfo **found = map_get(&c->info->global_untyped, expr); + rw_mutex_shared_unlock(&c->info->global_untyped_mutex); if (found) { return *found; } @@ -1370,9 +1370,9 @@ gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMod if (c->untyped != nullptr) { map_set(c->untyped, expr, make_expr_info(mode, type, value, false)); } else { - mutex_lock(&c->info->global_untyped_mutex); + rw_mutex_lock(&c->info->global_untyped_mutex); map_set(&c->info->global_untyped, expr, make_expr_info(mode, type, value, false)); - mutex_unlock(&c->info->global_untyped_mutex); + rw_mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1382,10 +1382,10 @@ gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) { GB_ASSERT(map_get(c->untyped, e) == nullptr); } else { auto *untyped = &c->info->global_untyped; - mutex_lock(&c->info->global_untyped_mutex); + rw_mutex_lock(&c->info->global_untyped_mutex); map_remove(untyped, e); GB_ASSERT(map_get(untyped, e) == nullptr); - mutex_unlock(&c->info->global_untyped_mutex); + rw_mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1454,6 +1454,7 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo BlockingMutex *mutex = &ctx->info->type_and_value_mutex; if (ctx->pkg) { + // TODO(bill): is a per package mutex is a good idea here? mutex = &ctx->pkg->type_and_value_mutex; } diff --git a/src/checker.hpp b/src/checker.hpp index 554c8ddf4..226f69c1c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -317,7 +317,7 @@ struct LoadFileCache { struct GenProcsData { Array procs; - BlockingMutex mutex; + RwMutex mutex; }; // CheckerInfo stores all the symbol information for a type-checked program @@ -347,14 +347,9 @@ struct CheckerInfo { // Below are accessed within procedures - // NOTE(bill): If the semantic checker (check_proc_body) is to ever to be multithreaded, - // these variables will be of contention - - Semaphore collect_semaphore; - + RwMutex global_untyped_mutex; UntypedExprInfoMap global_untyped; // NOTE(bill): This needs to be a map and not on the Ast // as it needs to be iterated across afterwards - BlockingMutex global_untyped_mutex; BlockingMutex builtin_mutex; BlockingMutex type_and_value_mutex; @@ -388,7 +383,7 @@ struct CheckerInfo { BlockingMutex load_file_mutex; StringMap load_file_cache; - BlockingMutex all_procedures_mutex;; + BlockingMutex all_procedures_mutex; Array all_procedures; }; diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index c48115079..1660d3487 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -57,7 +57,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) auto *found = map_get(&info->gen_procs, ident); if (found) { GenProcsData *gpd = *found; - MUTEX_GUARD(&gpd->mutex); + rw_mutex_shared_lock(&gpd->mutex); for (Entity *e : gpd->procs) { if (!ptr_set_exists(min_dep_set, e)) { continue; @@ -65,6 +65,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) DeclInfo *d = decl_info_of_entity(e); lb_build_nested_proc(p, &d->proc_lit->ProcLit, e); } + rw_mutex_shared_unlock(&gpd->mutex); } else { lb_build_nested_proc(p, pl, e); }