aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-01-02 12:28:38 +0000
committergingerBill <bill@gingerbill.org>2023-01-02 12:28:38 +0000
commit015fe924b8f9a1d8cb78d307a4f8ef6791402bea (patch)
tree244f74ef163f47c80475e47f36051e6f6a6fb7ce /src/checker.cpp
parenta5ce8a8c0bc33afb6a4cf7baa16528c0a551d8e0 (diff)
Remove use of queues for procedure checking.
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp108
1 files changed, 42 insertions, 66 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 1e40f04a6..30e7409f9 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1195,7 +1195,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp
GB_ASSERT(ctx->checker != nullptr);
mutex_lock(&ctx->mutex);
- auto *queue = ctx->procs_to_check_queue;
auto type_path = ctx->type_path;
array_clear(type_path);
@@ -1211,7 +1210,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp
add_curr_ast_file(ctx, file);
- ctx->procs_to_check_queue = queue;
ctx->untyped = untyped;
mutex_unlock(&ctx->mutex);
@@ -1232,7 +1230,7 @@ gb_internal void init_checker(Checker *c) {
mpmc_init(&c->procs_with_deferred_to_check, a, 1<<10);
// NOTE(bill): 1 Mi elements should be enough on average
- mpmc_init(&c->procs_to_check_queue, heap_allocator(), 1<<20);
+ array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20);
mpmc_init(&c->global_untyped_queue, a, 1<<20);
@@ -1244,7 +1242,7 @@ gb_internal void destroy_checker(Checker *c) {
destroy_checker_context(&c->builtin_ctx);
- mpmc_destroy(&c->procs_to_check_queue);
+ array_free(&c->procs_to_check);
mpmc_destroy(&c->global_untyped_queue);
}
@@ -1941,23 +1939,19 @@ gb_global std::atomic<bool> global_procedure_body_in_worker_queue = false;
gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc);
-gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) {
+gb_internal void check_procedure_later(Checker *c, ProcInfo *info) {
GB_ASSERT(info != nullptr);
GB_ASSERT(info->decl != nullptr);
if (MULTITHREAD_CHECKER && global_procedure_body_in_worker_queue) {
thread_pool_add_task(check_proc_info_worker_proc, info);
} else {
- if (build_context.threaded_checker && global_procedure_body_in_worker_queue) {
- GB_ASSERT(c->procs_to_check_queue != nullptr);
- }
-
- auto *queue = c->procs_to_check_queue ? c->procs_to_check_queue : &c->checker->procs_to_check_queue;
- mpmc_enqueue(queue, info);
+ GB_ASSERT(global_procedure_body_in_worker_queue == false);
+ array_add(&c->procs_to_check, info);
}
}
-gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) {
+gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) {
ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo);
info->file = file;
info->token = token;
@@ -4677,11 +4671,7 @@ struct CollectEntityWorkerData {
gb_global CollectEntityWorkerData *collect_entity_worker_data;
gb_internal WORKER_TASK_PROC(check_collect_entities_all_worker_proc) {
- isize thread_idx = 0;
- if (current_thread) {
- thread_idx = current_thread->idx;
- }
- CollectEntityWorkerData *wd = &collect_entity_worker_data[thread_idx];
+ CollectEntityWorkerData *wd = &collect_entity_worker_data[current_thread_index()];
Checker *c = wd->c;
CheckerContext *ctx = &wd->ctx;
@@ -4738,10 +4728,8 @@ gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *p
}
gb_internal WORKER_TASK_PROC(check_export_entities_worker_proc) {
- isize thread_idx = current_thread ? current_thread->idx : 0;
-
AstPackage *pkg = (AstPackage *)data;
- auto *wd = &collect_entity_worker_data[thread_idx];
+ auto *wd = &collect_entity_worker_data[current_thread_index()];
check_export_entities_in_pkg(&wd->ctx, pkg, &wd->untyped);
return 0;
}
@@ -5069,7 +5057,7 @@ gb_internal void calculate_global_init_order(Checker *c) {
}
-gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) {
+gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) {
if (pi == nullptr) {
return false;
}
@@ -5085,17 +5073,16 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u
}
return true;
}
+ if (e != nullptr && (e->flags & EntityFlag_ProcBodyChecked) != 0) {
+ GB_ASSERT(pi->decl->proc_checked);
+ return true;
+ }
+ pi->decl->proc_checked = true;
+ if (e != nullptr) {
+ e->flags |= EntityFlag_ProcBodyChecked;
+ }
}
- CheckerContext ctx = make_checker_context(c);
- defer (destroy_checker_context(&ctx));
- reset_checker_context(&ctx, pi->file, untyped);
- ctx.decl = pi->decl;
-
- GB_ASSERT(procs_to_check_queue != nullptr || MULTITHREAD_CHECKER);
-
- ctx.procs_to_check_queue = procs_to_check_queue;
-
GB_ASSERT(pi->type->kind == Type_Proc);
TypeProc *pt = &pi->type->Proc;
String name = pi->token.string;
@@ -5116,6 +5103,12 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u
}
}
+
+ CheckerContext ctx = make_checker_context(c);
+ defer (destroy_checker_context(&ctx));
+ reset_checker_context(&ctx, pi->file, untyped);
+ ctx.decl = pi->decl;
+
bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
@@ -5138,24 +5131,14 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u
ctx.state_flags &= ~StateFlag_type_assert;
}
- if (pi->body != nullptr && e != nullptr) {
- GB_ASSERT((e->flags & EntityFlag_ProcBodyChecked) == 0);
- }
-
check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body);
- MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) {
- if (e != nullptr) {
- e->flags |= EntityFlag_ProcBodyChecked;
- }
- pi->decl->proc_checked = true;
- }
add_untyped_expressions(&c->info, ctx.untyped);
return true;
}
GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *));
-gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped);
+gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped);
gb_internal void check_unchecked_bodies(Checker *c) {
// NOTE(2021-02-26, bill): Sanity checker
@@ -5193,15 +5176,13 @@ gb_internal void check_unchecked_bodies(Checker *c) {
}
debugf("unchecked: %.*s\n", LIT(e->token.string));
- mpmc_enqueue(&c->procs_to_check_queue, pi);
+ array_add(&c->procs_to_check, pi);
}
}
- auto *q = &c->procs_to_check_queue;
- ProcInfo *pi = nullptr;
- while (mpmc_dequeue(q, &pi)) {
+ for (ProcInfo *pi : c->procs_to_check) {
Entity *e = pi->decl->entity;
- if (consume_proc_info_queue(c, pi, q, &untyped)) {
+ if (consume_proc_info_queue(c, pi, &untyped)) {
add_dependency_to_set(c, e);
GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked);
}
@@ -5245,7 +5226,7 @@ gb_internal void check_test_procedures(Checker *c) {
gb_global std::atomic<isize> total_bodies_checked;
-gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) {
+gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) {
GB_ASSERT(pi->decl != nullptr);
if (pi->decl->parent && pi->decl->parent->entity) {
Entity *parent = pi->decl->parent->entity;
@@ -5253,14 +5234,14 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue
// This is prevent any possible race conditions in evaluation when multithreaded
// NOTE(bill): In single threaded mode, this should never happen
if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) {
- mpmc_enqueue(q, pi);
+ check_procedure_later(c, pi);
return false;
}
}
if (untyped) {
map_clear(untyped);
}
- bool ok = check_proc_info(c, pi, untyped, q);
+ bool ok = check_proc_info(c, pi, untyped);
total_bodies_checked.fetch_add(1, std::memory_order_relaxed);
return ok;
}
@@ -5273,12 +5254,9 @@ struct CheckProcedureBodyWorkerData {
gb_global CheckProcedureBodyWorkerData *check_procedure_bodies_worker_data;
gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) {
- isize thread_idx = 0;
- if (current_thread) {
- thread_idx = current_thread->idx;
- }
- UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[thread_idx].untyped;
- Checker *c = check_procedure_bodies_worker_data[thread_idx].c;
+ auto *wd = &check_procedure_bodies_worker_data[current_thread_index()];
+ UntypedExprInfoMap *untyped = &wd->untyped;
+ Checker *c = wd->c;
ProcInfo *pi = cast(ProcInfo *)data;
@@ -5294,7 +5272,7 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) {
}
}
map_clear(untyped);
- bool ok = check_proc_info(c, pi, untyped, nullptr);
+ bool ok = check_proc_info(c, pi, untyped);
total_bodies_checked.fetch_add(1, std::memory_order_relaxed);
return !ok;
}
@@ -5321,13 +5299,11 @@ gb_internal void check_procedure_bodies(Checker *c) {
});
if (thread_count == 1) {
- auto *this_queue = &c->procs_to_check_queue;
-
UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped;
-
- for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) {
- consume_proc_info_queue(c, pi, this_queue, untyped);
+ for_array(i, c->procs_to_check) {
+ consume_proc_info_queue(c, c->procs_to_check[i], untyped);
}
+ array_clear(&c->procs_to_check);
debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed));
return;
@@ -5335,12 +5311,12 @@ gb_internal void check_procedure_bodies(Checker *c) {
global_procedure_body_in_worker_queue = true;
- for (ProcInfo *pi = nullptr; mpmc_dequeue(&c->procs_to_check_queue, &pi); /**/) {
- thread_pool_add_task(check_proc_info_worker_proc, pi);
+ isize prev_procs_to_check_count = c->procs_to_check.count;
+ for_array(i, c->procs_to_check) {
+ thread_pool_add_task(check_proc_info_worker_proc, c->procs_to_check[i]);
}
-
- isize global_remaining = c->procs_to_check_queue.count.load(std::memory_order_relaxed);
- GB_ASSERT(global_remaining == 0);
+ GB_ASSERT(prev_procs_to_check_count == c->procs_to_check.count);
+ array_clear(&c->procs_to_check);
thread_pool_wait();