mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Add mutex guards for signature scopes
This commit is contained in:
@@ -77,15 +77,19 @@ template <typename T> Slice<T> slice_from_array(Array<T> const &a);
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
Slice<T> slice_make(gbAllocator const &allocator, isize count) {
|
||||||
|
GB_ASSERT(count >= 0);
|
||||||
Slice<T> s = {};
|
Slice<T> s = {};
|
||||||
s.data = gb_alloc_array(allocator, T, count);
|
s.data = gb_alloc_array(allocator, T, count);
|
||||||
|
GB_ASSERT(s.data != nullptr);
|
||||||
s.count = count;
|
s.count = count;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
|
||||||
|
GB_ASSERT(count >= 0);
|
||||||
s->data = gb_alloc_array(allocator, T, count);
|
s->data = gb_alloc_array(allocator, T, count);
|
||||||
|
GB_ASSERT(s->data != nullptr);
|
||||||
s->count = count;
|
s->count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1286,7 +1286,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
|||||||
using_entities.allocator = heap_allocator();
|
using_entities.allocator = heap_allocator();
|
||||||
defer (array_free(&using_entities));
|
defer (array_free(&using_entities));
|
||||||
|
|
||||||
{
|
MUTEX_GUARD_BLOCK(ctx->scope->mutex) {
|
||||||
if (type->Proc.param_count > 0) {
|
if (type->Proc.param_count > 0) {
|
||||||
TypeTuple *params = &type->Proc.params->Tuple;
|
TypeTuple *params = &type->Proc.params->Tuple;
|
||||||
for_array(i, params->variables) {
|
for_array(i, params->variables) {
|
||||||
|
|||||||
@@ -4021,10 +4021,12 @@ void check_did_you_mean_scope(String const &name, Scope *scope) {
|
|||||||
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
|
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
|
||||||
defer (did_you_mean_destroy(&d));
|
defer (did_you_mean_destroy(&d));
|
||||||
|
|
||||||
|
mutex_lock(&scope->mutex);
|
||||||
for_array(i, scope->elements.entries) {
|
for_array(i, scope->elements.entries) {
|
||||||
Entity *e = scope->elements.entries[i].value;
|
Entity *e = scope->elements.entries[i].value;
|
||||||
did_you_mean_append(&d, e->token.string);
|
did_you_mean_append(&d, e->token.string);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&scope->mutex);
|
||||||
check_did_you_mean_print(&d);
|
check_did_you_mean_print(&d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -607,7 +607,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b
|
|||||||
|
|
||||||
case Entity_ImportName: {
|
case Entity_ImportName: {
|
||||||
Scope *scope = e->ImportName.scope;
|
Scope *scope = e->ImportName.scope;
|
||||||
for_array(i, scope->elements.entries) {
|
MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
|
||||||
String name = scope->elements.entries[i].key.string;
|
String name = scope->elements.entries[i].key.string;
|
||||||
Entity *decl = scope->elements.entries[i].value;
|
Entity *decl = scope->elements.entries[i].value;
|
||||||
if (!is_entity_exported(decl)) continue;
|
if (!is_entity_exported(decl)) continue;
|
||||||
|
|||||||
+1
-1
@@ -622,7 +622,7 @@ void check_scope_usage(Checker *c, Scope *scope) {
|
|||||||
Array<VettedEntity> vetted_entities = {};
|
Array<VettedEntity> vetted_entities = {};
|
||||||
array_init(&vetted_entities, heap_allocator());
|
array_init(&vetted_entities, heap_allocator());
|
||||||
|
|
||||||
for_array(i, scope->elements.entries) {
|
MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
|
||||||
Entity *e = scope->elements.entries[i].value;
|
Entity *e = scope->elements.entries[i].value;
|
||||||
if (e == nullptr) continue;
|
if (e == nullptr) continue;
|
||||||
VettedEntity ve = {};
|
VettedEntity ve = {};
|
||||||
|
|||||||
+24
-10
@@ -325,18 +325,32 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
|||||||
// TODO(bill): Throughly test!
|
// TODO(bill): Throughly test!
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#if defined(GB_COMPILER_MSVC)
|
#if defined(GB_COMPILER_MSVC)
|
||||||
case gbAllocation_Alloc: {
|
case gbAllocation_Alloc:
|
||||||
isize aligned_size = align_formula_isize(size, alignment);
|
if (size == 0) {
|
||||||
// TODO(bill): Make sure this is aligned correctly
|
return NULL;
|
||||||
ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size);
|
} else {
|
||||||
} break;
|
isize aligned_size = align_formula_isize(size, alignment);
|
||||||
|
// TODO(bill): Make sure this is aligned correctly
|
||||||
|
ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case gbAllocation_Free:
|
case gbAllocation_Free:
|
||||||
HeapFree(GetProcessHeap(), 0, old_memory);
|
if (old_memory != nullptr) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, old_memory);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case gbAllocation_Resize:
|
||||||
|
if (old_memory != nullptr && size > 0) {
|
||||||
|
isize aligned_size = align_formula_isize(size, alignment);
|
||||||
|
ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size);
|
||||||
|
} else if (old_memory != nullptr) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, old_memory);
|
||||||
|
} else if (size != 0) {
|
||||||
|
isize aligned_size = align_formula_isize(size, alignment);
|
||||||
|
// TODO(bill): Make sure this is aligned correctly
|
||||||
|
ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case gbAllocation_Resize: {
|
|
||||||
isize aligned_size = align_formula_isize(size, alignment);
|
|
||||||
ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size);
|
|
||||||
} break;
|
|
||||||
#elif defined(GB_SYSTEM_LINUX)
|
#elif defined(GB_SYSTEM_LINUX)
|
||||||
// TODO(bill): *nix version that's decent
|
// TODO(bill): *nix version that's decent
|
||||||
case gbAllocation_Alloc: {
|
case gbAllocation_Alloc: {
|
||||||
|
|||||||
@@ -68,6 +68,40 @@ void yield_thread(void);
|
|||||||
void yield_process(void);
|
void yield_process(void);
|
||||||
|
|
||||||
|
|
||||||
|
struct MutexGuard {
|
||||||
|
MutexGuard() = delete;
|
||||||
|
MutexGuard(MutexGuard const &) = delete;
|
||||||
|
|
||||||
|
MutexGuard(BlockingMutex *bm) : bm{bm} {
|
||||||
|
mutex_lock(this->bm);
|
||||||
|
}
|
||||||
|
MutexGuard(RecursiveMutex *rm) : rm{rm} {
|
||||||
|
mutex_lock(this->rm);
|
||||||
|
}
|
||||||
|
MutexGuard(BlockingMutex &bm) : bm{&bm} {
|
||||||
|
mutex_lock(this->bm);
|
||||||
|
}
|
||||||
|
MutexGuard(RecursiveMutex &rm) : rm{&rm} {
|
||||||
|
mutex_lock(this->rm);
|
||||||
|
}
|
||||||
|
~MutexGuard() {
|
||||||
|
if (this->bm) {
|
||||||
|
mutex_unlock(this->bm);
|
||||||
|
} else if (this->rm) {
|
||||||
|
mutex_unlock(this->rm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const { return true; }
|
||||||
|
|
||||||
|
BlockingMutex *bm;
|
||||||
|
RecursiveMutex *rm;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_) = m)
|
||||||
|
#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_) = m
|
||||||
|
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
struct BlockingMutex {
|
struct BlockingMutex {
|
||||||
SRWLOCK srwlock;
|
SRWLOCK srwlock;
|
||||||
|
|||||||
Reference in New Issue
Block a user