Browse Source

Use `RwMutex` for `gen_procs`

gingerBill 2 years ago
parent
commit
774fea1e63
4 changed files with 20 additions and 23 deletions
  1. 8 8
      src/check_expr.cpp
  2. 7 6
      src/checker.cpp
  3. 3 8
      src/checker.hpp
  4. 2 1
      src/llvm_backend_stmt.cpp

+ 8 - 8
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());
 	auto *found = map_get(&info->gen_procs, base_entity->identifier.load());
 	if (found) {
 	if (found) {
 		gen_procs = *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) {
 		for (Entity *other : gen_procs->procs) {
 			Type *pt = base_type(other->type);
 			Type *pt = base_type(other->type);
 			if (are_types_identical(pt, final_proc_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 ////////////////////////////
 				// @@GPM ////////////////////////////
 				mutex_unlock(&info->gen_procs_mutex);
 				mutex_unlock(&info->gen_procs_mutex);
 				/////////////////////////////////////
 				/////////////////////////////////////
@@ -455,7 +455,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E
 				return true;
 				return true;
 			}
 			}
 		}
 		}
-		mutex_unlock(&gen_procs->mutex); // @local-mutex
+		rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex
 	} else {
 	} else {
 		gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData);
 		gen_procs = gb_alloc_item(permanent_allocator(), GenProcsData);
 		gen_procs->procs.allocator = heap_allocator();
 		gen_procs->procs.allocator = heap_allocator();
@@ -481,11 +481,11 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E
 			return false;
 			return false;
 		}
 		}
 
 
-		mutex_lock(&gen_procs->mutex); // @local-mutex
+		rw_mutex_shared_lock(&gen_procs->mutex); // @local-mutex
 		for (Entity *other : gen_procs->procs) {
 		for (Entity *other : gen_procs->procs) {
 			Type *pt = base_type(other->type);
 			Type *pt = base_type(other->type);
 			if (are_types_identical(pt, final_proc_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) {
 				if (poly_proc_data) {
 					poly_proc_data->gen_entity = other;
 					poly_proc_data->gen_entity = other;
@@ -509,7 +509,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E
 				return true;
 				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);
 		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);
 	ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo);
 	proc_info->file  = file;
 	proc_info->file  = file;

+ 7 - 6
src/checker.cpp

@@ -1356,9 +1356,9 @@ gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) {
 		}
 		}
 		return nullptr;
 		return nullptr;
 	} else {
 	} 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);
 		ExprInfo **found = map_get(&c->info->global_untyped, expr);
+		rw_mutex_shared_unlock(&c->info->global_untyped_mutex);
 		if (found) {
 		if (found) {
 			return *found;
 			return *found;
 		}
 		}
@@ -1370,9 +1370,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 {
-		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));
 		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);
 		GB_ASSERT(map_get(c->untyped, e) == nullptr);
 	} else {
 	} else {
 		auto *untyped = &c->info->global_untyped;
 		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);
 		map_remove(untyped, e);
 		GB_ASSERT(map_get(untyped, e) == nullptr);
 		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;
 	BlockingMutex *mutex = &ctx->info->type_and_value_mutex;
 	if (ctx->pkg) {
 	if (ctx->pkg) {
+		// TODO(bill): is a per package mutex is a good idea here?
 		mutex = &ctx->pkg->type_and_value_mutex;
 		mutex = &ctx->pkg->type_and_value_mutex;
 	}
 	}
 
 

+ 3 - 8
src/checker.hpp

@@ -317,7 +317,7 @@ struct LoadFileCache {
 
 
 struct GenProcsData {
 struct GenProcsData {
 	Array<Entity *> procs;
 	Array<Entity *> procs;
-	BlockingMutex   mutex;
+	RwMutex         mutex;
 };
 };
 
 
 // CheckerInfo stores all the symbol information for a type-checked program
 // CheckerInfo stores all the symbol information for a type-checked program
@@ -347,14 +347,9 @@ struct CheckerInfo {
 
 
 
 
 	// Below are accessed within procedures
 	// 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
 	UntypedExprInfoMap global_untyped; // NOTE(bill): This needs to be a map and not on the Ast
 	                                   // as it needs to be iterated across afterwards
 	                                   // as it needs to be iterated across afterwards
-	BlockingMutex global_untyped_mutex;
 	BlockingMutex builtin_mutex;
 	BlockingMutex builtin_mutex;
 
 
 	BlockingMutex type_and_value_mutex;
 	BlockingMutex type_and_value_mutex;
@@ -388,7 +383,7 @@ struct CheckerInfo {
 	BlockingMutex load_file_mutex;
 	BlockingMutex load_file_mutex;
 	StringMap<LoadFileCache *> load_file_cache;
 	StringMap<LoadFileCache *> load_file_cache;
 
 
-	BlockingMutex all_procedures_mutex;;
+	BlockingMutex all_procedures_mutex;
 	Array<ProcInfo *> all_procedures;
 	Array<ProcInfo *> all_procedures;
 };
 };
 
 

+ 2 - 1
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);
 			auto *found = map_get(&info->gen_procs, ident);
 			if (found) {
 			if (found) {
 				GenProcsData *gpd = *found;
 				GenProcsData *gpd = *found;
-				MUTEX_GUARD(&gpd->mutex);
+				rw_mutex_shared_lock(&gpd->mutex);
 				for (Entity *e : gpd->procs) {
 				for (Entity *e : gpd->procs) {
 					if (!ptr_set_exists(min_dep_set, e)) {
 					if (!ptr_set_exists(min_dep_set, e)) {
 						continue;
 						continue;
@@ -65,6 +65,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd)
 					DeclInfo *d = decl_info_of_entity(e);
 					DeclInfo *d = decl_info_of_entity(e);
 					lb_build_nested_proc(p, &d->proc_lit->ProcLit, e);
 					lb_build_nested_proc(p, &d->proc_lit->ProcLit, e);
 				}
 				}
+				rw_mutex_shared_unlock(&gpd->mutex);
 			} else {
 			} else {
 				lb_build_nested_proc(p, pl, e);
 				lb_build_nested_proc(p, pl, e);
 			}
 			}