mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 04:38:16 +00:00
Correct mpsc_dequeue
This commit is contained in:
@@ -1687,7 +1687,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
|||||||
case BuiltinProc___entry_point:
|
case BuiltinProc___entry_point:
|
||||||
operand->mode = Addressing_NoValue;
|
operand->mode = Addressing_NoValue;
|
||||||
operand->type = nullptr;
|
operand->type = nullptr;
|
||||||
mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call);
|
mpsc_enqueue(&c->info->intrinsics_entry_point_usage, call);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuiltinProc_DIRECTIVE:
|
case BuiltinProc_DIRECTIVE:
|
||||||
|
|||||||
+1
-1
@@ -1124,7 +1124,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|||||||
|
|
||||||
if (ac.require_declaration) {
|
if (ac.require_declaration) {
|
||||||
e->flags |= EntityFlag_Require;
|
e->flags |= EntityFlag_Require;
|
||||||
mpmc_enqueue(&ctx->info->required_global_variable_queue, e);
|
mpsc_enqueue(&ctx->info->required_global_variable_queue, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+16
-14
@@ -1160,11 +1160,11 @@ gb_internal void init_checker_info(CheckerInfo *i) {
|
|||||||
|
|
||||||
TIME_SECTION("checker info: mpmc queues");
|
TIME_SECTION("checker info: mpmc queues");
|
||||||
|
|
||||||
mpmc_init(&i->entity_queue, a, 1<<20);
|
mpsc_init(&i->entity_queue, a); // 1<<20);
|
||||||
mpsc_init(&i->definition_queue, a); //, 1<<20);
|
mpsc_init(&i->definition_queue, a); //); // 1<<20);
|
||||||
mpmc_init(&i->required_global_variable_queue, a, 1<<10);
|
mpsc_init(&i->required_global_variable_queue, a); // 1<<10);
|
||||||
mpmc_init(&i->required_foreign_imports_through_force_queue, a, 1<<10);
|
mpsc_init(&i->required_foreign_imports_through_force_queue, a); // 1<<10);
|
||||||
mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used
|
mpsc_init(&i->intrinsics_entry_point_usage, a); // 1<<10); // just waste some memory here, even if it probably never used
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void destroy_checker_info(CheckerInfo *i) {
|
gb_internal void destroy_checker_info(CheckerInfo *i) {
|
||||||
@@ -1181,10 +1181,10 @@ gb_internal void destroy_checker_info(CheckerInfo *i) {
|
|||||||
array_free(&i->variable_init_order);
|
array_free(&i->variable_init_order);
|
||||||
array_free(&i->required_foreign_imports_through_force);
|
array_free(&i->required_foreign_imports_through_force);
|
||||||
|
|
||||||
mpmc_destroy(&i->entity_queue);
|
mpsc_destroy(&i->entity_queue);
|
||||||
mpsc_destroy(&i->definition_queue);
|
mpsc_destroy(&i->definition_queue);
|
||||||
mpmc_destroy(&i->required_global_variable_queue);
|
mpsc_destroy(&i->required_global_variable_queue);
|
||||||
mpmc_destroy(&i->required_foreign_imports_through_force_queue);
|
mpsc_destroy(&i->required_foreign_imports_through_force_queue);
|
||||||
|
|
||||||
map_destroy(&i->objc_msgSend_types);
|
map_destroy(&i->objc_msgSend_types);
|
||||||
string_map_destroy(&i->load_file_cache);
|
string_map_destroy(&i->load_file_cache);
|
||||||
@@ -1711,7 +1711,8 @@ gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, En
|
|||||||
|
|
||||||
is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy;
|
is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy;
|
||||||
if (!is_lazy) {
|
if (!is_lazy) {
|
||||||
queue_count = mpmc_enqueue(&info->entity_queue, e);
|
GB_ASSERT(e != nullptr);
|
||||||
|
queue_count = mpsc_enqueue(&info->entity_queue, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->token.pos.file_id != 0) {
|
if (e->token.pos.file_id != 0) {
|
||||||
@@ -2375,12 +2376,12 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entity *e; mpmc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) {
|
for (Entity *e; mpsc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) {
|
||||||
array_add(&c->info.required_foreign_imports_through_force, e);
|
array_add(&c->info.required_foreign_imports_through_force, e);
|
||||||
add_dependency_to_set(c, e);
|
add_dependency_to_set(c, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entity *e; mpmc_dequeue(&c->info.required_global_variable_queue, &e); /**/) {
|
for (Entity *e; mpsc_dequeue(&c->info.required_global_variable_queue, &e); /**/) {
|
||||||
e->flags |= EntityFlag_Used;
|
e->flags |= EntityFlag_Used;
|
||||||
add_dependency_to_set(c, e);
|
add_dependency_to_set(c, e);
|
||||||
}
|
}
|
||||||
@@ -4058,6 +4059,7 @@ gb_internal void check_all_global_entities(Checker *c) {
|
|||||||
// Don't bother trying
|
// Don't bother trying
|
||||||
for_array(i, c->info.entities) {
|
for_array(i, c->info.entities) {
|
||||||
Entity *e = c->info.entities[i];
|
Entity *e = c->info.entities[i];
|
||||||
|
GB_ASSERT(e != nullptr);
|
||||||
if (e->flags & EntityFlag_Lazy) {
|
if (e->flags & EntityFlag_Lazy) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4461,7 +4463,7 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
|||||||
AttributeContext ac = {};
|
AttributeContext ac = {};
|
||||||
check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
|
check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
|
||||||
if (ac.require_declaration) {
|
if (ac.require_declaration) {
|
||||||
mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e);
|
mpsc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e);
|
||||||
add_entity_use(ctx, nullptr, e);
|
add_entity_use(ctx, nullptr, e);
|
||||||
}
|
}
|
||||||
if (ac.foreign_import_priority_index != 0) {
|
if (ac.foreign_import_priority_index != 0) {
|
||||||
@@ -5575,7 +5577,7 @@ gb_internal void check_unique_package_names(Checker *c) {
|
|||||||
gb_internal void check_add_entities_from_queues(Checker *c) {
|
gb_internal void check_add_entities_from_queues(Checker *c) {
|
||||||
isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed);
|
isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed);
|
||||||
array_reserve(&c->info.entities, cap);
|
array_reserve(&c->info.entities, cap);
|
||||||
for (Entity *e; mpmc_dequeue(&c->info.entity_queue, &e); /**/) {
|
for (Entity *e; mpsc_dequeue(&c->info.entity_queue, &e); /**/) {
|
||||||
array_add(&c->info.entities, e);
|
array_add(&c->info.entities, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5843,7 +5845,7 @@ gb_internal void check_parsed_files(Checker *c) {
|
|||||||
if (c->info.intrinsics_entry_point_usage.count > 0) {
|
if (c->info.intrinsics_entry_point_usage.count > 0) {
|
||||||
TIME_SECTION("check intrinsics.__entry_point usage");
|
TIME_SECTION("check intrinsics.__entry_point usage");
|
||||||
Ast *node = nullptr;
|
Ast *node = nullptr;
|
||||||
while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) {
|
while (mpsc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) {
|
||||||
if (c->info.entry_point == nullptr && node != nullptr) {
|
if (c->info.entry_point == nullptr && node != nullptr) {
|
||||||
if (node->file()->pkg->kind != Package_Runtime) {
|
if (node->file()->pkg->kind != Package_Runtime) {
|
||||||
warning(node, "usage of intrinsics.__entry_point will be a no-op");
|
warning(node, "usage of intrinsics.__entry_point will be a no-op");
|
||||||
|
|||||||
+4
-4
@@ -380,11 +380,11 @@ struct CheckerInfo {
|
|||||||
// NOTE(bill): These are actually MPSC queues
|
// NOTE(bill): These are actually MPSC queues
|
||||||
// TODO(bill): Convert them to be MPSC queues
|
// TODO(bill): Convert them to be MPSC queues
|
||||||
MPSCQueue<Entity *> definition_queue;
|
MPSCQueue<Entity *> definition_queue;
|
||||||
MPMCQueue<Entity *> entity_queue;
|
MPSCQueue<Entity *> entity_queue;
|
||||||
MPMCQueue<Entity *> required_global_variable_queue;
|
MPSCQueue<Entity *> required_global_variable_queue;
|
||||||
MPMCQueue<Entity *> required_foreign_imports_through_force_queue;
|
MPSCQueue<Entity *> required_foreign_imports_through_force_queue;
|
||||||
|
|
||||||
MPMCQueue<Ast *> intrinsics_entry_point_usage;
|
MPSCQueue<Ast *> intrinsics_entry_point_usage;
|
||||||
|
|
||||||
BlockingMutex objc_types_mutex;
|
BlockingMutex objc_types_mutex;
|
||||||
PtrMap<Ast *, ObjcMsgData> objc_msgSend_types;
|
PtrMap<Ast *, ObjcMsgData> objc_msgSend_types;
|
||||||
|
|||||||
+11
-1
@@ -43,11 +43,21 @@ gb_internal void debugf(char const *fmt, ...);
|
|||||||
#error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows
|
#error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TypeIsPointer {
|
||||||
|
enum {value = false};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TypeIsPointer<T *> {
|
||||||
|
enum {value = true};
|
||||||
|
};
|
||||||
|
|
||||||
#include "unicode.cpp"
|
#include "unicode.cpp"
|
||||||
#include "array.cpp"
|
#include "array.cpp"
|
||||||
#include "threading.cpp"
|
#include "threading.cpp"
|
||||||
#include "queue.cpp"
|
|
||||||
#include "common_memory.cpp"
|
#include "common_memory.cpp"
|
||||||
|
#include "queue.cpp"
|
||||||
#include "string.cpp"
|
#include "string.cpp"
|
||||||
#include "range_cache.cpp"
|
#include "range_cache.cpp"
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
template <typename T>
|
|
||||||
struct TypeIsPointer {
|
|
||||||
enum {value = false};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct TypeIsPointer<T *> {
|
|
||||||
enum {value = true};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct PtrSet {
|
struct PtrSet {
|
||||||
static_assert(TypeIsPointer<T>::value, "PtrSet::T must be a pointer");
|
static_assert(TypeIsPointer<T>::value, "PtrSet::T must be a pointer");
|
||||||
|
|||||||
+4
-1
@@ -69,10 +69,13 @@ gb_internal bool mpsc_dequeue(MPSCQueue<T> *q, T *value_) {
|
|||||||
if (next) {
|
if (next) {
|
||||||
q->tail.store(next, std::memory_order_relaxed);
|
q->tail.store(next, std::memory_order_relaxed);
|
||||||
// `tail` is now "dead" and needs to be "freed"
|
// `tail` is now "dead" and needs to be "freed"
|
||||||
if (*value_) *value_ = next->value;
|
tail->value = next->value;
|
||||||
|
T value = tail->value;
|
||||||
|
if (value_) *value_ = value;
|
||||||
q->count.fetch_sub(1, std::memory_order_acq_rel);
|
q->count.fetch_sub(1, std::memory_order_acq_rel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
GB_ASSERT(q->count.load(std::memory_order_acquire) == 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user