Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support protected mode of E2K #61

Closed
ivmai opened this issue Oct 30, 2023 · 1 comment
Closed

Support protected mode of E2K #61

ivmai opened this issue Oct 30, 2023 · 1 comment

Comments

@ivmai
Copy link
Owner

ivmai commented Oct 30, 2023

Host: Linux/elbrus-v5 (or later)
Compiler option (to build code in protected mode): -m128
As of current gcc/lcc, there are 2 issues:

  • sizeof uintptr_t != sizeof char*
  • conversion from pointer to __int128 is not symmetric (a numeric value cannot be converted back to pointer)

The 2nd item is rather hard to workaround (i.e. replace AO_uintptr_t with char* everywhere).

Compiler version: lcc:1.26.20:Jun--6-2023:e2k-v5-linux | gcc (GCC) 9.3.0 compatible

@ivmai
Copy link
Owner Author

ivmai commented Oct 31, 2023

The issues with the above patch is that cast between AO_uintptr_t* and char** breaks strict-aliasing rules ("warning: dereferencing type-punned pointer will break strict-aliasing rules").

ivmai added a commit that referenced this issue Nov 4, 2023
Issue #61 (libatomic_ops).

The "next" argument of AO_REAL_NEXT_PTR() is of AO_uintptr_t type but
actually is a pointer.  Some architectures (e.g. E2K in the protected
mode) does not allow conversion from a numeric type to a pointer, this
change allows the "next" argument to be passed correctly even on such
architectures.

* src/atomic_ops_stack.c (AO_stack_next_ptr_d): Implement.
* src/atomic_ops_stack.c (AO_stack_next_ptr): Add comment that the
function is deprecated.
* src/atomic_ops_stack.c (AO_stack_next_ptr): Likewise.
* src/atomic_ops_stack.c [!AO_USE_ALMOST_LOCK_FREE]
(AO_stack_push_release): Do not cast next to AO_uintptr_t.
* src/atomic_ops_stack.c [!AO_USE_ALMOST_LOCK_FREE]
(AO_stack_pop_acquire): Replace return NULL to break.
* src/atomic_ops_stack.h [!AO_REAL_PTR_AS_MACRO] (AO_REAL_NEXT_PTR):
Use AO_stack_next_ptr_d instead of AO_stack_next_ptr.
* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO
&& !AO_USE_ALMOST_LOCK_FREE] (AO_REAL_NEXT_PTR): Replace (x)
to *(&(x)).
* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO] (AO_REAL_HEAD_PTR):
Replace (x).AO_pa to (&(x))->AO_pa.
* src/atomic_ops_stack.h (AO_stack_head_ptr): Add comment that the
primitive (and similar ones) should not be used directly.
* src/atomic_ops_stack.h (AO_stack_next_ptr_d): Declare function.
* tests/test_stack.c [CPPCHECK] (main): Call AO_stack_next_ptr().
ivmai added a commit that referenced this issue Nov 4, 2023
(refactoring)

Issue #61 (libatomic_ops).

* src/atomic_ops_malloc.c (initial_heap_ptr): Change type from
AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_stack.h (AO__stack_aux.AO_stack_bl,
AO__stack_ptr_aux.AO_ptr): Likewise.
* src/atomic_ops_malloc.c (AO_uintptr_compare_and_swap,
AO_uintptr_compare_and_swap_acquire, AO_uintptr_load): Change name
prefix to AO_cptr_.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_cptr_compare_and_swap_acquire, AO_cptr_compare_and_swap_release,
AO_cptr_load, AO_cptr_load_acquire, AO_cptr_store_release): Likewise.
* src/atomic_ops_malloc.c (get_chunk): Change type of my_chunk_ptr,
initial_ptr local variables from AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_malloc.c (get_chunk): Add casts to AO_internal_ptr_t
and AO_uintptr_t where appropriate.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_stack_push_explicit_aux_release,
AO_stack_pop_explicit_aux_acquire, AO_stack_push_release,
AO_stack_pop_acquire): Likewise.
* src/atomic_ops_stack.c [AO_THREAD_SANITIZER] (store_before_cas):
Change type of arguments from AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_stack_push_explicit_aux_release): Change type of x_bits, next,
entry1, entry2 local variables from AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE
&& AO_THREAD_SANITIZER] (load_next): Change return and argument type
from AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_stack_pop_explicit_aux_acquire): Change type of first, next, zero
local variables from AO_uintptr_t to AO_internal_ptr_t.
* src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE]
(AO_stack_pop_explicit_aux_acquire): Change type of first_ptr local
variable from AO_uintptr_t* to AO_internal_ptr_t* type.
* src/atomic_ops_stack.h (AO_internal_ptr_t): New type (defined to
AO_uintptr_t).
* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO
&& AO_USE_ALMOST_LOCK_FREE] (AO_REAL_HEAD_PTR): Change type
of argument of AO_REAL_NEXT_PTR to AO_uintptr_t reference.
ivmai added a commit that referenced this issue Nov 4, 2023
Issue #61 (libatomic_ops).

* src/atomic_ops.h [AO_FAT_POINTER && __e2k__] (AO_uintptr_t): Define
to unsigned __int128; add comment; do not include inttypes.h.
* src/atomic_ops.h (AO_uintptr_t_size_static_assert): Define struct (to
serve as a compile-time assertion).
ivmai added a commit that referenced this issue Nov 4, 2023
Issue #61 (libatomic_ops).

Unlike CHERI ISA extension, the E2K protected mode does not allow
conversion from a numeric pointer-sized value to a pointer.

* src/atomic_ops_malloc.c [!AO_FAT_POINTER && AO_STACK_USE_CPTR]
(AO_cptr_compare_and_swap, AO_cptr_compare_and_swap_acquire,
AO_cptr_load): Redirect to GCC built-in atomic primitives.
* src/atomic_ops_stack.c [!AO_FAT_POINTER && AO_STACK_USE_CPTR]
(AO_cptr_compare_and_swap_acquire, AO_cptr_compare_and_swap_release,
AO_cptr_load, AO_cptr_load_acquire, AO_cptr_store_release): Likewise.
* src/atomic_ops_malloc.c [AO_STACK_USE_CPTR] (get_chunk): Rewrite the
expression of masking lowest bits to avoid conversion from a numeric
value to a pointer.
* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO && AO_STACK_USE_CPTR
&& AO_USE_ALMOST_LOCK_FREE] (AO_REAL_NEXT_PTR): Likewise.
* src/atomic_ops_stack.h [!AO_USE_ALMOST_LOCK_FREE
&& AO_STACK_USE_CPTR] (AO_USE_ALMOST_LOCK_FREE): Define macro.
* src/atomic_ops_stack.h [__e2k__ && AO_FAT_POINTER
&& !AO_STACK_USE_CPTR] (AO_STACK_USE_CPTR): Likewise.
* src/atomic_ops_stack.h [__e2k__ && AO_FAT_POINTER
|| AO_STACK_USE_CPTR] (AO_internal_ptr_t): Define to char* instead of
AO_uintptr_t.
@ivmai ivmai closed this as completed Nov 4, 2023
ivmai added a commit that referenced this issue May 21, 2024
(fix of commit 707a7b2)

Issue #61 (libatomic_ops).

* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO
&& AO_USE_ALMOST_LOCK_FREE && AO_STACK_USE_CPTR] (AO_REAL_NEXT_PTR):
Call AO_real_next_ptr_i() instead of direct evaluation of the
expression.
* src/atomic_ops_stack.h [AO_REAL_PTR_AS_MACRO
&& AO_USE_ALMOST_LOCK_FREE && AO_STACK_USE_CPTR] (AO_real_next_ptr_i):
New inline function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant