Skip to content

Commit

Permalink
fixup! update atomics.h to be more fully C11/C++11 compliant
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 10, 2021
1 parent 233cc24 commit 1439e17
Show file tree
Hide file tree
Showing 36 changed files with 231 additions and 204 deletions.
26 changes: 17 additions & 9 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ endif

# headers are used for dependency tracking, while public headers will be part of the dist
UV_HEADERS :=
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))
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)
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))
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)
ifeq ($(USE_SYSTEM_LIBUV),0)
UV_HEADERS += uv.h
UV_HEADERS += uv/*.h
Expand Down Expand Up @@ -376,15 +376,23 @@ endif

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

clang-sa-%: $(SRCDIR)/%.c $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check
@$(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 $<)
clang-sa-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check
@$(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++ $<)
clang-sagc-%: $(SRCDIR)/%.c $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) .FORCE | analyzegc-deps-check
@$(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 $<)
clang-sagc-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) .FORCE | analyzegc-deps-check
@$(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++ $<)

# Add C files as a target of `analyzegc`
analyzegc: $(addprefix clang-sa-,$(RUNTIME_SRCS))
clang-sa-%: $(SRCDIR)/%.c .FORCE | analyzegc-deps-check
@$(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 $<)
clang-sa-%: $(SRCDIR)/%.cpp .FORCE | analyzegc-deps-check
@$(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++ $<)


# Add C files as a target of `analyzesrc` and `analyzegc`
analyzesrc: $(addprefix clang-sa-,$(SRCS))
analyzegc: analyzesrc $(addprefix clang-sagc-,$(RUNTIME_SRCS))

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

.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc clang-sa-*
.FORCE:
.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc analyzesrc .FORCE
22 changes: 13 additions & 9 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static inline void arrayassign_safe(int hasptr, jl_value_t *parent, char *dst, c
assert(nb >= jl_datatype_size(jl_typeof(src))); // nb might move some undefined bits, but we should be okay with that
if (hasptr) {
size_t nptr = nb / sizeof(void*);
memmove_refs((void**)dst, (void**)src, nptr);
memmove_refs((void**)dst, (void* const*)src, nptr);
jl_gc_multi_wb(parent, src);
}
else {
Expand Down Expand Up @@ -588,7 +588,7 @@ JL_DLLEXPORT jl_value_t *jl_ptrarrayref(jl_array_t *a JL_PROPAGATES_ROOT, size_t
{
assert(i < jl_array_len(a));
assert(a->flags.ptrarray);
jl_value_t *elt = jl_atomic_load_relaxed(((jl_value_t**)a->data) + i);
jl_value_t *elt = jl_atomic_load_relaxed(((_Atomic(jl_value_t*)*)a->data) + i);
if (elt == NULL)
jl_throw(jl_undefref_exception);
return elt;
Expand Down Expand Up @@ -617,7 +617,7 @@ JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
JL_DLLEXPORT int jl_array_isassigned(jl_array_t *a, size_t i)
{
if (a->flags.ptrarray) {
return jl_atomic_load_relaxed(((jl_value_t**)jl_array_data(a)) + i) != NULL;
return jl_atomic_load_relaxed(((_Atomic(jl_value_t*)*)jl_array_data(a)) + i) != NULL;
}
else if (a->flags.hasptr) {
jl_datatype_t *eltype = (jl_datatype_t*)jl_tparam0(jl_typeof(a));
Expand Down Expand Up @@ -656,7 +656,7 @@ JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *rhs
arrayassign_safe(hasptr, jl_array_owner(a), &((char*)a->data)[i * a->elsize], rhs, a->elsize);
}
else {
jl_atomic_store_relaxed(((jl_value_t**)a->data) + i, rhs);
jl_atomic_store_relaxed(((_Atomic(jl_value_t*)*)a->data) + i, rhs);
jl_gc_wb(jl_array_owner(a), rhs);
}
}
Expand All @@ -666,7 +666,7 @@ JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i)
if (i >= jl_array_len(a))
jl_bounds_error_int((jl_value_t*)a, i + 1);
if (a->flags.ptrarray)
jl_atomic_store_relaxed(((jl_value_t**)a->data) + i, NULL);
jl_atomic_store_relaxed(((_Atomic(jl_value_t*)*)a->data) + i, NULL);
else if (a->flags.hasptr) {
size_t elsize = a->elsize;
jl_assume(elsize >= sizeof(void*) && elsize % sizeof(void*) == 0);
Expand Down Expand Up @@ -1243,9 +1243,11 @@ static NOINLINE ssize_t jl_array_ptr_copy_forward(jl_value_t *owner,
void **src_p, void **dest_p,
ssize_t n) JL_NOTSAFEPOINT
{
_Atomic(void*) *src_pa = (_Atomic(void*)*)src_p;
_Atomic(void*) *dest_pa = (_Atomic(void*)*)dest_p;
for (ssize_t i = 0; i < n; i++) {
void *val = jl_atomic_load_relaxed(src_p + i);
jl_atomic_store_relaxed(dest_p + i, val);
void *val = jl_atomic_load_relaxed(src_pa + i);
jl_atomic_store_relaxed(dest_pa + i, val);
// `val` is young or old-unmarked
if (val && !(jl_astaggedvalue(val)->bits.gc & GC_MARKED)) {
jl_gc_queue_root(owner);
Expand All @@ -1259,9 +1261,11 @@ static NOINLINE ssize_t jl_array_ptr_copy_backward(jl_value_t *owner,
void **src_p, void **dest_p,
ssize_t n) JL_NOTSAFEPOINT
{
_Atomic(void*) *src_pa = (_Atomic(void*)*)src_p;
_Atomic(void*) *dest_pa = (_Atomic(void*)*)dest_p;
for (ssize_t i = 0; i < n; i++) {
void *val = jl_atomic_load_relaxed(src_p + n - i - 1);
jl_atomic_store_relaxed(dest_p + n - i - 1, val);
void *val = jl_atomic_load_relaxed(src_pa + n - i - 1);
jl_atomic_store_relaxed(dest_pa + n - i - 1, val);
// `val` is young or old-unmarked
if (val && !(jl_astaggedvalue(val)->bits.gc & GC_MARKED)) {
jl_gc_queue_root(owner);
Expand Down
2 changes: 1 addition & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ typedef struct _jl_ast_context_t {

static jl_ast_context_t jl_ast_main_ctx;

#ifdef __clang_analyzer__
#ifdef __clang_gcanalyzer__
jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT;
#else
#define jl_ast_ctx(fl_ctx) container_of(fl_ctx, jl_ast_context_t, fl)
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ static jl_value_t *do_apply( jl_value_t **args, uint32_t nargs, jl_value_t *iter
}
if (arg_heap) {
// optimization: keep only the first root, free the others
#ifndef __clang_analyzer__
#ifndef __clang_gcanalyzer__
((void**)roots)[-2] = (void*)JL_GC_ENCODE_PUSHARGS(1);
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5748,7 +5748,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con
// some sanity checking and check whether there's a vararg
size_t nargt = jl_svec_len(argt);
bool isVa = (nargt > 0 && jl_is_vararg(jl_svecref(argt, nargt - 1)));
assert(!isVa);
assert(!isVa); (void)isVa;

jl_array_t *closure_types = NULL;
jl_value_t *sigt = NULL; // dispatch-sig = type signature with Ref{} annotations removed and applied to the env
Expand Down
10 changes: 5 additions & 5 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
jl_methtable_type);
mt->name = jl_demangle_typename(name);
mt->module = module;
mt->defs = jl_nothing;
mt->leafcache = (jl_array_t*)jl_an_empty_vec_any;
mt->cache = jl_nothing;
jl_atomic_store_relaxed(&mt->defs, jl_nothing);
jl_atomic_store_relaxed(&mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
jl_atomic_store_relaxed(&mt->cache, jl_nothing);
mt->max_args = 0;
mt->kwsorter = NULL;
mt->backedges = NULL;
Expand All @@ -69,8 +69,8 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu
tn->name = name;
tn->module = module;
tn->wrapper = NULL;
tn->cache = jl_emptysvec;
tn->linearcache = jl_emptysvec;
jl_atomic_store_relaxed(&tn->cache, jl_emptysvec);
jl_atomic_store_relaxed(&tn->linearcache, jl_emptysvec);
tn->names = NULL;
tn->hash = bitmix(bitmix(module ? module->build_id : 0, name->hash), 0xa1ada1da);
tn->abstract = abstract;
Expand Down
2 changes: 1 addition & 1 deletion src/dlload.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ JL_DLLEXPORT int jl_dlsym(void *handle, const char *symbol, void ** value, int t
char err[256];
win32_formatmessage(GetLastError(), err, sizeof(err));
#endif
#ifndef __clang_analyzer__
#ifndef __clang_gcanalyzer__
// Hide the error throwing from the analyser since there isn't a way to express
// "safepoint only when throwing error" currently.
jl_errorf("could not load symbol \"%s\":\n%s", symbol, err);
Expand Down
16 changes: 9 additions & 7 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,13 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
jl_serialize_value(s, (jl_value_t*)table[i]);
jl_binding_t *b = (jl_binding_t*)table[i+1];
jl_serialize_value(s, b->name);
jl_value_t *e = b->value;
jl_value_t *e = jl_atomic_load_relaxed(&b->value);
if (!b->constp && e && jl_is_cpointer(e) && jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
jl_serialize_cnull(s, jl_typeof(e));
else
jl_serialize_value(s, e);
jl_serialize_value(s, b->globalref);
jl_serialize_value(s, jl_atomic_load_relaxed(&b->globalref));
jl_serialize_value(s, b->owner);
write_int8(s->s, (b->deprecated<<3) | (b->constp<<2) | (b->exportp<<1) | (b->imported));
}
Expand Down Expand Up @@ -660,7 +660,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
if (!(serialization_mode & METHOD_INTERNAL))
return;
jl_serialize_value(s, m->specializations);
jl_serialize_value(s, m->speckeyset);
jl_serialize_value(s, jl_atomic_load_relaxed(&m->speckeyset));
jl_serialize_value(s, (jl_value_t*)m->name);
jl_serialize_value(s, (jl_value_t*)m->file);
write_int32(s->s, m->line);
Expand Down Expand Up @@ -1510,8 +1510,9 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_
}
m->specializations = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&m->specializations);
jl_gc_wb(m, m->specializations);
m->speckeyset = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->speckeyset);
jl_gc_wb(m, m->speckeyset);
jl_array_t *speckeyset = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->speckeyset);
jl_atomic_store_relaxed(&m->speckeyset, speckeyset);
jl_gc_wb(m, speckeyset);
m->name = (jl_sym_t*)jl_deserialize_value(s, NULL);
jl_gc_wb(m, m->name);
m->file = (jl_sym_t*)jl_deserialize_value(s, NULL);
Expand Down Expand Up @@ -1653,8 +1654,9 @@ static jl_value_t *jl_deserialize_value_module(jl_serializer_state *s) JL_GC_DIS
jl_value_t *bvalue = jl_deserialize_value(s, (jl_value_t**)&b->value);
*(jl_value_t**)&b->value = bvalue;
if (bvalue != NULL) jl_gc_wb(m, bvalue);
b->globalref = jl_deserialize_value(s, &b->globalref);
if (b->globalref != NULL) jl_gc_wb(m, b->globalref);
jl_value_t *bglobalref = jl_deserialize_value(s, (jl_value_t**)&b->globalref);
*(jl_value_t**)&b->globalref = bglobalref;
if (bglobalref != NULL) jl_gc_wb(m, bglobalref);
b->owner = (jl_module_t*)jl_deserialize_value(s, (jl_value_t**)&b->owner);
if (b->owner != NULL) jl_gc_wb(m, b->owner);
int8_t flags = read_int8(s->s);
Expand Down
16 changes: 9 additions & 7 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2404,8 +2404,8 @@ module_binding: {
void *vb = jl_astaggedvalue(b);
verify_parent1("module", binding->parent, &vb, "binding_buff");
(void)vb;
jl_value_t *value = b->value;
jl_value_t *globalref = b->globalref;
jl_value_t *value = jl_atomic_load_relaxed(&b->value);
jl_value_t *globalref = jl_atomic_load_relaxed(&b->globalref);
if (value) {
verify_parent2("module", binding->parent,
&b->value, "binding(%s)", jl_symbol_name(b->name));
Expand Down Expand Up @@ -2808,9 +2808,11 @@ static void mark_roots(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp)
}
}
gc_mark_queue_obj(gc_cache, sp, jl_anytuple_type_type);
for (size_t i = 0; i < N_CALL_CACHE; i++)
if (call_cache[i])
gc_mark_queue_obj(gc_cache, sp, call_cache[i]);
for (size_t i = 0; i < N_CALL_CACHE; i++) {
jl_typemap_entry_t *v = jl_atomic_load_relaxed(&call_cache[i]);
if (v != NULL)
gc_mark_queue_obj(gc_cache, sp, v);
}
if (jl_all_methods != NULL)
gc_mark_queue_obj(gc_cache, sp, jl_all_methods);
if (_jl_debug_method_invalidation != NULL)
Expand Down Expand Up @@ -2977,8 +2979,8 @@ static void jl_gc_queue_remset(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp
jl_binding_t *ptr = (jl_binding_t*)items[i];
// A null pointer can happen here when the binding is cleaned up
// as an exception is thrown after it was already queued (#10221)
if (!ptr->value) continue;
if (gc_mark_queue_obj(gc_cache, sp, ptr->value)) {
jl_value_t *v = jl_atomic_load_relaxed(&ptr->value);
if (v != NULL && gc_mark_queue_obj(gc_cache, sp, v)) {
items[n_bnd_refyoung] = ptr;
n_bnd_refyoung++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ typedef struct {
int ub;
} pagetable_t;

#ifdef __clang_analyzer__
#ifdef __clang_gcanalyzer__
unsigned ffs_u32(uint32_t bitvec) JL_NOTSAFEPOINT;
#else
STATIC_INLINE unsigned ffs_u32(uint32_t bitvec)
Expand Down
Loading

0 comments on commit 1439e17

Please sign in to comment.