Minimize mutex usage when in single threaded mode.

This commit is contained in:
gingerBill
2025-09-10 21:41:52 +01:00
parent 992cad101c
commit 5ea2e1fe60
7 changed files with 42 additions and 27 deletions
+1 -1
View File
@@ -948,7 +948,7 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
error(ident, "foreign library names must be an identifier"); error(ident, "foreign library names must be an identifier");
} else { } else {
String name = ident->Ident.token.string; String name = ident->Ident.token.string;
Entity *found = scope_lookup(ctx->scope, name); Entity *found = scope_lookup(ctx->scope, name, ident->Ident.hash);
if (found == nullptr) { if (found == nullptr) {
if (is_blank_ident(name)) { if (is_blank_ident(name)) {
+5 -5
View File
@@ -1738,7 +1738,7 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam
o->expr = n; o->expr = n;
String name = n->Ident.token.string; String name = n->Ident.token.string;
Entity *e = scope_lookup(c->scope, name); Entity *e = scope_lookup(c->scope, name, n->Ident.hash);
if (e == nullptr) { if (e == nullptr) {
if (is_blank_ident(name)) { if (is_blank_ident(name)) {
error(n, "'_' cannot be used as a value"); error(n, "'_' cannot be used as a value");
@@ -5361,7 +5361,7 @@ gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *
} }
} else */if (node->kind == Ast_Ident) { } else */if (node->kind == Ast_Ident) {
String name = node->Ident.token.string; String name = node->Ident.token.string;
return scope_lookup(c->scope, name); return scope_lookup(c->scope, name, node->Ident.hash);
} else if (!ident_only) if (node->kind == Ast_SelectorExpr) { } else if (!ident_only) if (node->kind == Ast_SelectorExpr) {
ast_node(se, SelectorExpr, node); ast_node(se, SelectorExpr, node);
if (se->token.kind == Token_ArrowRight) { if (se->token.kind == Token_ArrowRight) {
@@ -5383,7 +5383,7 @@ gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *
if (op_expr->kind == Ast_Ident) { if (op_expr->kind == Ast_Ident) {
String op_name = op_expr->Ident.token.string; String op_name = op_expr->Ident.token.string;
Entity *e = scope_lookup(c->scope, op_name); Entity *e = scope_lookup(c->scope, op_name, op_expr->Ident.hash);
if (e == nullptr) { if (e == nullptr) {
return nullptr; return nullptr;
} }
@@ -5480,7 +5480,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod
if (op_expr->kind == Ast_Ident) { if (op_expr->kind == Ast_Ident) {
String op_name = op_expr->Ident.token.string; String op_name = op_expr->Ident.token.string;
Entity *e = scope_lookup(c->scope, op_name); Entity *e = scope_lookup(c->scope, op_name, op_expr->Ident.hash);
add_entity_use(c, op_expr, e); add_entity_use(c, op_expr, e);
expr_entity = e; expr_entity = e;
@@ -5903,7 +5903,7 @@ gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = fals
return true; return true;
} }
} else { } else {
Entity *e = scope_lookup(s, name); Entity *e = scope_lookup(s, name, i->hash);
if (e != nullptr) { if (e != nullptr) {
if (out_scope) *out_scope = e->scope; if (out_scope) *out_scope = e->scope;
return true; return true;
+7 -5
View File
@@ -484,7 +484,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
} }
if (ident_node != nullptr) { if (ident_node != nullptr) {
ast_node(i, Ident, ident_node); ast_node(i, Ident, ident_node);
e = scope_lookup(ctx->scope, i->token.string); e = scope_lookup(ctx->scope, i->token.string, i->hash);
if (e != nullptr && e->kind == Entity_Variable) { if (e != nullptr && e->kind == Entity_Variable) {
used = (e->flags & EntityFlag_Used) != 0; // NOTE(bill): Make backup just in case used = (e->flags & EntityFlag_Used) != 0; // NOTE(bill): Make backup just in case
} }
@@ -1812,8 +1812,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
error(node, "Iteration over a bit_set of an enum is not allowed runtime type information (RTTI) has been disallowed"); error(node, "Iteration over a bit_set of an enum is not allowed runtime type information (RTTI) has been disallowed");
} }
if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) { if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) {
String name = rs->vals[0]->Ident.token.string; AstIdent *ident = &rs->vals[0]->Ident;
Entity *found = scope_lookup(ctx->scope, name); String name = ident->token.string;
Entity *found = scope_lookup(ctx->scope, name, ident->hash);
if (found && are_types_identical(found->type, t->BitSet.elem)) { if (found && are_types_identical(found->type, t->BitSet.elem)) {
ERROR_BLOCK(); ERROR_BLOCK();
gbString s = expr_to_string(expr); gbString s = expr_to_string(expr);
@@ -1857,8 +1858,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
error(node, "#reverse for is not supported for map types, as maps are unordered"); error(node, "#reverse for is not supported for map types, as maps are unordered");
} }
if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) { if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) {
String name = rs->vals[0]->Ident.token.string; AstIdent *ident = &rs->vals[0]->Ident;
Entity *found = scope_lookup(ctx->scope, name); String name = ident->token.string;
Entity *found = scope_lookup(ctx->scope, name, ident->hash);
if (found && are_types_identical(found->type, t->Map.key)) { if (found && are_types_identical(found->type, t->Map.key)) {
ERROR_BLOCK(); ERROR_BLOCK();
gbString s = expr_to_string(expr); gbString s = expr_to_string(expr);
+25 -14
View File
@@ -380,16 +380,25 @@ gb_internal Entity *scope_lookup_current(Scope *s, String const &name) {
} }
gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) { gb_global std::atomic<bool> in_single_threaded_checker_stage;
gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_, u32 hash) {
bool is_single_threaded = in_single_threaded_checker_stage.load(std::memory_order_relaxed);
if (scope != nullptr) { if (scope != nullptr) {
bool gone_thru_proc = false; bool gone_thru_proc = false;
bool gone_thru_package = false; bool gone_thru_package = false;
StringHashKey key = string_hash_string(name); StringHashKey key = {};
if (hash) {
key.hash = hash;
key.string = name;
} else {
key = string_hash_string(name);
}
for (Scope *s = scope; s != nullptr; s = s->parent) { for (Scope *s = scope; s != nullptr; s = s->parent) {
Entity **found = nullptr; Entity **found = nullptr;
rw_mutex_shared_lock(&s->mutex); if (!is_single_threaded) rw_mutex_shared_lock(&s->mutex);
found = string_map_get(&s->elements, key); found = string_map_get(&s->elements, key);
rw_mutex_shared_unlock(&s->mutex); if (!is_single_threaded) rw_mutex_shared_unlock(&s->mutex);
if (found) { if (found) {
Entity *e = *found; Entity *e = *found;
if (gone_thru_proc) { if (gone_thru_proc) {
@@ -424,9 +433,9 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s
if (scope_) *scope_ = nullptr; if (scope_) *scope_ = nullptr;
} }
gb_internal Entity *scope_lookup(Scope *s, String const &name) { gb_internal Entity *scope_lookup(Scope *s, String const &name, u32 hash) {
Entity *entity = nullptr; Entity *entity = nullptr;
scope_lookup_parent(s, name, nullptr, &entity); scope_lookup_parent(s, name, nullptr, &entity, hash);
return entity; return entity;
} }
@@ -507,11 +516,9 @@ end:;
return result; return result;
} }
gb_global bool in_single_threaded_checker_stage = false;
gb_internal Entity *scope_insert(Scope *s, Entity *entity) { gb_internal Entity *scope_insert(Scope *s, Entity *entity) {
String name = entity->token.string; String name = entity->token.string;
if (in_single_threaded_checker_stage) { if (in_single_threaded_checker_stage.load(std::memory_order_relaxed)) {
return scope_insert_with_name_no_mutex(s, name, entity); return scope_insert_with_name_no_mutex(s, name, entity);
} else { } else {
return scope_insert_with_name(s, name, entity); return scope_insert_with_name(s, name, entity);
@@ -853,9 +860,13 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope, u64 vet_flags) {
gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) {
rw_mutex_lock(&d->deps_mutex); if (in_single_threaded_checker_stage.load(std::memory_order_relaxed)) {
ptr_set_add(&d->deps, e); ptr_set_add(&d->deps, e);
rw_mutex_unlock(&d->deps_mutex); } else {
rw_mutex_lock(&d->deps_mutex);
ptr_set_add(&d->deps, e);
rw_mutex_unlock(&d->deps_mutex);
}
} }
gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) { gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) {
if (d == nullptr || type == nullptr) { if (d == nullptr || type == nullptr) {
@@ -4958,7 +4969,7 @@ gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d)
} }
gb_internal void check_all_global_entities(Checker *c) { gb_internal void check_all_global_entities(Checker *c) {
in_single_threaded_checker_stage = true; in_single_threaded_checker_stage.store(true, std::memory_order_relaxed);
// NOTE(bill): This must be single threaded // NOTE(bill): This must be single threaded
// Don't bother trying // Don't bother trying
@@ -4980,7 +4991,7 @@ gb_internal void check_all_global_entities(Checker *c) {
} }
} }
in_single_threaded_checker_stage = false; in_single_threaded_checker_stage.store(false, std::memory_order_relaxed);
} }
+2 -2
View File
@@ -623,8 +623,8 @@ gb_internal Entity *entity_of_node(Ast *expr);
gb_internal Entity *scope_lookup_current(Scope *s, String const &name); gb_internal Entity *scope_lookup_current(Scope *s, String const &name);
gb_internal Entity *scope_lookup (Scope *s, String const &name); gb_internal Entity *scope_lookup (Scope *s, String const &name, u32 hash=0);
gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_, u32 hash=0);
gb_internal Entity *scope_insert (Scope *s, Entity *entity); gb_internal Entity *scope_insert (Scope *s, Entity *entity);
+1
View File
@@ -750,6 +750,7 @@ gb_internal Ast *ast_matrix_index_expr(AstFile *f, Ast *expr, Token open, Token
gb_internal Ast *ast_ident(AstFile *f, Token token) { gb_internal Ast *ast_ident(AstFile *f, Token token) {
Ast *result = alloc_ast_node(f, Ast_Ident); Ast *result = alloc_ast_node(f, Ast_Ident);
result->Ident.token = token; result->Ident.token = token;
result->Ident.hash = string_hash(token.string);
return result; return result;
} }
+1
View File
@@ -396,6 +396,7 @@ struct AstSplitArgs {
AST_KIND(Ident, "identifier", struct { \ AST_KIND(Ident, "identifier", struct { \
Token token; \ Token token; \
Entity *entity; \ Entity *entity; \
u32 hash; \
}) \ }) \
AST_KIND(Implicit, "implicit", Token) \ AST_KIND(Implicit, "implicit", Token) \
AST_KIND(Uninit, "uninitialized value", Token) \ AST_KIND(Uninit, "uninitialized value", Token) \