Skip to content

Commit d2bd6ab

Browse files
committed
[Concurrency] TaskLocals allow configuring inheritance: never
1 parent b811b12 commit d2bd6ab

File tree

13 files changed

+168
-316
lines changed

13 files changed

+168
-316
lines changed

include/swift/ABI/Task.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ class AsyncTask : public HeapObject, public Job {
241241
IsParent = 0b11
242242
};
243243

244+
/// Values must match `TaskLocalInheritance` declared in `TaskLocal.swift`.
245+
enum class TaskLocalInheritance : uint8_t {
246+
Default = 0,
247+
Never = 1
248+
};
249+
244250
class TaskLocalItem {
245251
private:
246252
/// Mask used for the low status bits in a task local chain item.
@@ -325,7 +331,6 @@ class AsyncTask : public HeapObject, public Job {
325331
size_t amountToAllocate = TaskLocalItem::itemSize(valueType);
326332
// assert(amountToAllocate % MaximumAlignment == 0); // TODO: do we need this?
327333
void *allocation = malloc(amountToAllocate); // TODO: use task-local allocator
328-
fprintf(stderr, "MALLOC link item: %d\n", allocation);
329334
TaskLocalItem *item =
330335
new(allocation) TaskLocalItem(keyType, valueType);
331336

@@ -430,7 +435,7 @@ class AsyncTask : public HeapObject, public Job {
430435

431436
void popValue(AsyncTask *task);
432437

433-
OpaqueValue* get(const Metadata *keyType);
438+
OpaqueValue* get(const Metadata *keType, TaskLocalInheritance inheritance);
434439
};
435440

436441
TaskLocalValuesFragment *localValuesFragment() {
@@ -444,8 +449,9 @@ class AsyncTask : public HeapObject, public Job {
444449
return reinterpret_cast<TaskLocalValuesFragment*>(offset);
445450
}
446451

447-
OpaqueValue* localValueGet(const Metadata *keyType) {
448-
return localValuesFragment()->get(keyType);
452+
OpaqueValue* localValueGet(const Metadata *keyType,
453+
TaskLocalValuesFragment::TaskLocalInheritance inheritance) {
454+
return localValuesFragment()->get(keyType, inheritance);
449455
}
450456

451457
// ==== TaskGroup ------------------------------------------------------------

include/swift/Runtime/Concurrency.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#define SWIFT_RUNTIME_CONCURRENCY_H
1919

2020
#include "swift/ABI/TaskStatus.h"
21-
#include "swift/Runtime/ExistentialContainer.h"
2221

2322
namespace swift {
2423
class DefaultActor;
@@ -226,17 +225,21 @@ size_t swift_task_getJobFlags(AsyncTask* task);
226225
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
227226
bool swift_task_isCancelled(AsyncTask* task);
228227

228+
using TaskLocalValuesFragment = AsyncTask::TaskLocalValuesFragment;
229+
229230
/// Get a task local value from the passed in task. Its Swift signature is
230231
///
231232
/// \code
232233
/// func _taskLocalValueGet<Key>(
233234
/// _ task: Builtin.NativeObject,
234-
/// keyType: Any.Type /*Key.Type*/
235+
/// keyType: Any.Type /*Key.Type*/,
236+
/// inheritance: UInt8/*TaskLocalInheritance*/
235237
/// ) -> UnsafeMutableRawPointer? where Key: TaskLocalKey
236238
/// \endcode
237239
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
238240
OpaqueValue* swift_task_localValueGet(AsyncTask* task,
239-
const Metadata *keyType);
241+
const Metadata *keyType,
242+
TaskLocalValuesFragment::TaskLocalInheritance inheritance);
240243

241244
/// Add a task local value to the passed in task.
242245
///

stdlib/public/Concurrency/Task.cpp

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
using namespace swift;
3333
using FutureFragment = AsyncTask::FutureFragment;
3434
using GroupFragment = AsyncTask::GroupFragment;
35+
using TaskLocalValuesFragment = AsyncTask::TaskLocalValuesFragment;
36+
using TaskLocalInheritance = AsyncTask::TaskLocalValuesFragment::TaskLocalInheritance;
3537

3638
void FutureFragment::destroy() {
3739
auto queueHead = waitQueue.load(std::memory_order_acquire);
@@ -237,8 +239,6 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
237239
}
238240

239241
headerSize += sizeof(AsyncTask::TaskLocalValuesFragment);
240-
fprintf(stderr, "error: %s [%s:%d] adding values fragment size=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
241-
sizeof(AsyncTask::TaskLocalValuesFragment));
242242

243243
if (flags.task_isTaskGroup()) {
244244
headerSize += sizeof(AsyncTask::GroupFragment);
@@ -311,13 +311,9 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
311311
initialContext->Flags.setShouldNotDeallocateInCallee(true);
312312

313313
// Initialize the task-local allocator.
314-
// TODO: consider providing an initial pre-allocated first slab to the
315-
// allocator.
314+
// TODO: consider providing an initial pre-allocated first slab to the allocator.
316315
_swift_task_alloc_initialize(task);
317316

318-
fprintf(stderr, "error: %s [%s:%d] prepared task=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
319-
task);
320-
321317
return {task, initialContext};
322318
}
323319

@@ -499,28 +495,21 @@ size_t swift::swift_task_getJobFlags(AsyncTask *task) {
499495
return task->Flags.getOpaqueValue();
500496
}
501497

502-
void swift::swift_task_local_value_push(AsyncTask *task,
503-
const Metadata *keyType,
504-
/* +1 */ OpaqueValue *value, const Metadata *valueType) {
505-
fprintf(stderr, "error: %s [%s:%d] PUSH keyType=%d value=%d *value=%d\n",
506-
__FUNCTION__, __FILE_NAME__, __LINE__,
507-
keyType, value, *reinterpret_cast<int*>(value));
498+
void swift::swift_task_localValuePush(AsyncTask *task,
499+
const Metadata *keyType,
500+
/* +1 */ OpaqueValue *value,
501+
const Metadata *valueType) {
508502
task->localValuesFragment()->pushValue(task, keyType, value, valueType);
509503
}
510504

511-
void swift::swift_task_local_value_pop(AsyncTask *task) {
512-
fprintf(stderr, "error: %s [%s:%d] POP task=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
513-
task);
505+
void swift::swift_task_localValuePop(AsyncTask *task) {
514506
task->localValuesFragment()->popValue(task);
515507
}
516508

517-
OpaqueValue* swift::swift_task_local_value_get(AsyncTask *task,
518-
const Metadata *keyType) {
519-
auto value = task->localValueGet(keyType);
520-
fprintf(stderr, "error: %s [%s:%d] lookup keyType=%d value=%d\n",
521-
__FUNCTION__, __FILE_NAME__, __LINE__,
522-
keyType, value);
523-
return value;
509+
OpaqueValue* swift::swift_task_localValueGet(AsyncTask *task,
510+
const Metadata *keyType,
511+
TaskLocalInheritance inheritance) {
512+
return task->localValueGet(keyType, inheritance);
524513
}
525514

526515
namespace {

stdlib/public/Concurrency/Task.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@
1212

1313
import Swift
1414
@_implementationOnly import _SwiftConcurrencyShims
15-
#if canImport(Darwin)
16-
import Darwin
17-
#elseif canImport(Glibc)
18-
import Glibc
19-
#elseif os(Windows)
20-
import CRT
21-
#else
22-
#error("Unsupported platform")
23-
#endif
24-
2515

2616
// ==== Task -------------------------------------------------------------------
2717

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- TaskGroup.cpp - Task Group internal message channel ------------===//
1+
//===--- TaskGroup.cpp - Task Groups --------------------------------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// Object management for async child tasks that are children of a task group.
13+
// Object management for child tasks that are children of a task group.
1414
//
1515
//===----------------------------------------------------------------------===//
1616

stdlib/public/Concurrency/TaskLocal.cpp

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- TaskGroup.cpp - Task Group internal message channel ------------===//
1+
//===--- TaskLocal.cpp - Task Local Values --------------------------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -9,10 +9,6 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
//
13-
// Object management for task local values.
14-
//
15-
//===----------------------------------------------------------------------===//
1612

1713
#include "swift/Runtime/Concurrency.h"
1814
#include "swift/ABI/Task.h"
@@ -33,16 +29,12 @@ void TaskLocalValuesFragment::destroy() {
3329
case TaskLocalValuesFragment::NextLinkType::IsNext:
3430
next = item->getNext();
3531
item->destroy();
36-
fprintf(stderr, "FREE: %d\n", item);
3732
free(item);
3833
item = next;
3934
break;
4035

4136
case TaskLocalValuesFragment::NextLinkType::IsParent:
4237
case TaskLocalValuesFragment::NextLinkType::IsTerminal:
43-
fprintf(stderr, "error: %s [%s:%d] done destroying [fragment:%d] type=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
44-
this, item->getNextLinkType());
45-
4638
// we're done here, we must not destroy values owned by the parent task.
4739
return;
4840
}
@@ -71,10 +63,6 @@ void TaskLocalValuesFragment::pushValue(AsyncTask *task,
7163

7264
auto item = TaskLocalItem::createLink(task, keyType, valueType);
7365
valueType->vw_initializeWithTake(item->getStoragePtr(), value);
74-
75-
fprintf(stderr, "error: %s [%s:%d] PUSH bound item: task=%d item=%d -> item.next=%d keyType=%d item->getStoragePtr=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
76-
task, item, item->getNext(), keyType, item->getStoragePtr());
77-
7866
head = item;
7967
}
8068

@@ -84,31 +72,26 @@ void TaskLocalValuesFragment::popValue(AsyncTask *task) {
8472
head = head->getNext();
8573
}
8674

87-
OpaqueValue *TaskLocalValuesFragment::get(const Metadata *keyType, const TaskLocalInheritance inherit) {
75+
OpaqueValue *TaskLocalValuesFragment::get(
76+
const Metadata *keyType,
77+
const TaskLocalInheritance inherit) {
8878
assert(keyType && "Task.Local key must not be null.");
8979

9080
auto item = head;
91-
fprintf(stderr, "error: %s [%s:%d] get @ [%d] keyType %d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
92-
item, keyType);
9381
while (item) {
94-
fprintf(stderr, "error: %s [%s:%d] loop, get; keyType=%d item=%d value=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
95-
keyType, item, item->getStoragePtr());
9682
if (item->keyType == keyType) {
9783
return item->getStoragePtr();
9884
}
9985

100-
// if the hey is an `inherit = .never` type, we stop our search the first
86+
// if the key is an `inherit = .never` type, we stop our search the first
10187
// time we would be jumping to a parent task to continue the search.
10288
if (item->getNextLinkType() == NextLinkType::IsParent &&
103-
inherit == TaskLocalInheritance::never)
89+
inherit == TaskLocalInheritance::Never)
10490
return nullptr;
10591

10692
item = item->getNext();
10793
}
10894

109-
fprintf(stderr, "error: %s [%s:%d] not found, get @ [%d] keyType %d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
110-
item, keyType);
111-
11295
return nullptr;
11396
}
11497

stdlib/public/Concurrency/TaskLocal.swift

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,6 @@
1313
import Swift
1414
@_implementationOnly import _SwiftConcurrencyShims
1515

16-
#if canImport(Darwin)
17-
import Darwin
18-
#elseif canImport(Glibc)
19-
import Glibc
20-
#elseif os(Windows)
21-
import CRT
22-
#else
23-
#error("Unsupported platform")
24-
#endif
25-
2616
/// Namespace for declaring `TaskLocalKey`s.
2717
public enum TaskLocalValues {}
2818

@@ -54,12 +44,12 @@ public protocol TaskLocalKey {
5444
}
5545

5646
extension TaskLocalKey {
57-
static var inherit: TaskLocalInheritance { .default }
47+
public static var inherit: TaskLocalInheritance { .default }
5848
}
5949

60-
///
50+
/// Determines task local value behavior in child tasks.
6151
// TODO: should likely remain extensible
62-
public enum TaskLocalInheritance: Int {
52+
public enum TaskLocalInheritance: UInt8, Equatable {
6353
/// The default inheritance strategy.
6454
///
6555
/// Task local values whose keys are `default` inherited are available to the
@@ -83,7 +73,8 @@ extension Task {
8373
async -> Key.Value where Key: TaskLocalKey {
8474
let task = Builtin.getCurrentAsyncTask()
8575

86-
guard let rawValue = _taskLocalValueGet(task, keyType: Key.self) else {
76+
let value = _taskLocalValueGet(task, keyType: Key.self, inheritance: Key.inherit.rawValue)
77+
guard let rawValue = value else {
8778
return Key.defaultValue
8879
}
8980

@@ -108,7 +99,6 @@ extension Task {
10899
) async -> BodyResult where Key: TaskLocalKey {
109100
let task = Builtin.getCurrentAsyncTask()
110101

111-
// fputs("error [Task.swift:\(#line)]: setting DONE keyType=\(Key.self), value=\(value)\n", stderr)
112102
_taskLocalValuePush(task, keyType: Key.self, value: value)
113103

114104
defer {
@@ -133,7 +123,6 @@ extension Task {
133123
) async throws -> BodyResult where Key: TaskLocalKey {
134124
let task = Builtin.getCurrentAsyncTask()
135125

136-
// fputs("error [Task.swift:\(#line)]: setting DONE keyType=\(Key.self), value=\(value)\n", stderr)
137126
_taskLocalValuePush(task, keyType: Key.self, value: value)
138127

139128
defer {
@@ -169,20 +158,21 @@ extension AnyTaskLocalKey: Hashable {
169158

170159
// ==== ------------------------------------------------------------------------
171160

172-
@_silgen_name("swift_task_local_value_push")
161+
@_silgen_name("swift_task_localValuePush")
173162
public func _taskLocalValuePush<Value>(
174163
_ task: Builtin.NativeObject,
175164
keyType: Any.Type/*Key.Type*/,
176165
value: __owned Value
177166
) // where Key: TaskLocalKey
178167

179-
@_silgen_name("swift_task_local_value_pop")
168+
@_silgen_name("swift_task_localValuePop")
180169
public func _taskLocalValuePop(
181170
_ task: Builtin.NativeObject
182171
)
183172

184-
@_silgen_name("swift_task_local_value_get")
173+
@_silgen_name("swift_task_localValueGet")
185174
public func _taskLocalValueGet(
186175
_ task: Builtin.NativeObject,
187-
keyType: Any.Type/*Key.Type*/
176+
keyType: Any.Type/*Key.Type*/,
177+
inheritance: UInt8/*TaskLocalInheritance*/
188178
) -> UnsafeMutableRawPointer? // where Key: TaskLocalKey

0 commit comments

Comments
 (0)