authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-27 17:16:00-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-27 17:16:00-04:00
log442e244b4dd371d674436a163d62efdcd4e17a00
treedee4e6118d43ac8990f861818ee052f6faf0d114
parent10764ee0e66e5d9a815073340d8f16a58e225422

suspend sets suspend bit


2 files changed, 20 insertions(+), 3 deletions(-)

src/ir.cpp+18-1
......@@ -6874,9 +6874,26 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
68746874
68756875 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup");
68766876 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume");
6877 IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended");
6878 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended");
68776879
6878 IrInstruction *suspend_code;
68796880 IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false);
6881 IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize);
6882 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010
6883 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0);
6884
6885 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node,
6886 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
6887 AtomicRmwOp_or, AtomicOrderSeqCst);
6888 IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false);
6889 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false);
6890 ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false);
6891
6892 ir_set_cursor_at_end_and_append_block(irb, suspended_block);
6893 ir_build_unreachable(irb, parent_scope, node);
6894
6895 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block);
6896 IrInstruction *suspend_code;
68806897 if (node->data.suspend.block == nullptr) {
68816898 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
68826899 } else {
test/cases/coroutines.zig+2-2
......@@ -244,8 +244,8 @@ test "break from suspend" {
244244 std.debug.assert(my_result == 2);
245245}
246246async fn testBreakFromSuspend(my_result: *i32) void {
247 s: suspend |p| {
248 break :s;
247 suspend |p| {
248 resume p;
249249 }
250250 my_result.* += 1;
251251 suspend;