Skip to content

Use safepoint to deliver SIGINT #16174

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

Merged
merged 9 commits into from
May 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,20 @@ end
# within a long-running C routine.
sigatomic_begin() = ccall(:jl_sigatomic_begin, Void, ())
sigatomic_end() = ccall(:jl_sigatomic_end, Void, ())
disable_sigint(f::Function) = try sigatomic_begin(); f(); finally sigatomic_end(); end
reenable_sigint(f::Function) = try sigatomic_end(); f(); finally sigatomic_begin(); end
function disable_sigint(f::Function)
sigatomic_begin()
res = f()
# Exception unwind sigatomic automatically
sigatomic_end()
res
end
function reenable_sigint(f::Function)
sigatomic_end()
res = f()
# Exception unwind sigatomic automatically
sigatomic_begin()
res
end

function ccallable(f::Function, rt::Type, argt::Type, name::Union{AbstractString,Symbol}=string(f))
ccall(:jl_extern_c, Void, (Any, Any, Any, Cstring), f, rt, argt, name)
Expand Down
2 changes: 2 additions & 0 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,7 @@ function typeinf_loop(frame)
frame.inworkq || typeinf_frame(frame)
return
end
ccall(:jl_sigatomic_begin, Void, ())
try
in_typeinf_loop = true
# the core type-inference algorithm
Expand Down Expand Up @@ -1608,6 +1609,7 @@ function typeinf_loop(frame)
println(ex)
ccall(:jlbacktrace, Void, ())
end
ccall(:jl_sigatomic_end, Void, ())
nothing
end

Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SRCS := \
jltypes gf typemap ast builtins module interpreter \
alloc dlload sys init task array dump toplevel jl_uv jlapi signal-handling \
simplevector APInt-C runtime_intrinsics runtime_ccall \
threadgroup threading stackwalk gc
threadgroup threading stackwalk gc safepoint

ifeq ($(JULIACODEGEN),LLVM)
SRCS += codegen disasm debuginfo llvm-simdloop llvm-gcroot
Expand Down
6 changes: 6 additions & 0 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ static jl_ast_context_list_t *jl_ast_ctx_freed = NULL;

static jl_ast_context_t *jl_ast_ctx_enter(void)
{
JL_SIGATOMIC_BEGIN();
JL_LOCK_NOGC(&flisp_lock);
jl_ast_context_list_t *node;
jl_ast_context_t *ctx;
Expand Down Expand Up @@ -267,6 +268,7 @@ static jl_ast_context_t *jl_ast_ctx_enter(void)

static void jl_ast_ctx_leave(jl_ast_context_t *ctx)
{
JL_SIGATOMIC_END();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks --lisp; segfaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... ok.... will fix later today....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in case you need it now, I think making jl_sigint_safepoint noop should work around it for now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 417e49a

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be tested if breaking it matters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run(pipeline(DevNull, $(Base.julia_cmd()) --lisp, DevNull)) ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like that. might need to be unix only, would need to run it through CI first

if (--ctx->ref)
return;
JL_LOCK_NOGC(&flisp_lock);
Expand All @@ -285,6 +287,8 @@ void jl_init_frontend(void)
jl_ast_main_ctx.task = jl_current_task;
jl_ast_context_list_insert(&jl_ast_ctx_using, &jl_ast_main_ctx.list);
jl_init_ast_ctx(&jl_ast_main_ctx);
// To match the one in jl_ast_ctx_leave
JL_SIGATOMIC_BEGIN();
jl_ast_ctx_leave(&jl_ast_main_ctx);
}

Expand Down Expand Up @@ -758,6 +762,7 @@ jl_value_t *jl_parse_eval_all(const char *fname, size_t len,
form = scm_to_julia(fl_ctx, expansion, 0);
jl_sym_t *head = NULL;
if (jl_is_expr(form)) head = ((jl_expr_t*)form)->head;
JL_SIGATOMIC_END();
if (head == jl_incomplete_sym)
jl_errorf("syntax: %s", jl_string_data(jl_exprarg(form,0)));
else if (head == error_sym)
Expand All @@ -766,6 +771,7 @@ jl_value_t *jl_parse_eval_all(const char *fname, size_t len,
jl_lineno = jl_unbox_long(jl_exprarg(form,0));
else
result = jl_toplevel_eval_flex(form, 1);
JL_SIGATOMIC_BEGIN();
ast = cdr_(ast);
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,25 +194,25 @@ JL_CALLABLE(jl_f_throw)

JL_DLLEXPORT void jl_enter_handler(jl_handler_t *eh)
{
JL_SIGATOMIC_BEGIN();
// Must have no safepoint
eh->prev = jl_current_task->eh;
eh->gcstack = jl_pgcstack;
#ifdef JULIA_ENABLE_THREADING
eh->gc_state = jl_gc_state();
eh->locks_len = jl_current_task->locks.len;
#endif
eh->defer_signal = jl_get_ptls_states()->defer_signal;
jl_current_task->eh = eh;
// TODO: this should really go after setjmp(). see comment in
// ctx_switch in task.c.
JL_SIGATOMIC_END();
}

JL_DLLEXPORT void jl_pop_handler(int n)
{
while (n > 0) {
jl_eh_restore_state(jl_current_task->eh);
n--;
}
if (__unlikely(n <= 0))
return;
jl_handler_t *eh = jl_current_task->eh;
while (--n > 0)
eh = eh->prev;
jl_eh_restore_state(eh);
}

// primitives -----------------------------------------------------------------
Expand Down
70 changes: 48 additions & 22 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1243,28 +1243,54 @@ static jl_cgval_t emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
assert(!isVa);
assert(nargt == 0);
JL_GC_POP();
#ifdef JULIA_ENABLE_THREADING
#ifdef LLVM39
builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SingleThread);
#else
builder.CreateFence(SequentiallyConsistent, SingleThread);
#endif
Value *addr;
if (imaging_mode) {
assert(ctx->signalPage);
addr = ctx->signalPage;
}
else {
addr = builder.CreateIntToPtr(
ConstantInt::get(T_size, (uintptr_t)jl_gc_signal_page), T_pint8);
}
builder.CreateLoad(addr, true);
#ifdef LLVM39
builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SingleThread);
#else
builder.CreateFence(SequentiallyConsistent, SingleThread);
#endif
#endif
emit_signal_fence();
builder.CreateLoad(ctx->signalPage, true);
emit_signal_fence();
return ghostValue(jl_void_type);
}
if (fptr == &jl_sigatomic_begin ||
((!f_lib || (intptr_t)f_lib == 2) && f_name &&
strcmp(f_name, "jl_sigatomic_begin") == 0)) {
assert(lrt == T_void);
assert(!isVa);
assert(nargt == 0);
JL_GC_POP();
Value *pdefer_sig = emit_defer_signal(ctx);
Value *defer_sig = builder.CreateLoad(pdefer_sig);
defer_sig = builder.CreateAdd(defer_sig,
ConstantInt::get(T_sigatomic, 1));
builder.CreateStore(defer_sig, pdefer_sig);
emit_signal_fence();
return ghostValue(jl_void_type);
}
if (fptr == &jl_sigatomic_end ||
((!f_lib || (intptr_t)f_lib == 2) && f_name &&
strcmp(f_name, "jl_sigatomic_end") == 0)) {
assert(lrt == T_void);
assert(!isVa);
assert(nargt == 0);
JL_GC_POP();
Value *pdefer_sig = emit_defer_signal(ctx);
Value *defer_sig = builder.CreateLoad(pdefer_sig);
emit_signal_fence();
error_unless(builder.CreateICmpNE(defer_sig,
ConstantInt::get(T_sigatomic, 0)),
"sigatomic_end called in non-sigatomic region", ctx);
defer_sig = builder.CreateSub(defer_sig,
ConstantInt::get(T_sigatomic, 1));
builder.CreateStore(defer_sig, pdefer_sig);
BasicBlock *checkBB = BasicBlock::Create(jl_LLVMContext, "check",
ctx->f);
BasicBlock *contBB = BasicBlock::Create(jl_LLVMContext, "cont");
builder.CreateCondBr(
builder.CreateICmpEQ(defer_sig, ConstantInt::get(T_sigatomic, 0)),
checkBB, contBB);
builder.SetInsertPoint(checkBB);
builder.CreateLoad(builder.CreateConstGEP1_32(ctx->signalPage, -1),
true);
builder.CreateBr(contBB);
ctx->f->getBasicBlockList().push_back(contBB);
builder.SetInsertPoint(contBB);
return ghostValue(jl_void_type);
}
if (fptr == (void(*)(void))&jl_is_leaf_type ||
Expand Down
26 changes: 25 additions & 1 deletion src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ static bool deserves_sret(jl_value_t *dt, Type *T)
static Value *emit_nthptr_addr(Value *v, ssize_t n)
{
return builder.CreateGEP(builder.CreateBitCast(v, T_ppjlvalue),
ConstantInt::get(T_size, (ssize_t)n));
ConstantInt::get(T_size, n));
}

static Value *emit_nthptr_addr(Value *v, Value *idx)
Expand All @@ -477,6 +477,13 @@ static Value *emit_nthptr_recast(Value *v, Value *idx, MDNode *tbaa, Type *ptype
return tbaa_decorate(tbaa,builder.CreateLoad(builder.CreateBitCast(vptr,ptype), false));
}

static Value *emit_nthptr_recast(Value *v, ssize_t n, MDNode *tbaa, Type *ptype)
{
// p = (jl_value_t**)v; *(ptype)&p[n]
Value *vptr = emit_nthptr_addr(v, n);
return tbaa_decorate(tbaa,builder.CreateLoad(builder.CreateBitCast(vptr,ptype), false));
}

static Value *emit_typeptr_addr(Value *p)
{
ssize_t offset = (sizeof(jl_taggedvalue_t) -
Expand Down Expand Up @@ -1710,3 +1717,20 @@ static Value *emit_exc_in_transit(jl_codectx_t *ctx)
Constant *offset = ConstantInt::getSigned(T_int32, offsetof(jl_tls_states_t, exception_in_transit) / sizeof(void*));
return builder.CreateGEP(pexc_in_transit, ArrayRef<Value*>(offset), "jl_exception_in_transit");
}

static void emit_signal_fence(void)
{
#ifdef LLVM39
builder.CreateFence(AtomicOrdering::SequentiallyConsistent, SingleThread);
#else
builder.CreateFence(SequentiallyConsistent, SingleThread);
#endif
}

static Value *emit_defer_signal(jl_codectx_t *ctx)
{
Value *ptls = builder.CreateBitCast(ctx->ptlsStates,
PointerType::get(T_sigatomic, 0));
Constant *offset = ConstantInt::getSigned(T_int32, offsetof(jl_tls_states_t, defer_signal) / sizeof(sig_atomic_t));
return builder.CreateGEP(ptls, ArrayRef<Value*>(offset), "jl_defer_signal");
}
21 changes: 7 additions & 14 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ static IntegerType *T_uint64;

static IntegerType *T_char;
static IntegerType *T_size;
static IntegerType *T_sigatomic;

static Type *T_float16;
static Type *T_float32;
Expand Down Expand Up @@ -342,8 +343,6 @@ static GlobalVariable *jltls_states_var;
// Imaging mode only
static GlobalVariable *jltls_states_func_ptr = NULL;
static size_t jltls_states_func_idx = 0;
static GlobalVariable *jl_gc_signal_page_ptr = NULL;
static size_t jl_gc_signal_page_idx = 0;
#endif

// important functions
Expand Down Expand Up @@ -576,9 +575,7 @@ typedef struct {
std::vector<bool> inbounds;

CallInst *ptlsStates;
#ifdef JULIA_ENABLE_THREADING
Value *signalPage;
#endif

llvm::DIBuilder *dbuilder;
bool debug_enabled;
Expand Down Expand Up @@ -1340,6 +1337,7 @@ const jl_value_t *jl_dump_function_asm(void *f, int raw_mc)
return (jl_value_t*)jl_pchar_to_array((char*)fptr, symsize);
}

int8_t gc_state = jl_gc_safe_enter();
jl_dump_asm_internal(fptr, symsize, slide,
#ifndef USE_MCJIT
context,
Expand All @@ -1355,6 +1353,7 @@ const jl_value_t *jl_dump_function_asm(void *f, int raw_mc)
#ifndef LLVM37
fstream.flush();
#endif
jl_gc_safe_leave(gc_state);

return jl_cstr_to_string(const_cast<char*>(stream.str().c_str()));
}
Expand Down Expand Up @@ -3429,12 +3428,9 @@ static void allocate_gc_frame(BasicBlock *b0, jl_codectx_t *ctx)
{
// allocate a placeholder gc instruction
ctx->ptlsStates = builder.CreateCall(prepare_call(jltls_states_func));
#ifdef JULIA_ENABLE_THREADING
if (imaging_mode) {
ctx->signalPage =
tbaa_decorate(tbaa_const, builder.CreateLoad(prepare_global(jl_gc_signal_page_ptr)));
}
#endif
int nthfield = offsetof(jl_tls_states_t, safepoint) / sizeof(void*);
ctx->signalPage = emit_nthptr_recast(ctx->ptlsStates, nthfield, tbaa_const,
PointerType::get(T_psize, 0));
}

void jl_codegen_finalize_temp_arg(CallInst *ptlsStates, Type *T_pjlvalue,
Expand Down Expand Up @@ -4975,6 +4971,7 @@ static void init_julia_llvm_env(Module *m)
T_size = T_uint64;
else
T_size = T_uint32;
T_sigatomic = Type::getIntNTy(jl_LLVMContext, sizeof(sig_atomic_t) * 8);
T_psize = PointerType::get(T_size, 0);
T_float16 = Type::getHalfTy(jl_LLVMContext);
T_float32 = Type::getFloatTy(jl_LLVMContext);
Expand Down Expand Up @@ -5165,10 +5162,6 @@ static void init_julia_llvm_env(Module *m)
jl_emit_sysimg_slot(m, pfunctype, "jl_get_ptls_states.ptr",
(uintptr_t)jl_get_ptls_states_getter(),
jltls_states_func_idx);
jl_gc_signal_page_ptr =
jl_emit_sysimg_slot(m, T_pint8, "jl_gc_signal_page.ptr",
(uintptr_t)jl_gc_signal_page,
jl_gc_signal_page_idx);
}
#endif

Expand Down
Loading