Skip to content

Commit 3b4b1c3

Browse files
authored
Merge pull request swiftlang#34842 from DougGregor/worlds-slowest-fibonacci
2 parents 7bb9aa7 + fd8097c commit 3b4b1c3

File tree

8 files changed

+99
-13
lines changed

8 files changed

+99
-13
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ bool swift_task_removeStatusRecord(AsyncTask *task,
174174
TaskStatusRecord *record);
175175

176176
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
177-
JobPriority
178-
swift_task_getPriority(AsyncTask* task);
177+
JobFlags
178+
swift_task_getJobFlags(AsyncTask* task);
179179

180180
/// This should have the same representation as an enum like this:
181181
/// enum NearestTaskDeadline {

lib/IRGen/IRGenFunction.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,6 @@ Address IRGenFunction::emitTaskAlloc(llvm::Value *size, Alignment alignment) {
495495
auto *call = Builder.CreateCall(IGM.getTaskAllocFn(), {getAsyncTask(), size});
496496
call->setDoesNotThrow();
497497
call->setCallingConv(IGM.SwiftCC);
498-
call->addAttribute(llvm::AttributeList::FunctionIndex,
499-
llvm::Attribute::ReadNone);
500498
auto address = Address(call, alignment);
501499
return address;
502500
}

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, PoundAssert)
541541
CONSTANT_OWNERSHIP_BUILTIN(None, TypePtrAuthDiscriminator)
542542
CONSTANT_OWNERSHIP_BUILTIN(None, IntInstrprofIncrement)
543543
CONSTANT_OWNERSHIP_BUILTIN(None, GlobalStringTablePointer)
544-
CONSTANT_OWNERSHIP_BUILTIN(Owned, GetCurrentAsyncTask)
544+
CONSTANT_OWNERSHIP_BUILTIN(None, GetCurrentAsyncTask)
545545
CONSTANT_OWNERSHIP_BUILTIN(None, CancelAsyncTask)
546546
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTask)
547547
CONSTANT_OWNERSHIP_BUILTIN(Owned, CreateAsyncTaskFuture)

stdlib/public/Concurrency/Task.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,6 @@ void swift::swift_task_run(AsyncTask *taskToRun) {
352352
taskToRun->run(ExecutorRef::noPreference());
353353
}
354354

355-
JobPriority swift::swift_task_getPriority(AsyncTask *task) {
356-
return task->getPriority();
355+
JobFlags swift::swift_task_getJobFlags(AsyncTask *task) {
356+
return task->Flags;
357357
}

stdlib/public/Concurrency/Task.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ extension Task {
4444
/// This function returns instantly and will never suspend.
4545
/* @instantaneous */
4646
public static func currentPriority() async -> Priority {
47-
let task = Builtin.getCurrentAsyncTask()
48-
return getPriority(task)
47+
let flags = getJobFlags(Builtin.getCurrentAsyncTask())
48+
return flags.priority
4949
}
5050

5151
/// Task priority may inform decisions an `Executor` makes about how and when
@@ -416,8 +416,8 @@ extension Task {
416416
@_silgen_name("swift_task_run")
417417
public func runTask(_ task: __owned Builtin.NativeObject)
418418

419-
@_silgen_name("swift_task_getPriority")
420-
public func getPriority(_ task: __owned Builtin.NativeObject) -> Task.Priority
419+
@_silgen_name("swift_task_getJobFlags")
420+
func getJobFlags(_ task: Builtin.NativeObject) -> Task.JobFlags
421421

422422
public func runAsync(_ asyncFun: @escaping () async -> ()) {
423423
let childTask = Builtin.createAsyncTask(0, nil, asyncFun)

test/Concurrency/Runtime/async_task_priority_basic.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ extension DispatchQueue {
2525
func test_getPriority() {
2626
_ = DispatchQueue.main.async { () async in
2727
let p = await Task.currentPriority()
28-
// CHECK: priority: userInteractive
28+
// CHECK: priority: default
2929
print("priority: \(p)")
30-
assert(p == Task.Priority.userInteractive)
30+
assert(p == Task.Priority.default)
3131
exit(0)
3232
}
3333
}

test/Concurrency/Runtime/basic_future.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// REQUIRES: executable_test
44
// REQUIRES: concurrency
55
// REQUIRES: OS=macosx
6+
// XFAIL: CPU=arm64e
67

78
import Dispatch
89

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency)
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: concurrency
5+
// REQUIRES: OS=macosx
6+
// XFAIL: CPU=arm64e
7+
8+
import Dispatch
9+
10+
extension DispatchQueue {
11+
func async<R>(execute: @escaping () async throws -> R) -> Task.Handle<R> {
12+
let handle = Task.runDetached(operation: execute)
13+
14+
// Run the task
15+
_ = { self.async { handle.run() } }()
16+
17+
return handle
18+
}
19+
20+
func async<R>(in group: DispatchGroup,
21+
execute: @escaping () async throws -> R) -> Task.Handle<R> {
22+
let handle = Task.runDetached(operation: execute)
23+
24+
// Run the task
25+
group.enter()
26+
_ = {
27+
self.async {
28+
handle.run()
29+
group.leave()
30+
}
31+
}()
32+
33+
return handle
34+
}
35+
}
36+
37+
func fib(_ n: Int) -> Int {
38+
var first = 0
39+
var second = 1
40+
for _ in 0..<n {
41+
let temp = first
42+
first = second
43+
second = temp + first
44+
}
45+
return first
46+
}
47+
48+
func asyncFib(_ n: Int, group: DispatchGroup, queue: DispatchQueue) async -> Int {
49+
if n == 0 || n == 1 {
50+
return n
51+
}
52+
53+
let first = queue.async(in: group) {
54+
await asyncFib(n - 2, group: group, queue: queue)
55+
}
56+
57+
let second = queue.async(in: group) {
58+
await asyncFib(n - 1, group: group, queue: queue)
59+
}
60+
61+
// Sleep a random amount of time waiting on the result producing a result.
62+
usleep(UInt32.random(in: 0..<100) * 1000)
63+
64+
let result = await try! first.get() + second.get()
65+
66+
// Sleep a random amount of time before producing a result.
67+
usleep(UInt32.random(in: 0..<100) * 1000)
68+
69+
return result
70+
}
71+
72+
func runFibonacci(_ n: Int) {
73+
let queue = DispatchQueue(label: "concurrent", attributes: .concurrent)
74+
let group = DispatchGroup()
75+
76+
var result = 0
77+
_ = queue.async(in: group) {
78+
result = await asyncFib(n, group: group, queue: queue)
79+
}
80+
group.wait()
81+
82+
print()
83+
print("Async fib = \(result), sequential fib = \(fib(n))")
84+
assert(result == fib(n))
85+
}
86+
87+
runFibonacci(15)

0 commit comments

Comments
 (0)