mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-14 23:33:15 +00:00
intrinsics.atomic_type_is_lock_free
This commit is contained in:
@@ -70,7 +70,7 @@ atomic_signal_fence :: #force_inline proc(order: memory_order) {
|
||||
|
||||
// 7.17.5 Lock-free property
|
||||
atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool {
|
||||
return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T))
|
||||
return intrinsics.atomic_type_is_lock_free(T)
|
||||
}
|
||||
|
||||
// 7.17.6 Atomic integer types
|
||||
|
||||
@@ -71,6 +71,8 @@ Atomic_Memory_Order :: enum {
|
||||
Seq_Cst = 5,
|
||||
}
|
||||
|
||||
atomic_type_is_lock_free :: proc($T: typeid) -> bool ---
|
||||
|
||||
atomic_thread_fence :: proc(order: Atomic_Memory_Order) ---
|
||||
atomic_signal_fence :: proc(order: Atomic_Memory_Order) ---
|
||||
|
||||
|
||||
@@ -449,6 +449,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
case BuiltinProc_objc_find_class:
|
||||
case BuiltinProc_objc_register_selector:
|
||||
case BuiltinProc_objc_register_class:
|
||||
case BuiltinProc_atomic_type_is_lock_free:
|
||||
// NOTE(bill): The first arg may be a Type, this will be checked case by case
|
||||
break;
|
||||
|
||||
@@ -3232,6 +3233,35 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
break;
|
||||
|
||||
|
||||
case BuiltinProc_atomic_type_is_lock_free:
|
||||
{
|
||||
Ast *expr = ce->args[0];
|
||||
Operand o = {};
|
||||
check_expr_or_type(c, &o, expr);
|
||||
|
||||
if (o.mode == Addressing_Invalid || o.mode == Addressing_Builtin) {
|
||||
return false;
|
||||
}
|
||||
if (o.type == nullptr || o.type == t_invalid || is_type_asm_proc(o.type)) {
|
||||
error(o.expr, "Invalid argument to '%.*s'", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
if (is_type_polymorphic(o.type)) {
|
||||
error(o.expr, "'%.*s' of polymorphic type cannot be determined", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
if (is_type_untyped(o.type)) {
|
||||
error(o.expr, "'%.*s' of untyped type is not allowed", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
Type *t = o.type;
|
||||
bool is_lock_free = is_type_lock_free(t);
|
||||
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->type = t_untyped_bool;
|
||||
operand->value = exact_value_bool(is_lock_free);
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_atomic_thread_fence:
|
||||
case BuiltinProc_atomic_signal_fence:
|
||||
|
||||
@@ -86,6 +86,7 @@ enum BuiltinProcId {
|
||||
BuiltinProc_prefetch_write_instruction,
|
||||
BuiltinProc_prefetch_write_data,
|
||||
|
||||
BuiltinProc_atomic_type_is_lock_free,
|
||||
BuiltinProc_atomic_thread_fence,
|
||||
BuiltinProc_atomic_signal_fence,
|
||||
BuiltinProc_atomic_store,
|
||||
@@ -305,6 +306,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("atomic_type_is_lock_free"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
@@ -45,9 +45,9 @@ enum EntityFlag : u64 {
|
||||
EntityFlag_NoAlias = 1ull<<9,
|
||||
EntityFlag_TypeField = 1ull<<10,
|
||||
EntityFlag_Value = 1ull<<11,
|
||||
EntityFlag_Sret = 1ull<<12,
|
||||
EntityFlag_ByVal = 1ull<<13,
|
||||
EntityFlag_BitFieldValue = 1ull<<14,
|
||||
|
||||
|
||||
|
||||
EntityFlag_PolyConst = 1ull<<15,
|
||||
EntityFlag_NotExported = 1ull<<16,
|
||||
EntityFlag_ConstInput = 1ull<<17,
|
||||
|
||||
@@ -447,7 +447,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
|
||||
Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
|
||||
Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
|
||||
e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
|
||||
e->flags |= EntityFlag_NoAlias;
|
||||
|
||||
return_ptr_value.value = LLVMGetParam(p->value, 0);
|
||||
LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);
|
||||
|
||||
@@ -2218,6 +2218,17 @@ bool elem_type_can_be_constant(Type *t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_type_lock_free(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t == t_invalid) {
|
||||
return false;
|
||||
}
|
||||
i64 sz = type_size_of(t);
|
||||
// TODO(bill): Figure this out correctly
|
||||
return sz <= build_context.max_align;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_type_comparable(Type *t) {
|
||||
t = base_type(t);
|
||||
|
||||
Reference in New Issue
Block a user