Skip to content

Commit 73b6746

Browse files
committed
[Concurrency] Correct memory effect attributes of task_create
Without this, llvm would sometimes wrongly assume there's no indirect accesses and the optimizations can lead to a runtime crash, by optimizing away initializing options properly. Resolves rdar://152548190
1 parent 1484f1c commit 73b6746

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2376,7 +2376,7 @@ FUNCTION(TaskCreate,
23762376
RefCountedPtrTy),
23772377
ATTRS(NoUnwind),
23782378
EFFECT(RuntimeEffect::Concurrency),
2379-
MEMEFFECTS(ArgMemOnly))
2379+
MEMEFFECTS(ReadOnly))
23802380

23812381
// void swift_task_switch(AsyncContext *resumeContext,
23822382
// TaskContinuationFunction *resumeFunction,

stdlib/public/Concurrency/Task+immediate.swift.gyb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ extension Task where Failure == ${FAILURE_TYPE} {
7979
public static func immediate(
8080
name: String? = nil,
8181
priority: TaskPriority? = nil,
82-
% # NOTE: This closure cannot be 'sending' because we'll trigger ' pattern that the region based isolation checker does not understand how to check'
83-
% # In this case: `func syncOnMyGlobalActor() { Task.immediate { @MyGlobalActor in } }`
8482
@_implicitSelfCapture @_inheritActorContext(always) operation: sending @isolated(any) @escaping () async throws -> Success
8583
) -> Task<Success, ${FAILURE_TYPE}> {
8684

test/Concurrency/Runtime/startImmediately.swift

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -392,28 +392,6 @@ print("callActorFromStartSynchronousTask() - actor in custom executor with its o
392392
let actorQueue = DispatchQueue(label: "recipient-actor-queue")
393393
callActorFromStartSynchronousTask(recipient: .recipientOnQueue(RecipientOnQueue(queue: actorQueue)))
394394

395-
396-
// 50: callActorFromStartSynchronousTask()
397-
// 51: before immediate [thread:0x00007000054f5000] @ :366
398-
// 52: inside immediate [thread:0x00007000054f5000] @ :372
399-
// 53: inside immediate, call rec.sync() [thread:0x00007000054f5000] @ :380
400-
// 54: Recipient/sync(syncTaskThreadID:) Current actor thread id = 0x000070000567e000 @ :336
401-
// 55: inside immediate, call rec.sync() done [thread:0x000070000567e000] @ :385
402-
// 56: Inner thread id = 0x00007000054f5000
403-
// 57: Current thread id = 0x000070000567e000
404-
// 60: after immediate [thread:0x00007000054f5000] @ :418
405-
// 61: - async work on queue
406-
// 62: - async work on queue
407-
// 63: - async work on queue
408-
// 64: - async work on queue
409-
// 65: - async work on queue
410-
// 67: - async work on queue
411-
// 68: - async work on queue
412-
// 69: - async work on queue
413-
// 71: Inner thread id = 0x00007000054f5000
414-
// 72: Current thread id = 0x000070000567e000
415-
// 73: inside immediate, done [thread:0x000070000567e000] @ :414
416-
417395
// CHECK-LABEL: callActorFromStartSynchronousTask() - actor in custom executor with its own queue
418396
// No interleaving allowed between "before" and "inside":
419397
// CHECK: before immediate [thread:[[CALLING_THREAD4:.*]]]
@@ -452,3 +430,36 @@ actor RecipientOnQueue: RecipientProtocol {
452430
try? await Task.sleep(for: .milliseconds(100))
453431
}
454432
}
433+
434+
print("\n\n==== ------------------------------------------------------------------")
435+
print("call_startSynchronously_insideActor()")
436+
437+
actor A {
438+
func f() {
439+
Task.startSynchronously() {
440+
print("Task.startSynchronously")
441+
}
442+
}
443+
444+
func f2() {
445+
Task.immediate() {
446+
print("Task.immediate")
447+
}
448+
449+
Task.immediate() { @MainActor in
450+
print("Task.immediate { @MainActor }")
451+
}
452+
}
453+
}
454+
455+
func call_startSynchronously_insideActor() async {
456+
await A().f()
457+
await A().f2()
458+
}
459+
460+
await call_startSynchronously_insideActor()
461+
462+
// CHECK-LABEL: call_startSynchronously_insideActor()
463+
// Those two definitely in this order, however the startSynchronously is not determinate
464+
// CHECK: Task.immediate
465+
// CHECK: Task.immediate { @MainActor }

0 commit comments

Comments
 (0)