aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-08-05 15:07:06 +0100
committergingerBill <gingerBill@users.noreply.github.com>2025-08-05 15:07:06 +0100
commiteae43f122556f7219dc05a8fb7674a122ad977ba (patch)
treefc2cb57e456d500c253d778e0a82c04564a4ec35
parentf8d24923fdd701c0a08b8ffb7200cebdc9820b76 (diff)
parentaccdd7c2af4c2b9f4a0b923a47df4c2eb6074b0a (diff)
Merge branch 'master' into bill/utf16-strings
-rw-r--r--core/os/os2/file_windows.odin6
-rw-r--r--core/prof/spall/spall.odin4
-rw-r--r--core/thread/thread_unix.odin7
-rw-r--r--src/check_builtin.cpp2
-rw-r--r--src/check_expr.cpp2
-rw-r--r--src/checker.cpp6
-rw-r--r--src/checker_builtin_procs.hpp2
-rw-r--r--src/types.cpp78
8 files changed, 92 insertions, 15 deletions
diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin
index 304cf99ac..25e9cb4b0 100644
--- a/core/os/os2/file_windows.odin
+++ b/core/os/os2/file_windows.odin
@@ -249,9 +249,9 @@ _destroy :: proc(f: ^File_Impl) -> Error {
a := f.allocator
err0 := free(rawptr(f.wname), a)
err1 := delete(f.name, a)
- err2 := free(f, a)
- err3 := delete(f.r_buf, a)
- err4 := delete(f.w_buf, a)
+ err2 := delete(f.r_buf, a)
+ err3 := delete(f.w_buf, a)
+ err4 := free(f, a)
err0 or_return
err1 or_return
err2 or_return
diff --git a/core/prof/spall/spall.odin b/core/prof/spall/spall.odin
index 16b809359..dc53dc3dc 100644
--- a/core/prof/spall/spall.odin
+++ b/core/prof/spall/spall.odin
@@ -103,6 +103,7 @@ context_create_with_sleep :: proc(filename: string, sleep := 2 * time.Second) ->
context_create :: proc{context_create_with_scale, context_create_with_sleep}
+@(no_instrumentation)
context_destroy :: proc(ctx: ^Context) {
if ctx == nil {
return
@@ -146,6 +147,7 @@ buffer_flush :: proc "contextless" (ctx: ^Context, buffer: ^Buffer) #no_bounds_c
buffer.first_ts = end
}
+@(no_instrumentation)
buffer_destroy :: proc(ctx: ^Context, buffer: ^Buffer) {
buffer_flush(ctx, buffer)
@@ -155,12 +157,14 @@ buffer_destroy :: proc(ctx: ^Context, buffer: ^Buffer) {
@(deferred_in=_scoped_buffer_end)
+@(no_instrumentation)
SCOPED_EVENT :: proc(ctx: ^Context, buffer: ^Buffer, name: string, args: string = "", location := #caller_location) -> bool {
_buffer_begin(ctx, buffer, name, args, location)
return true
}
@(private)
+@(no_instrumentation)
_scoped_buffer_end :: proc(ctx: ^Context, buffer: ^Buffer, _, _: string, _ := #caller_location) {
_buffer_end(ctx, buffer)
}
diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin
index 1431442a9..1db32657e 100644
--- a/core/thread/thread_unix.odin
+++ b/core/thread/thread_unix.odin
@@ -81,8 +81,13 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
}
defer posix.pthread_attr_destroy(&attrs)
- // NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
+ stacksize: posix.rlimit
+ if res := posix.getrlimit(.STACK, &stacksize); res == .OK && stacksize.rlim_cur > 0 {
+ _ = posix.pthread_attr_setstacksize(&attrs, uint(stacksize.rlim_cur))
+ }
+
res: posix.Errno
+ // NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
res = posix.pthread_attr_setdetachstate(&attrs, .CREATE_JOINABLE)
assert(res == nil)
when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index da5eb8977..57413f519 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -33,6 +33,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
is_type_sliceable,
is_type_comparable,
is_type_simple_compare,
+ is_type_nearly_simple_compare,
is_type_dereferenceable,
is_type_valid_for_keys,
is_type_valid_for_matrix_elems,
@@ -6159,6 +6160,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
case BuiltinProc_type_is_sliceable:
case BuiltinProc_type_is_comparable:
case BuiltinProc_type_is_simple_compare:
+ case BuiltinProc_type_is_nearly_simple_compare:
case BuiltinProc_type_is_dereferenceable:
case BuiltinProc_type_is_valid_map_key:
case BuiltinProc_type_is_valid_matrix_elements:
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 34149f92b..faa338f36 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -6621,7 +6621,7 @@ gb_internal bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Sco
Entity *e = entry.value;
switch (e->kind) {
case Entity_TypeName: {
- if (print_count == 0) error_line("\n\tWith the following definitions:\n");
+ // if (print_count == 0) error_line("\n\tWith the following definitions:\n");
gbString str = type_to_string(e->type);
error_line("\t\t%.*s :: %s;\n", LIT(e->token.string), str);
diff --git a/src/checker.cpp b/src/checker.cpp
index 20da5b19b..e9fa792f3 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -6804,7 +6804,11 @@ gb_internal void check_parsed_files(Checker *c) {
for_array(i, c->info.definitions) {
Entity *e = c->info.definitions[i];
if (e->kind == Entity_TypeName && e->type != nullptr && is_type_typed(e->type)) {
- (void)type_align_of(e->type);
+ if (e->TypeName.is_type_alias) {
+ // Ignore for the time being
+ } else {
+ (void)type_align_of(e->type);
+ }
} else if (e->kind == Entity_Procedure) {
DeclInfo *decl = e->decl_info;
ast_node(pl, ProcLit, decl->proc_lit);
diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp
index bff887d9e..b8b105fd2 100644
--- a/src/checker_builtin_procs.hpp
+++ b/src/checker_builtin_procs.hpp
@@ -265,6 +265,7 @@ BuiltinProc__type_simple_boolean_begin,
BuiltinProc_type_is_sliceable,
BuiltinProc_type_is_comparable,
BuiltinProc_type_is_simple_compare, // easily compared using memcmp
+ BuiltinProc_type_is_nearly_simple_compare, // easily compared using memcmp (including floats)
BuiltinProc_type_is_dereferenceable,
BuiltinProc_type_is_valid_map_key,
BuiltinProc_type_is_valid_matrix_elements,
@@ -623,6 +624,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("type_is_sliceable"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_comparable"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_simple_compare"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+ {STR_LIT("type_is_nearly_simple_compare"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_dereferenceable"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_valid_map_key"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_valid_matrix_elements"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
diff --git a/src/types.cpp b/src/types.cpp
index ad576c8af..51d170f2b 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -157,10 +157,11 @@ struct TypeStruct {
bool is_polymorphic;
bool are_offsets_set : 1;
- bool are_offsets_being_processed : 1;
bool is_packed : 1;
bool is_raw_union : 1;
bool is_poly_specialized : 1;
+
+ std::atomic<bool> are_offsets_being_processed;
};
struct TypeUnion {
@@ -259,7 +260,7 @@ struct TypeProc {
Slice<Entity *> variables; /* Entity_Variable */ \
i64 * offsets; \
BlockingMutex mutex; /* for settings offsets */ \
- bool are_offsets_being_processed; \
+ std::atomic<bool> are_offsets_being_processed; \
bool are_offsets_set; \
bool is_packed; \
}) \
@@ -2633,6 +2634,62 @@ gb_internal bool is_type_simple_compare(Type *t) {
return false;
}
+// NOTE(bill): type can be easily compared using memcmp or contains a float
+gb_internal bool is_type_nearly_simple_compare(Type *t) {
+ t = core_type(t);
+ switch (t->kind) {
+ case Type_Array:
+ return is_type_nearly_simple_compare(t->Array.elem);
+
+ case Type_EnumeratedArray:
+ return is_type_nearly_simple_compare(t->EnumeratedArray.elem);
+
+ case Type_Basic:
+ if (t->Basic.flags & (BasicFlag_SimpleCompare|BasicFlag_Numeric)) {
+ return true;
+ }
+ if (t->Basic.kind == Basic_typeid) {
+ return true;
+ }
+ return false;
+
+ case Type_Pointer:
+ case Type_MultiPointer:
+ case Type_SoaPointer:
+ case Type_Proc:
+ case Type_BitSet:
+ return true;
+
+ case Type_Matrix:
+ return is_type_nearly_simple_compare(t->Matrix.elem);
+
+ case Type_Struct:
+ for_array(i, t->Struct.fields) {
+ Entity *f = t->Struct.fields[i];
+ if (!is_type_nearly_simple_compare(f->type)) {
+ return false;
+ }
+ }
+ return true;
+
+ case Type_Union:
+ for_array(i, t->Union.variants) {
+ Type *v = t->Union.variants[i];
+ if (!is_type_nearly_simple_compare(v)) {
+ return false;
+ }
+ }
+ // make it dumb on purpose
+ return t->Union.variants.count == 1;
+
+ case Type_SimdVector:
+ return is_type_nearly_simple_compare(t->SimdVector.elem);
+
+ }
+
+ return false;
+}
+
gb_internal bool is_type_load_safe(Type *type) {
GB_ASSERT(type != nullptr);
type = core_type(core_array_type(type));
@@ -4121,18 +4178,18 @@ gb_internal bool type_set_offsets(Type *t) {
if (t->kind == Type_Struct) {
MUTEX_GUARD(&t->Struct.offset_mutex);
if (!t->Struct.are_offsets_set) {
- t->Struct.are_offsets_being_processed = true;
+ t->Struct.are_offsets_being_processed.store(true);
t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union, t->Struct.custom_min_field_align, t->Struct.custom_max_field_align);
- t->Struct.are_offsets_being_processed = false;
+ t->Struct.are_offsets_being_processed.store(false);
t->Struct.are_offsets_set = true;
return true;
}
} else if (is_type_tuple(t)) {
MUTEX_GUARD(&t->Tuple.mutex);
if (!t->Tuple.are_offsets_set) {
- t->Tuple.are_offsets_being_processed = true;
+ t->Tuple.are_offsets_being_processed.store(true);
t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false, 1, 0);
- t->Tuple.are_offsets_being_processed = false;
+ t->Tuple.are_offsets_being_processed.store(false);
t->Tuple.are_offsets_set = true;
return true;
}
@@ -4317,9 +4374,12 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
if (path->failure) {
return FAILURE_SIZE;
}
- if (t->Struct.are_offsets_being_processed && t->Struct.offsets == nullptr) {
- type_path_print_illegal_cycle(path, path->path.count-1);
- return FAILURE_SIZE;
+ {
+ MUTEX_GUARD(&t->Struct.offset_mutex);
+ if (t->Struct.are_offsets_being_processed.load() && t->Struct.offsets == nullptr) {
+ type_path_print_illegal_cycle(path, path->path.count-1);
+ return FAILURE_SIZE;
+ }
}
type_set_offsets(t);
GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr);