Skip to content

Commit 1439e17

Browse files
committed
fixup! update atomics.h to be more fully C11/C++11 compliant
1 parent 233cc24 commit 1439e17

36 files changed

+231
-204
lines changed

src/Makefile

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ endif
9595

9696
# headers are used for dependency tracking, while public headers will be part of the dist
9797
UV_HEADERS :=
98-
HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h locks.h atomics.h julia_internal.h options.h timing.h) $(addprefix $(BUILDDIR)/, $(DTRACE_HEADERS))
99-
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h locks.h atomics.h julia_gcext.h)
98+
HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h julia_internal.h options.h timing.h) $(addprefix $(BUILDDIR)/, $(DTRACE_HEADERS))
99+
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h julia_gcext.h)
100100
ifeq ($(USE_SYSTEM_LIBUV),0)
101101
UV_HEADERS += uv.h
102102
UV_HEADERS += uv/*.h
@@ -376,15 +376,23 @@ endif
376376

377377
clangsa: $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT)
378378

379-
clang-sa-%: $(SRCDIR)/%.c $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check
380-
@$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $<)
381-
clang-sa-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check
382-
@$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS) $(JCXXFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c++ $<)
379+
clang-sagc-%: $(SRCDIR)/%.c $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) .FORCE | analyzegc-deps-check
380+
@$(call PRINT_ANALYZE, $(build_bindir)/clang -D__clang_gcanalyzer__ --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $<)
381+
clang-sagc-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) .FORCE | analyzegc-deps-check
382+
@$(call PRINT_ANALYZE, $(build_bindir)/clang -D__clang_gcanalyzer__ --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS) $(JCXXFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c++ $<)
383383

384-
# Add C files as a target of `analyzegc`
385-
analyzegc: $(addprefix clang-sa-,$(RUNTIME_SRCS))
384+
clang-sa-%: $(SRCDIR)/%.c .FORCE | analyzegc-deps-check
385+
@$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text $(CLANGSA_FLAGS) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $<)
386+
clang-sa-%: $(SRCDIR)/%.cpp .FORCE | analyzegc-deps-check
387+
@$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS) $(JCXXFLAGS) $(DEBUGFLAGS) --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c++ $<)
388+
389+
390+
# Add C files as a target of `analyzesrc` and `analyzegc`
391+
analyzesrc: $(addprefix clang-sa-,$(SRCS))
392+
analyzegc: analyzesrc $(addprefix clang-sagc-,$(RUNTIME_SRCS))
386393

387394
clean-analyzegc:
388395
rm -f $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT)
389396

390-
.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc clang-sa-*
397+
.FORCE:
398+
.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc analyzesrc .FORCE

src/array.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static inline void arrayassign_safe(int hasptr, jl_value_t *parent, char *dst, c
2626
assert(nb >= jl_datatype_size(jl_typeof(src))); // nb might move some undefined bits, but we should be okay with that
2727
if (hasptr) {
2828
size_t nptr = nb / sizeof(void*);
29-
memmove_refs((void**)dst, (void**)src, nptr);
29+
memmove_refs((void**)dst, (void* const*)src, nptr);
3030
jl_gc_multi_wb(parent, src);
3131
}
3232
else {
@@ -588,7 +588,7 @@ JL_DLLEXPORT jl_value_t *jl_ptrarrayref(jl_array_t *a JL_PROPAGATES_ROOT, size_t
588588
{
589589
assert(i < jl_array_len(a));
590590
assert(a->flags.ptrarray);
591-
jl_value_t *elt = jl_atomic_load_relaxed(((jl_value_t**)a->data) + i);
591+
jl_value_t *elt = jl_atomic_load_relaxed(((_Atomic(jl_value_t*)*)a->data) + i);
592592
if (elt == NULL)
593593
jl_throw(jl_undefref_exception);
594594
return elt;
@@ -617,7 +617,7 @@ JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
617617
JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i)
618618
{
619619
if (a->flags.ptrarray) {
620-
return jl_atomic_load_relaxed(((jl_value_t**)jl_array_data(a)) + i) != NULL;
620+
return jl_atomic_load_relaxed(((_Atomic(jl_value_t*)*)jl_array_data(a)) + i) != NULL;
621621
}
622622
else if (a->flags.hasptr) {
623623
jl_datatype_t *eltype = (jl_datatype_t*)jl_tparam0(jl_typeof(a));
@@ -656,7 +656,7 @@ JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *rhs
656656
arrayassign_safe(hasptr, jl_array_owner(a), &((char*)a->data)[i * a->elsize], rhs, a->elsize);
657657
}
658658
else {
659-
jl_atomic_store_relaxed(((jl_value_t**)a->data) + i, rhs);
659+
jl_atomic_store_relaxed(((_Atomic(jl_value_t*)*)a->data) + i, rhs);
660660
jl_gc_wb(jl_array_owner(a), rhs);
661661
}
662662
}
@@ -666,7 +666,7 @@ JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i)
666666
if (i >= jl_array_len(a))
667667
jl_bounds_error_int((jl_value_t*)a, i + 1);
668668
if (a->flags.ptrarray)
669-
jl_atomic_store_relaxed(((jl_value_t**)a->data) + i, NULL);
669+
jl_atomic_store_relaxed(((_Atomic(jl_value_t*)*)a->data) + i, NULL);
670670
else if (a->flags.hasptr) {
671671
size_t elsize = a->elsize;
672672
jl_assume(elsize >= sizeof(void*) && elsize % sizeof(void*) == 0);
@@ -1243,9 +1243,11 @@ static NOINLINE ssize_t jl_array_ptr_copy_forward(jl_value_t *owner,
12431243
void **src_p, void **dest_p,
12441244
ssize_t n) JL_NOTSAFEPOINT
12451245
{
1246+
_Atomic(void*) *src_pa = (_Atomic(void*)*)src_p;
1247+
_Atomic(void*) *dest_pa = (_Atomic(void*)*)dest_p;
12461248
for (ssize_t i = 0; i < n; i++) {
1247-
void *val = jl_atomic_load_relaxed(src_p + i);
1248-
jl_atomic_store_relaxed(dest_p + i, val);
1249+
void *val = jl_atomic_load_relaxed(src_pa + i);
1250+
jl_atomic_store_relaxed(dest_pa + i, val);
12491251
// `val` is young or old-unmarked
12501252
if (val && !(jl_astaggedvalue(val)->bits.gc & GC_MARKED)) {
12511253
jl_gc_queue_root(owner);
@@ -1259,9 +1261,11 @@ static NOINLINE ssize_t jl_array_ptr_copy_backward(jl_value_t *owner,
12591261
void **src_p, void **dest_p,
12601262
ssize_t n) JL_NOTSAFEPOINT
12611263
{
1264+
_Atomic(void*) *src_pa = (_Atomic(void*)*)src_p;
1265+
_Atomic(void*) *dest_pa = (_Atomic(void*)*)dest_p;
12621266
for (ssize_t i = 0; i < n; i++) {
1263-
void *val = jl_atomic_load_relaxed(src_p + n - i - 1);
1264-
jl_atomic_store_relaxed(dest_p + n - i - 1, val);
1267+
void *val = jl_atomic_load_relaxed(src_pa + n - i - 1);
1268+
jl_atomic_store_relaxed(dest_pa + n - i - 1, val);
12651269
// `val` is young or old-unmarked
12661270
if (val && !(jl_astaggedvalue(val)->bits.gc & GC_MARKED)) {
12671271
jl_gc_queue_root(owner);

src/ast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ typedef struct _jl_ast_context_t {
125125

126126
static jl_ast_context_t jl_ast_main_ctx;
127127

128-
#ifdef __clang_analyzer__
128+
#ifdef __clang_gcanalyzer__
129129
jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT;
130130
#else
131131
#define jl_ast_ctx(fl_ctx) container_of(fl_ctx, jl_ast_context_t, fl)

src/builtins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ static jl_value_t *do_apply( jl_value_t **args, uint32_t nargs, jl_value_t *iter
706706
}
707707
if (arg_heap) {
708708
// optimization: keep only the first root, free the others
709-
#ifndef __clang_analyzer__
709+
#ifndef __clang_gcanalyzer__
710710
((void**)roots)[-2] = (void*)JL_GC_ENCODE_PUSHARGS(1);
711711
#endif
712712
}

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5748,7 +5748,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con
57485748
// some sanity checking and check whether there's a vararg
57495749
size_t nargt = jl_svec_len(argt);
57505750
bool isVa = (nargt > 0 && jl_is_vararg(jl_svecref(argt, nargt - 1)));
5751-
assert(!isVa);
5751+
assert(!isVa); (void)isVa;
57525752

57535753
jl_array_t *closure_types = NULL;
57545754
jl_value_t *sigt = NULL; // dispatch-sig = type signature with Ref{} annotations removed and applied to the env

src/datatype.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
4848
jl_methtable_type);
4949
mt->name = jl_demangle_typename(name);
5050
mt->module = module;
51-
mt->defs = jl_nothing;
52-
mt->leafcache = (jl_array_t*)jl_an_empty_vec_any;
53-
mt->cache = jl_nothing;
51+
jl_atomic_store_relaxed(&mt->defs, jl_nothing);
52+
jl_atomic_store_relaxed(&mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
53+
jl_atomic_store_relaxed(&mt->cache, jl_nothing);
5454
mt->max_args = 0;
5555
mt->kwsorter = NULL;
5656
mt->backedges = NULL;
@@ -69,8 +69,8 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu
6969
tn->name = name;
7070
tn->module = module;
7171
tn->wrapper = NULL;
72-
tn->cache = jl_emptysvec;
73-
tn->linearcache = jl_emptysvec;
72+
jl_atomic_store_relaxed(&tn->cache, jl_emptysvec);
73+
jl_atomic_store_relaxed(&tn->linearcache, jl_emptysvec);
7474
tn->names = NULL;
7575
tn->hash = bitmix(bitmix(module ? module->build_id : 0, name->hash), 0xa1ada1da);
7676
tn->abstract = abstract;

src/dlload.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ JL_DLLEXPORT int jl_dlsym(void *handle, const char *symbol, void ** value, int t
309309
char err[256];
310310
win32_formatmessage(GetLastError(), err, sizeof(err));
311311
#endif
312-
#ifndef __clang_analyzer__
312+
#ifndef __clang_gcanalyzer__
313313
// Hide the error throwing from the analyser since there isn't a way to express
314314
// "safepoint only when throwing error" currently.
315315
jl_errorf("could not load symbol \"%s\":\n%s", symbol, err);

src/dump.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,13 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
350350
jl_serialize_value(s, (jl_value_t*)table[i]);
351351
jl_binding_t *b = (jl_binding_t*)table[i+1];
352352
jl_serialize_value(s, b->name);
353-
jl_value_t *e = b->value;
353+
jl_value_t *e = jl_atomic_load_relaxed(&b->value);
354354
if (!b->constp && e && jl_is_cpointer(e) && jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
355355
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
356356
jl_serialize_cnull(s, jl_typeof(e));
357357
else
358358
jl_serialize_value(s, e);
359-
jl_serialize_value(s, b->globalref);
359+
jl_serialize_value(s, jl_atomic_load_relaxed(&b->globalref));
360360
jl_serialize_value(s, b->owner);
361361
write_int8(s->s, (b->deprecated<<3) | (b->constp<<2) | (b->exportp<<1) | (b->imported));
362362
}
@@ -660,7 +660,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
660660
if (!(serialization_mode & METHOD_INTERNAL))
661661
return;
662662
jl_serialize_value(s, m->specializations);
663-
jl_serialize_value(s, m->speckeyset);
663+
jl_serialize_value(s, jl_atomic_load_relaxed(&m->speckeyset));
664664
jl_serialize_value(s, (jl_value_t*)m->name);
665665
jl_serialize_value(s, (jl_value_t*)m->file);
666666
write_int32(s->s, m->line);
@@ -1510,8 +1510,9 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_
15101510
}
15111511
m->specializations = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&m->specializations);
15121512
jl_gc_wb(m, m->specializations);
1513-
m->speckeyset = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->speckeyset);
1514-
jl_gc_wb(m, m->speckeyset);
1513+
jl_array_t *speckeyset = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->speckeyset);
1514+
jl_atomic_store_relaxed(&m->speckeyset, speckeyset);
1515+
jl_gc_wb(m, speckeyset);
15151516
m->name = (jl_sym_t*)jl_deserialize_value(s, NULL);
15161517
jl_gc_wb(m, m->name);
15171518
m->file = (jl_sym_t*)jl_deserialize_value(s, NULL);
@@ -1653,8 +1654,9 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) JL_GC_DIS
16531654
jl_value_t *bvalue = jl_deserialize_value(s, (jl_value_t**)&b->value);
16541655
*(jl_value_t**)&b->value = bvalue;
16551656
if (bvalue != NULL) jl_gc_wb(m, bvalue);
1656-
b->globalref = jl_deserialize_value(s, &b->globalref);
1657-
if (b->globalref != NULL) jl_gc_wb(m, b->globalref);
1657+
jl_value_t *bglobalref = jl_deserialize_value(s, (jl_value_t**)&b->globalref);
1658+
*(jl_value_t**)&b->globalref = bglobalref;
1659+
if (bglobalref != NULL) jl_gc_wb(m, bglobalref);
16581660
b->owner = (jl_module_t*)jl_deserialize_value(s, (jl_value_t**)&b->owner);
16591661
if (b->owner != NULL) jl_gc_wb(m, b->owner);
16601662
int8_t flags = read_int8(s->s);

src/gc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,8 +2404,8 @@ module_binding: {
24042404
void *vb = jl_astaggedvalue(b);
24052405
verify_parent1("module", binding->parent, &vb, "binding_buff");
24062406
(void)vb;
2407-
jl_value_t *value = b->value;
2408-
jl_value_t *globalref = b->globalref;
2407+
jl_value_t *value = jl_atomic_load_relaxed(&b->value);
2408+
jl_value_t *globalref = jl_atomic_load_relaxed(&b->globalref);
24092409
if (value) {
24102410
verify_parent2("module", binding->parent,
24112411
&b->value, "binding(%s)", jl_symbol_name(b->name));
@@ -2808,9 +2808,11 @@ static void mark_roots(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp)
28082808
}
28092809
}
28102810
gc_mark_queue_obj(gc_cache, sp, jl_anytuple_type_type);
2811-
for (size_t i = 0; i < N_CALL_CACHE; i++)
2812-
if (call_cache[i])
2813-
gc_mark_queue_obj(gc_cache, sp, call_cache[i]);
2811+
for (size_t i = 0; i < N_CALL_CACHE; i++) {
2812+
jl_typemap_entry_t *v = jl_atomic_load_relaxed(&call_cache[i]);
2813+
if (v != NULL)
2814+
gc_mark_queue_obj(gc_cache, sp, v);
2815+
}
28142816
if (jl_all_methods != NULL)
28152817
gc_mark_queue_obj(gc_cache, sp, jl_all_methods);
28162818
if (_jl_debug_method_invalidation != NULL)
@@ -2977,8 +2979,8 @@ static void jl_gc_queue_remset(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp
29772979
jl_binding_t *ptr = (jl_binding_t*)items[i];
29782980
// A null pointer can happen here when the binding is cleaned up
29792981
// as an exception is thrown after it was already queued (#10221)
2980-
if (!ptr->value) continue;
2981-
if (gc_mark_queue_obj(gc_cache, sp, ptr->value)) {
2982+
jl_value_t *v = jl_atomic_load_relaxed(&ptr->value);
2983+
if (v != NULL && gc_mark_queue_obj(gc_cache, sp, v)) {
29822984
items[n_bnd_refyoung] = ptr;
29832985
n_bnd_refyoung++;
29842986
}

src/gc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ typedef struct {
371371
int ub;
372372
} pagetable_t;
373373

374-
#ifdef __clang_analyzer__
374+
#ifdef __clang_gcanalyzer__
375375
unsigned ffs_u32(uint32_t bitvec) JL_NOTSAFEPOINT;
376376
#else
377377
STATIC_INLINE unsigned ffs_u32(uint32_t bitvec)

0 commit comments

Comments
 (0)