Browse Source

Disable the need for mutexes in single threaded checker stage

gingerBill 1 year ago
parent
commit
eb6805ef40
3 changed files with 32 additions and 41 deletions
  1. 3 1
      src/check_expr.cpp
  2. 19 30
      src/checker.cpp
  3. 10 10
      src/types.cpp

+ 3 - 1
src/check_expr.cpp

@@ -500,7 +500,9 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E
 		nctx.no_polymorphic_errors = false;
 		nctx.no_polymorphic_errors = false;
 
 
 		// NOTE(bill): Reset scope from the failed procedure type
 		// NOTE(bill): Reset scope from the failed procedure type
-		scope_reset(scope);
+		scope->head_child.store(nullptr, std::memory_order_relaxed);
+		string_map_clear(&scope->elements);
+		ptr_set_clear(&scope->imported);
 
 
 		// LEAK NOTE(bill): Cloning this AST may be leaky but this is not really an issue due to arena-based allocation
 		// LEAK NOTE(bill): Cloning this AST may be leaky but this is not really an issue due to arena-based allocation
 		Ast *cloned_proc_type_node = clone_ast(pt->node);
 		Ast *cloned_proc_type_node = clone_ast(pt->node);

+ 19 - 30
src/checker.cpp

@@ -1,5 +1,7 @@
 #define DEBUG_CHECK_ALL_PROCEDURES 1
 #define DEBUG_CHECK_ALL_PROCEDURES 1
 
 
+gb_global bool in_single_threaded_checker_stage = false;
+
 #include "entity.cpp"
 #include "entity.cpp"
 #include "types.cpp"
 #include "types.cpp"
 
 
@@ -50,15 +52,6 @@ gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *f
 	return check_rtti_type_disallowed(ast_token(expr), type, format);
 	return check_rtti_type_disallowed(ast_token(expr), type, format);
 }
 }
 
 
-gb_internal void scope_reset(Scope *scope) {
-	if (scope == nullptr) return;
-
-	rw_mutex_lock(&scope->mutex);
-	scope->head_child.store(nullptr, std::memory_order_relaxed);
-	string_map_clear(&scope->elements);
-	ptr_set_clear(&scope->imported);
-	rw_mutex_unlock(&scope->mutex);
-}
 
 
 gb_internal void scope_reserve(Scope *scope, isize count) {
 gb_internal void scope_reserve(Scope *scope, isize count) {
 	string_map_reserve(&scope->elements, 2*count);
 	string_map_reserve(&scope->elements, 2*count);
@@ -168,16 +161,13 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j
 }
 }
 
 
 
 
-
-
-
 gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
 gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
 	gb_zero_item(d);
 	gb_zero_item(d);
 	if (parent) {
 	if (parent) {
-		mutex_lock(&parent->next_mutex);
+		if (!in_single_threaded_checker_stage) mutex_lock(&parent->next_mutex);
 		d->next_sibling = parent->next_child;
 		d->next_sibling = parent->next_child;
 		parent->next_child = d;
 		parent->next_child = d;
-		mutex_unlock(&parent->next_mutex);
+		if (!in_single_threaded_checker_stage) mutex_unlock(&parent->next_mutex);
 	}
 	}
 	d->parent = parent;
 	d->parent = parent;
 	d->scope  = scope;
 	d->scope  = scope;
@@ -384,7 +374,6 @@ gb_internal Entity *scope_lookup_current(Scope *s, String const &name) {
 	return nullptr;
 	return nullptr;
 }
 }
 
 
-gb_global bool in_single_threaded_mode_scopes = false;
 
 
 gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) {
 gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) {
 	if (scope != nullptr) {
 	if (scope != nullptr) {
@@ -393,9 +382,9 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s
 		StringHashKey key = string_hash_string(name);
 		StringHashKey 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;
-			if (!in_single_threaded_mode_scopes) rw_mutex_shared_lock(&s->mutex);
+			if (!in_single_threaded_checker_stage) rw_mutex_shared_lock(&s->mutex);
 			found = string_map_get(&s->elements, key);
 			found = string_map_get(&s->elements, key);
-			if (!in_single_threaded_mode_scopes) rw_mutex_shared_unlock(&s->mutex);
+			if (!in_single_threaded_checker_stage) rw_mutex_shared_unlock(&s->mutex);
 			if (found) {
 			if (found) {
 				Entity *e = *found;
 				Entity *e = *found;
 				if (gone_thru_proc) {
 				if (gone_thru_proc) {
@@ -515,7 +504,7 @@ end:;
 
 
 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_mode_scopes) {
+	if (in_single_threaded_checker_stage) {
 		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);
@@ -773,17 +762,17 @@ 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) rw_mutex_lock(&d->deps_mutex);
 	ptr_set_add(&d->deps, e);
 	ptr_set_add(&d->deps, e);
-	rw_mutex_unlock(&d->deps_mutex);
+	if (!in_single_threaded_checker_stage) 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) {
 	if (d == nullptr) {
 		return;
 		return;
 	}
 	}
-	rw_mutex_lock(&d->type_info_deps_mutex);
+	if (!in_single_threaded_checker_stage) rw_mutex_lock(&d->type_info_deps_mutex);
 	ptr_set_add(&d->type_info_deps, type);
 	ptr_set_add(&d->type_info_deps, type);
-	rw_mutex_unlock(&d->type_info_deps_mutex);
+	if (!in_single_threaded_checker_stage) rw_mutex_unlock(&d->type_info_deps_mutex);
 }
 }
 
 
 
 
@@ -1394,7 +1383,7 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp
 		return;
 		return;
 	}
 	}
 	GB_ASSERT(ctx->checker != nullptr);
 	GB_ASSERT(ctx->checker != nullptr);
-	mutex_lock(&ctx->mutex);
+	if (!in_single_threaded_checker_stage) mutex_lock(&ctx->mutex);
 
 
 	auto type_path = ctx->type_path;
 	auto type_path = ctx->type_path;
 	array_clear(type_path);
 	array_clear(type_path);
@@ -1413,7 +1402,7 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp
 
 
 	ctx->untyped = untyped;
 	ctx->untyped = untyped;
 
 
-	mutex_unlock(&ctx->mutex);
+	if (!in_single_threaded_checker_stage) mutex_unlock(&ctx->mutex);
 }
 }
 
 
 
 
@@ -1559,9 +1548,9 @@ gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMod
 	if (c->untyped != nullptr) {
 	if (c->untyped != nullptr) {
 		map_set(c->untyped, expr, make_expr_info(mode, type, value, false));
 		map_set(c->untyped, expr, make_expr_info(mode, type, value, false));
 	} else {
 	} else {
-		rw_mutex_lock(&c->info->global_untyped_mutex);
+		if (!in_single_threaded_checker_stage) rw_mutex_lock(&c->info->global_untyped_mutex);
 		map_set(&c->info->global_untyped, expr, make_expr_info(mode, type, value, false));
 		map_set(&c->info->global_untyped, expr, make_expr_info(mode, type, value, false));
-		rw_mutex_unlock(&c->info->global_untyped_mutex);
+		if (!in_single_threaded_checker_stage) rw_mutex_unlock(&c->info->global_untyped_mutex);
 	}
 	}
 }
 }
 
 
@@ -1571,10 +1560,10 @@ gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) {
 		GB_ASSERT(map_get(c->untyped, e) == nullptr);
 		GB_ASSERT(map_get(c->untyped, e) == nullptr);
 	} else {
 	} else {
 		auto *untyped = &c->info->global_untyped;
 		auto *untyped = &c->info->global_untyped;
-		rw_mutex_lock(&c->info->global_untyped_mutex);
+		if (!in_single_threaded_checker_stage) rw_mutex_lock(&c->info->global_untyped_mutex);
 		map_remove(untyped, e);
 		map_remove(untyped, e);
 		GB_ASSERT(map_get(untyped, e) == nullptr);
 		GB_ASSERT(map_get(untyped, e) == nullptr);
-		rw_mutex_unlock(&c->info->global_untyped_mutex);
+		if (!in_single_threaded_checker_stage) rw_mutex_unlock(&c->info->global_untyped_mutex);
 	}
 	}
 }
 }
 
 
@@ -4596,7 +4585,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_mode_scopes = true;
+	in_single_threaded_checker_stage = true;
 
 
 	// NOTE(bill): This must be single threaded
 	// NOTE(bill): This must be single threaded
 	// Don't bother trying
 	// Don't bother trying
@@ -4618,7 +4607,7 @@ gb_internal void check_all_global_entities(Checker *c) {
 		}
 		}
 	}
 	}
 
 
-	in_single_threaded_mode_scopes = false;
+	in_single_threaded_checker_stage = false;
 }
 }
 
 
 
 

+ 10 - 10
src/types.cpp

@@ -808,9 +808,9 @@ gb_internal void type_path_init(TypePath *tp) {
 }
 }
 
 
 gb_internal void type_path_free(TypePath *tp) {
 gb_internal void type_path_free(TypePath *tp) {
-	mutex_lock(&tp->mutex);
+	if (!in_single_threaded_checker_stage) mutex_lock(&tp->mutex);
 	array_free(&tp->path);
 	array_free(&tp->path);
-	mutex_unlock(&tp->mutex);
+	if (!in_single_threaded_checker_stage) mutex_unlock(&tp->mutex);
 }
 }
 
 
 gb_internal void type_path_print_illegal_cycle(TypePath *tp, isize start_index) {
 gb_internal void type_path_print_illegal_cycle(TypePath *tp, isize start_index) {
@@ -839,7 +839,7 @@ gb_internal bool type_path_push(TypePath *tp, Type *t) {
 	}
 	}
 	Entity *e = t->Named.type_name;
 	Entity *e = t->Named.type_name;
 
 
-	mutex_lock(&tp->mutex);
+	if (!in_single_threaded_checker_stage) mutex_lock(&tp->mutex);
 
 
 	for (isize i = 0; i < tp->path.count; i++) {
 	for (isize i = 0; i < tp->path.count; i++) {
 		Entity *p = tp->path[i];
 		Entity *p = tp->path[i];
@@ -850,18 +850,18 @@ gb_internal bool type_path_push(TypePath *tp, Type *t) {
 
 
 	array_add(&tp->path, e);
 	array_add(&tp->path, e);
 
 
-	mutex_unlock(&tp->mutex);
+	if (!in_single_threaded_checker_stage) mutex_unlock(&tp->mutex);
 
 
 	return true;
 	return true;
 }
 }
 
 
 gb_internal void type_path_pop(TypePath *tp) {
 gb_internal void type_path_pop(TypePath *tp) {
 	if (tp != nullptr) {
 	if (tp != nullptr) {
-		mutex_lock(&tp->mutex);
+		if (!in_single_threaded_checker_stage) mutex_lock(&tp->mutex);
 		if (tp->path.count > 0) {
 		if (tp->path.count > 0) {
 			array_pop(&tp->path);
 			array_pop(&tp->path);
 		}
 		}
-		mutex_unlock(&tp->mutex);
+		if (!in_single_threaded_checker_stage) mutex_unlock(&tp->mutex);
 	}
 	}
 }
 }
 
 
@@ -3216,8 +3216,8 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name
 			GB_ASSERT(e->kind == Entity_TypeName);
 			GB_ASSERT(e->kind == Entity_TypeName);
 			if (e->TypeName.objc_metadata) {
 			if (e->TypeName.objc_metadata) {
 				auto *md = e->TypeName.objc_metadata;
 				auto *md = e->TypeName.objc_metadata;
-				mutex_lock(md->mutex);
-				defer (mutex_unlock(md->mutex));
+				if (!in_single_threaded_checker_stage) mutex_lock(md->mutex);
+				defer (if (!in_single_threaded_checker_stage) mutex_unlock(md->mutex));
 				for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
 				for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
 					GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup);
 					GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup);
 					if (entry.name == field_name) {
 					if (entry.name == field_name) {
@@ -3294,8 +3294,8 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name
 			GB_ASSERT(e->kind == Entity_TypeName);
 			GB_ASSERT(e->kind == Entity_TypeName);
 			if (e->TypeName.objc_metadata) {
 			if (e->TypeName.objc_metadata) {
 				auto *md = e->TypeName.objc_metadata;
 				auto *md = e->TypeName.objc_metadata;
-				mutex_lock(md->mutex);
-				defer (mutex_unlock(md->mutex));
+				if (!in_single_threaded_checker_stage) mutex_lock(md->mutex);
+				defer (if (!in_single_threaded_checker_stage) mutex_unlock(md->mutex));
 				for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
 				for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
 					GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup);
 					GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup);
 					if (entry.name == field_name) {
 					if (entry.name == field_name) {