mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix race condition with regards to #soa arrays by using the fields mutex
This commit is contained in:
+5
-5
@@ -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);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user