Skip to content

Commit eab51c4

Browse files
committed
[Concurrency] Cancellation Shields PoC
1 parent 8dd006f commit eab51c4

File tree

24 files changed

+559
-10
lines changed

24 files changed

+559
-10
lines changed

include/swift/ABI/Task.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,10 @@ class AsyncTask : public Job {
468468

469469
/// Check whether this task has been cancelled.
470470
/// Checking this is, of course, inherently race-prone on its own.
471-
bool isCancelled() const;
471+
///
472+
/// \param ignoreShield if cancellation shield should be ignored.
473+
/// Cancellation shields prevent the observation of the isCancelled flag while active.
474+
bool isCancelled(bool ignoreShield) const;
472475

473476
// ==== INITIAL TASK RECORDS =================================================
474477
// A task may have a number of "initial" records set, they MUST be set in the
@@ -531,6 +534,12 @@ class AsyncTask : public Job {
531534
/// Returns true if storage has still more bindings.
532535
bool localValuePop();
533536

537+
// ==== Cancellation Shields -------------------------------------------------
538+
539+
/// Returns true if the shield was installed and should be removed when leaving the shielded scope.
540+
bool cancellationShieldPush();
541+
void cancellationShieldPop();
542+
534543
// ==== Child Fragment -------------------------------------------------------
535544

536545
/// A fragment of an async task structure that happens to be a child task.

include/swift/AST/Builtins.def

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,16 @@ BUILTIN_MISC_OPERATION(TaskLocalValuePush, "taskLocalValuePush", "", Special)
12101210
/// Signature: () -> ()
12111211
BUILTIN_MISC_OPERATION(TaskLocalValuePop, "taskLocalValuePop", "", Special)
12121212

1213+
/// Equivalent to calling swift_task_cancellationShieldPush.
1214+
///
1215+
/// Signature: () -> ()
1216+
BUILTIN_MISC_OPERATION(TaskCancellationShieldPush, "taskCancellationShieldPush", "", Special)
1217+
1218+
/// Equivalent to calling swift_task_cancellationShieldPop.
1219+
///
1220+
/// Signature: () -> ()
1221+
BUILTIN_MISC_OPERATION(TaskCancellationShieldPop, "taskCancellationShieldPop", "", Special)
1222+
12131223
#undef BUILTIN_TYPE_TRAIT_OPERATION
12141224
#undef BUILTIN_UNARY_OPERATION
12151225
#undef BUILTIN_BINARY_PREDICATE

include/swift/Runtime/Concurrency.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ void swift_task_localValuePop();
721721
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
722722
void swift_task_localsCopyTo(AsyncTask* target);
723723

724+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
725+
void swift_task_cancellationShieldPush();
726+
727+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
728+
void swift_task_cancellationShieldPop();
729+
724730
/// Switch the current task to a new executor if we aren't already
725731
/// running on a compatible executor.
726732
///

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,6 +2734,26 @@ FUNCTION(TaskLocalValuePop,
27342734
EFFECT(RuntimeEffect::Concurrency),
27352735
UNKNOWN_MEMEFFECTS)
27362736

2737+
// void swift_task_cancellationShieldPush();
2738+
FUNCTION(TaskCancellationShieldPush,
2739+
_Concurrency, swift_task_cancellationShieldPush, SwiftCC,
2740+
ConcurrencyAvailability,
2741+
RETURNS(), // TODO: return a bool here
2742+
ARGS(),
2743+
ATTRS(NoUnwind),
2744+
EFFECT(RuntimeEffect::Concurrency),
2745+
UNKNOWN_MEMEFFECTS)
2746+
2747+
// void swift_task_cancellationShieldPop();
2748+
FUNCTION(TaskCancellationShieldPop,
2749+
_Concurrency, swift_task_cancellationShieldPop, SwiftCC,
2750+
ConcurrencyAvailability,
2751+
RETURNS(),
2752+
ARGS(),
2753+
ATTRS(NoUnwind),
2754+
EFFECT(RuntimeEffect::Concurrency),
2755+
UNKNOWN_MEMEFFECTS)
2756+
27372757
// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContextWithType(const Metadata *);
27382758
FUNCTION(AutoDiffCreateLinearMapContextWithType,
27392759
Swift, swift_autoDiffCreateLinearMapContextWithType, SwiftCC,

include/swift/SIL/AddressWalker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) {
296296
case BuiltinValueKind::FlowSensitiveSelfIsolation:
297297
case BuiltinValueKind::FlowSensitiveDistributedSelfIsolation:
298298
case BuiltinValueKind::TaskLocalValuePush:
299+
case BuiltinValueKind::TaskCancellationShieldPush:
300+
case BuiltinValueKind::TaskCancellationShieldPop:
299301
callVisitUse(op);
300302
continue;
301303
default:

lib/AST/Builtins.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2410,6 +2410,14 @@ static ValueDecl *getTaskLocalValuePop(ASTContext &ctx, Identifier id) {
24102410
return getBuiltinFunction(ctx, id, _thin, _parameters(), _void);
24112411
}
24122412

2413+
static ValueDecl *getTaskCancellationShieldPush(ASTContext &ctx, Identifier id) {
2414+
return getBuiltinFunction(ctx, id, _thin, _parameters(), _void);
2415+
}
2416+
2417+
static ValueDecl *getTaskCancellationShieldPop(ASTContext &ctx, Identifier id) {
2418+
return getBuiltinFunction(ctx, id, _thin, _parameters(), _void);
2419+
}
2420+
24132421
/// An array of the overloaded builtin kinds.
24142422
static const OverloadedBuiltinKind OverloadedBuiltinKinds[] = {
24152423
OverloadedBuiltinKind::None,
@@ -3516,6 +3524,12 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
35163524

35173525
case BuiltinValueKind::TaskLocalValuePop:
35183526
return getTaskLocalValuePop(Context, Id);
3527+
3528+
case BuiltinValueKind::TaskCancellationShieldPush:
3529+
return getTaskCancellationShieldPush(Context, Id);
3530+
3531+
case BuiltinValueKind::TaskCancellationShieldPop:
3532+
return getTaskCancellationShieldPop(Context, Id);
35193533
}
35203534

35213535
llvm_unreachable("bad builtin value!");

lib/IRGen/GenBuiltin.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,10 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
15871587
auto *valueMetatype = IGF.emitTypeMetadataRef(argTypes[1].getASTType());
15881588
return emitBuiltinTaskLocalValuePush(IGF, key, value, valueMetatype);
15891589
}
1590+
case BuiltinValueKind::TaskCancellationShieldPush:
1591+
return emitBuiltinTaskCancellationShieldPush(IGF);
1592+
case BuiltinValueKind::TaskCancellationShieldPop:
1593+
return emitBuiltinTaskCancellationShieldPop(IGF);
15901594

15911595
// Builtins without IRGen implementations.
15921596
case BuiltinValueKind::None:

lib/IRGen/GenConcurrency.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,24 @@ void irgen::emitBuiltinTaskLocalValuePop(IRGenFunction &IGF) {
368368
call->setCallingConv(IGF.IGM.SwiftCC);
369369
}
370370

371+
void irgen::emitBuiltinTaskCancellationShieldPush(IRGenFunction &IGF) {
372+
auto *call =
373+
IGF.Builder.CreateCall(IGF.IGM.getTaskCancellationShieldPushFunctionPointer(), {});
374+
call->setDoesNotThrow();
375+
call->setCallingConv(IGF.IGM.SwiftCC);
376+
// llvm::Value *identity =
377+
// IGF.Builder.CreatePtrToInt(executor, IGF.IGM.ExecutorFirstTy);
378+
379+
// out.add
380+
}
381+
382+
void irgen::emitBuiltinTaskCancellationShieldPop(IRGenFunction &IGF) {
383+
auto *call =
384+
IGF.Builder.CreateCall(IGF.IGM.getTaskCancellationShieldPopFunctionPointer(), {});
385+
call->setDoesNotThrow();
386+
call->setCallingConv(IGF.IGM.SwiftCC);
387+
}
388+
371389
void irgen::emitFinishAsyncLet(IRGenFunction &IGF,
372390
llvm::Value *asyncLet,
373391
llvm::Value *resultBuffer) {

lib/IRGen/GenConcurrency.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ void emitBuiltinTaskLocalValuePush(IRGenFunction &IGF, llvm::Value *key,
138138

139139
void emitBuiltinTaskLocalValuePop(IRGenFunction &IGF);
140140

141+
void emitBuiltinTaskCancellationShieldPush(IRGenFunction &IGF);
142+
143+
void emitBuiltinTaskCancellationShieldPop(IRGenFunction &IGF);
144+
141145
} // end namespace irgen
142146
} // end namespace swift
143147

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,9 @@ BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskRemovePriorityEscalationHandler)
10651065
// second is an address to our generic Value.
10661066
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskLocalValuePush)
10671067

1068+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskCancellationShieldPush)
1069+
BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskCancellationShieldPop)
1070+
10681071
#undef BUILTIN_OPERAND_OWNERSHIP
10691072

10701073
#define SHOULD_NEVER_VISIT_BUILTIN(ID) \
@@ -1076,6 +1079,8 @@ BUILTIN_OPERAND_OWNERSHIP(TrivialUse, TaskLocalValuePush)
10761079
SHOULD_NEVER_VISIT_BUILTIN(GetCurrentAsyncTask)
10771080
SHOULD_NEVER_VISIT_BUILTIN(GetCurrentExecutor)
10781081
SHOULD_NEVER_VISIT_BUILTIN(TaskLocalValuePop)
1082+
// SHOULD_NEVER_VISIT_BUILTIN(TaskCancellationShieldPush)
1083+
// SHOULD_NEVER_VISIT_BUILTIN(TaskCancellationShieldPop)
10791084
#undef SHOULD_NEVER_VISIT_BUILTIN
10801085

10811086
// Builtins that should be lowered to SIL instructions so we should never see

0 commit comments

Comments
 (0)