Skip to content

Commit

Permalink
increase max atomic size to 16 on 64-bit platforms (JuliaLang#42268)
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash authored Mar 9, 2024
1 parent e9c84c8 commit 39f141d
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ endif
JCFLAGS += -Wold-style-definition -Wstrict-prototypes -Wc++-compat

ifeq ($(USECLANG),1)
FLAGS += -Wno-return-type-c-linkage
FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment
endif

FLAGS += -DJL_BUILD_ARCH='"$(ARCH)"'
Expand Down
5 changes: 3 additions & 2 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdalign.h>
#include "julia.h"
#include "julia_internal.h"
#include "julia_assert.h"
Expand Down Expand Up @@ -1012,7 +1013,7 @@ JL_DLLEXPORT int jl_is_foreign_type(jl_datatype_t *dt)

#if MAX_POINTERATOMIC_SIZE >= 16
typedef struct _jl_uint128_t {
uint64_t a;
alignas(16) uint64_t a;
uint64_t b;
} jl_uint128_t;
#endif
Expand Down Expand Up @@ -1356,7 +1357,7 @@ JL_DLLEXPORT int jl_atomic_storeonce_bits(jl_datatype_t *dt, char *dst, const jl
#endif
#if MAX_POINTERATOMIC_SIZE >= 16
else if (nb <= 16) {
jl_uint128_t y128 = 0;
jl_uint128_t y128 = {0};
jl_uint128_t z128 = zext_read128(src, nb);
while (1) {
success = jl_atomic_cmpswap((_Atomic(jl_uint128_t)*)dst, &y128, z128);
Expand Down
11 changes: 8 additions & 3 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@
#endif

// Define the largest size (bytes) of a properly aligned object that the
// processor family and compiler typically supports without a lock
// (assumed to be at least a pointer size). Since C is bad at handling 16-byte
// types, we currently use 8 here as the default.
// processor family (MAX_ATOMIC_SIZE) and compiler (MAX_POINTERATOMIC_SIZE)
// typically supports without a lock (assumed to be at least a pointer size)
// with MAX_POINTERATOMIC_SIZE >= MAX_ATOMIC_SIZE.
#ifdef _P64
#define MAX_ATOMIC_SIZE 16
#define MAX_POINTERATOMIC_SIZE 16
#else
#define MAX_ATOMIC_SIZE 8
#define MAX_POINTERATOMIC_SIZE 8
#endif

#ifdef _P64
#define NWORDS(sz) (((sz)+7)>>3)
Expand Down
2 changes: 1 addition & 1 deletion test/intrinsics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co
@test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(10), S(3), :sequentially_consistent, :sequentially_consistent)
end
@test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[]
if sizeof(r) > 8
if sizeof(r) > 2*sizeof(Int)
@test_throws ErrorException("atomic_pointerref: invalid pointer for atomic operation") unsafe_load(p, :sequentially_consistent)
@test_throws ErrorException("atomic_pointerset: invalid pointer for atomic operation") unsafe_store!(p, T(1), :sequentially_consistent)
@test_throws ErrorException("atomic_pointerswap: invalid pointer for atomic operation") unsafe_swap!(p, T(100), :sequentially_consistent)
Expand Down

0 comments on commit 39f141d

Please sign in to comment.