Skip to content

Commit 58ea749

Browse files
committed
[TaskLocal] Crash on inapropriate use within task group
1 parent 3d96d05 commit 58ea749

File tree

8 files changed

+148
-164
lines changed

8 files changed

+148
-164
lines changed

include/swift/ABI/MetadataKind.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ METADATAKIND(Task,
9393
METADATAKIND(Job,
9494
3 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate)
9595

96-
/// A heap-allocated task-local value `TaskLocal::Item`.
97-
METADATAKIND(TaskLocalHeapItem,
98-
4 | MetadataKindIsNonType | MetadataKindIsRuntimePrivate)
99-
10096
// getEnumeratedMetadataKind assumes that all the enumerated values here
10197
// will be <= LastEnumeratedMetadataKind.
10298

include/swift/ABI/TaskLocal.h

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ struct SwiftError;
2828
class TaskStatusRecord;
2929
class TaskGroup;
3030

31-
extern FullMetadata<HeapMetadata> taskLocalHeapItemHeapMetadata;
32-
3331
// ==== Task Locals Values ---------------------------------------------------
3432

3533
class TaskLocal {
@@ -46,9 +44,6 @@ class TaskLocal {
4644
/// lookups by skipping empty parent tasks during get(), and explained
4745
/// in depth in `createParentLink`.
4846
IsParent = 0b01,
49-
50-
/// The next item is "unstructured" and must be ref-counted.
51-
ThisItemIsHeapItem = 0b10
5247
};
5348

5449
/// Values must match `TaskLocalInheritance` declared in `TaskLocal.swift`.
@@ -133,10 +128,6 @@ class TaskLocal {
133128
return static_cast<NextLinkType>(next & statusMask);
134129
}
135130

136-
bool isHeapItem() const {
137-
return getNextLinkType() == NextLinkType::ThisItemIsHeapItem;
138-
}
139-
140131
/// Item does not contain any actual value, and is only used to point at
141132
/// a specific parent item.
142133
bool isEmpty() const {
@@ -147,14 +138,13 @@ class TaskLocal {
147138
OpaqueValue *getStoragePtr() {
148139
fprintf(stderr, "[%s:%d] (%s) GET STORAGE\n", __FILE__, __LINE__, __FUNCTION__);
149140
return reinterpret_cast<OpaqueValue *>(
150-
reinterpret_cast<char *>(this) + storageOffset(isHeapItem(), valueType));
141+
reinterpret_cast<char *>(this) + storageOffset(valueType));
151142
}
152143

153144
/// Compute the offset of the storage from the base of the item.
154-
static size_t storageOffset(bool isHeapItem, const Metadata *valueType) {
145+
static size_t storageOffset(const Metadata *valueType) {
155146
size_t offset = sizeof(Item);
156147

157-
158148
if (valueType) {
159149
size_t alignment = valueType->vw_alignment();
160150
return (offset + alignment - 1) & ~(alignment - 1);
@@ -164,54 +154,15 @@ class TaskLocal {
164154
}
165155

166156
/// Determine the size of the item given a particular value type.
167-
static size_t itemSize(bool isHeapItem, const Metadata *valueType) {
168-
size_t offset = storageOffset(isHeapItem, valueType);
169-
size_t headerSize = isHeapItem ? sizeof(HeapObject) : 0;
170-
offset += headerSize;
157+
static size_t itemSize(const Metadata *valueType) {
158+
size_t offset = storageOffset(valueType);
171159
if (valueType) {
172160
offset += valueType->vw_size();
173161
}
174162
return offset;
175163
}
176164
};
177165

178-
/// Heap allocated version of TaskLocal::Item.
179-
/// It is used in limited un-structured concurrency cases, where the task
180-
/// local must be stored on the heap for the time being.
181-
///
182-
/// MUST HAVE THE SAME LAYOUT AS TaskLocal::Item.
183-
/// FIXME: how to actually make this work...
184-
/// get the address of "after heap object" and cast that to Item?
185-
class HeapItem : public HeapObject, public Item {
186-
public:
187-
188-
explicit HeapItem(const HeapMetadata *metadata = &taskLocalHeapItemHeapMetadata)
189-
: HeapObject(metadata),
190-
Item() {}
191-
192-
explicit HeapItem(const HeapObject *key, const Metadata *valueType)
193-
: HeapItem(&taskLocalHeapItemHeapMetadata, key, valueType) {}
194-
195-
explicit HeapItem(const HeapMetadata *metadata,
196-
const HeapObject *key, const Metadata *valueType)
197-
: HeapObject(metadata),
198-
Item(key, valueType) {}
199-
200-
201-
/// Retrieve a pointer to the `Item` that is part of this object.
202-
TaskLocal::Item *getItem() {
203-
fprintf(stderr, "[%s:%d] (%s) GET ITEM PTR, heapItem:%p\n", __FILE__, __LINE__, __FUNCTION__, this);
204-
return reinterpret_cast<TaskLocal::Item *>(
205-
reinterpret_cast<char *>(this) + itemOffset());
206-
}
207-
208-
/// Compute the offset of `Item` part of this object.
209-
static size_t itemOffset() {
210-
size_t offset = sizeof(HeapObject);
211-
return offset;
212-
}
213-
};
214-
215166
class Storage {
216167
friend class TaskLocal::Item;
217168
private:

include/swift/Runtime/Concurrency.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,19 @@ void swift_asyncLet_wait_throwing(OpaqueValue *,
333333
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
334334
void swift_asyncLet_end(AsyncLet *alet);
335335

336+
/// Returns true if the currently executing AsyncTask has a
337+
/// 'TaskGroupTaskStatusRecord' present.
338+
///
339+
/// This can be called from any thread.
340+
///
341+
/// Its Swift signature is
342+
///
343+
/// \code
344+
/// func swift_taskGroup_hasTaskGroupRecord()
345+
/// \endcode
346+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
347+
bool swift_taskGroup_hasTaskGroupRecord();
348+
336349
/// Add a status record to a task. The record should not be
337350
/// modified while it is registered with a task.
338351
///
@@ -406,6 +419,12 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
406419
void swift_task_removeCancellationHandler(
407420
CancellationNotificationStatusRecord *record);
408421

422+
/// Report error about attempting to bind a task-local value from an illegal context.
423+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
424+
void swift_task_reportIllegalTaskLocalBindingWithinWithTaskGroup(
425+
const unsigned char *file, uintptr_t fileLength,
426+
bool fileIsASCII, uintptr_t line);
427+
409428
/// Get a task local value from the passed in task. Its Swift signature is
410429
///
411430
/// \code

stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ OVERRIDE_TASK_GROUP(taskGroup_addPending, bool,
218218
swift::, (TaskGroup *group, bool unconditionally),
219219
(group, unconditionally))
220220

221+
222+
OVERRIDE_TASK_LOCAL(task_reportIllegalTaskLocalBindingWithinWithTaskGroup, void,
223+
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
224+
(const unsigned char *file, uintptr_t fileLength,
225+
bool fileIsASCII, uintptr_t line),
226+
(file, fileLength, fileIsASCII, line))
227+
221228
OVERRIDE_TASK_LOCAL(task_localValuePush, void,
222229
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
223230
swift::,

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,10 @@ func _taskGroupIsCancelled(group: Builtin.RawPointer) -> Bool
817817
@_silgen_name("swift_taskGroup_wait_next_throwing")
818818
func _taskGroupWaitNext<T>(group: Builtin.RawPointer) async throws -> T?
819819

820+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
821+
@_silgen_name("swift_task_hasTaskGroupStatusRecord")
822+
func _taskHasTaskGroupStatusRecord() -> Bool
823+
820824
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
821825
enum PollStatus: Int {
822826
case empty = 0

stdlib/public/Concurrency/TaskGroupPrivate.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@
2222

2323
namespace swift {
2424

25-
//void _swift_taskgroup_offer(AsyncTask *completed,
26-
// AsyncContext *context,
27-
// ExecutorRef executor);
28-
//
29-
//void _swift_taskgroup_cancelAll(AsyncTask *completed,
30-
// TaskGroup *group);
31-
3225
} // end namespace swift
3326

3427
#endif

0 commit comments

Comments
 (0)