Browse Source

Fix race condition with regards to #soa arrays by using the fields mutex

gingerBill 1 year ago
parent
commit
cbfb32c34c
2 changed files with 15 additions and 5 deletions
  1. 5 5
      src/check_type.cpp
  2. 10 0
      src/threading.cpp

+ 5 - 5
src/check_type.cpp

@@ -2553,6 +2553,8 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
 		GB_ASSERT(is_type_struct(elem));
 		GB_ASSERT(is_type_struct(elem));
 
 
 		Type *old_struct = base_type(elem);
 		Type *old_struct = base_type(elem);
+		RW_MUTEX_GUARD(&old_struct->Struct.fields_mutex);
+
 		field_count = old_struct->Struct.fields.count;
 		field_count = old_struct->Struct.fields.count;
 
 
 		soa_struct = alloc_type_struct();
 		soa_struct = alloc_type_struct();
@@ -2593,21 +2595,19 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
 	}
 	}
 
 
 	if (soa_kind != StructSoa_Fixed) {
 	if (soa_kind != StructSoa_Fixed) {
-		Entity *len_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+0);
+		Entity *len_field = alloc_entity_field(scope, make_token_ident("__$len"), t_int, false, cast(i32)field_count+0);
 		soa_struct->Struct.fields[field_count+0] = len_field;
 		soa_struct->Struct.fields[field_count+0] = len_field;
 		add_entity(ctx, scope, nullptr, len_field);
 		add_entity(ctx, scope, nullptr, len_field);
 		add_entity_use(ctx, nullptr, len_field);
 		add_entity_use(ctx, nullptr, len_field);
 
 
 		if (soa_kind == StructSoa_Dynamic) {
 		if (soa_kind == StructSoa_Dynamic) {
-			Entity *cap_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+1);
+			Entity *cap_field = alloc_entity_field(scope, make_token_ident("__$cap"), t_int, false, cast(i32)field_count+1);
 			soa_struct->Struct.fields[field_count+1] = cap_field;
 			soa_struct->Struct.fields[field_count+1] = cap_field;
 			add_entity(ctx, scope, nullptr, cap_field);
 			add_entity(ctx, scope, nullptr, cap_field);
 			add_entity_use(ctx, nullptr, cap_field);
 			add_entity_use(ctx, nullptr, cap_field);
 
 
-			Token token = {};
-			token.string = str_lit("allocator");
 			init_mem_allocator(ctx->checker);
 			init_mem_allocator(ctx->checker);
-			Entity *allocator_field = alloc_entity_field(scope, token, t_allocator, false, cast(i32)field_count+2);
+			Entity *allocator_field = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, cast(i32)field_count+2);
 			soa_struct->Struct.fields[field_count+2] = allocator_field;
 			soa_struct->Struct.fields[field_count+2] = allocator_field;
 			add_entity(ctx, scope, nullptr, allocator_field);
 			add_entity(ctx, scope, nullptr, allocator_field);
 			add_entity_use(ctx, nullptr, allocator_field);
 			add_entity_use(ctx, nullptr, allocator_field);

+ 10 - 0
src/threading.cpp

@@ -119,17 +119,25 @@ struct MutexGuard {
 	explicit MutexGuard(RecursiveMutex *rm) noexcept : rm{rm} {
 	explicit MutexGuard(RecursiveMutex *rm) noexcept : rm{rm} {
 		mutex_lock(this->rm);
 		mutex_lock(this->rm);
 	}
 	}
+	explicit MutexGuard(RwMutex *rm) noexcept : rwm{rwm} {
+		rw_mutex_lock(this->rwm);
+	}
 	explicit MutexGuard(BlockingMutex &bm) noexcept : bm{&bm} {
 	explicit MutexGuard(BlockingMutex &bm) noexcept : bm{&bm} {
 		mutex_lock(this->bm);
 		mutex_lock(this->bm);
 	}
 	}
 	explicit MutexGuard(RecursiveMutex &rm) noexcept : rm{&rm} {
 	explicit MutexGuard(RecursiveMutex &rm) noexcept : rm{&rm} {
 		mutex_lock(this->rm);
 		mutex_lock(this->rm);
 	}
 	}
+	explicit MutexGuard(RwMutex &rwm) noexcept : rwm{&rwm} {
+		rw_mutex_lock(this->rwm);
+	}
 	~MutexGuard() noexcept {
 	~MutexGuard() noexcept {
 		if (this->bm) {
 		if (this->bm) {
 			mutex_unlock(this->bm);
 			mutex_unlock(this->bm);
 		} else if (this->rm) {
 		} else if (this->rm) {
 			mutex_unlock(this->rm);
 			mutex_unlock(this->rm);
+		} else if (this->rwm) {
+			rw_mutex_unlock(this->rwm);
 		}
 		}
 	}
 	}
 
 
@@ -137,10 +145,12 @@ struct MutexGuard {
 
 
 	BlockingMutex *bm;
 	BlockingMutex *bm;
 	RecursiveMutex *rm;
 	RecursiveMutex *rm;
+	RwMutex *rwm;
 };
 };
 
 
 #define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m})
 #define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m})
 #define MUTEX_GUARD(m) mutex_lock(m); defer (mutex_unlock(m))
 #define MUTEX_GUARD(m) mutex_lock(m); defer (mutex_unlock(m))
+#define RW_MUTEX_GUARD(m) rw_mutex_lock(m); defer (rw_mutex_unlock(m))
 
 
 
 
 struct RecursiveMutex {
 struct RecursiveMutex {