mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
115 lines
4.2 KiB
C++
115 lines
4.2 KiB
C++
//===--- TaskGroup.cpp - Task Group internal message channel ------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Object management for task local values.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/Runtime/Concurrency.h"
|
|
#include "swift/ABI/Task.h"
|
|
#include "swift/ABI/Metadata.h"
|
|
|
|
using namespace swift;
|
|
using TaskLocalValuesFragment = AsyncTask::TaskLocalValuesFragment;
|
|
|
|
// =============================================================================
|
|
// ==== destroy ----------------------------------------------------------------
|
|
|
|
void TaskLocalValuesFragment::destroy() {
|
|
auto item = head;
|
|
head = nullptr;
|
|
TaskLocalItem *next;
|
|
while (item) {
|
|
switch (item->getNextLinkType()) {
|
|
case TaskLocalValuesFragment::NextLinkType::IsNext:
|
|
next = item->getNext();
|
|
item->destroy();
|
|
fprintf(stderr, "FREE: %d\n", item);
|
|
free(item);
|
|
item = next;
|
|
break;
|
|
|
|
case TaskLocalValuesFragment::NextLinkType::IsParent:
|
|
case TaskLocalValuesFragment::NextLinkType::IsTerminal:
|
|
fprintf(stderr, "error: %s [%s:%d] done destroying [fragment:%d] type=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
|
|
this, item->getNextLinkType());
|
|
|
|
// we're done here, we must not destroy values owned by the parent task.
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// ==== Initialization ---------------------------------------------------------
|
|
|
|
void TaskLocalValuesFragment::initializeLinkParent(AsyncTask* task,
|
|
AsyncTask* parent) {
|
|
assert(!head && "fragment was already initialized");
|
|
if (parent) {
|
|
head = TaskLocalItem::createParentLink(task, parent);
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// ==== push / pop / get -------------------------------------------------------
|
|
|
|
void TaskLocalValuesFragment::pushValue(AsyncTask *task,
|
|
const Metadata *keyType,
|
|
/* +1 */ OpaqueValue *value,
|
|
const Metadata *valueType) {
|
|
assert(value && "Task local value must not be nil");
|
|
|
|
auto item = TaskLocalItem::createLink(task, keyType, valueType);
|
|
valueType->vw_initializeWithTake(item->getStoragePtr(), value);
|
|
|
|
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__,
|
|
task, item, item->getNext(), keyType, item->getStoragePtr());
|
|
|
|
head = item;
|
|
}
|
|
|
|
void TaskLocalValuesFragment::popValue(AsyncTask *task) {
|
|
assert(head && "attempted to pop value off empty task-local stack");
|
|
head->destroy();
|
|
head = head->getNext();
|
|
}
|
|
|
|
OpaqueValue *TaskLocalValuesFragment::get(const Metadata *keyType, const TaskLocalInheritance inherit) {
|
|
assert(keyType && "Task.Local key must not be null.");
|
|
|
|
auto item = head;
|
|
fprintf(stderr, "error: %s [%s:%d] get @ [%d] keyType %d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
|
|
item, keyType);
|
|
while (item) {
|
|
fprintf(stderr, "error: %s [%s:%d] loop, get; keyType=%d item=%d value=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
|
|
keyType, item, item->getStoragePtr());
|
|
if (item->keyType == keyType) {
|
|
return item->getStoragePtr();
|
|
}
|
|
|
|
// if the hey is an `inherit = .never` type, we stop our search the first
|
|
// time we would be jumping to a parent task to continue the search.
|
|
if (item->getNextLinkType() == NextLinkType::IsParent &&
|
|
inherit == TaskLocalInheritance::never)
|
|
return nullptr;
|
|
|
|
item = item->getNext();
|
|
}
|
|
|
|
fprintf(stderr, "error: %s [%s:%d] not found, get @ [%d] keyType %d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
|
|
item, keyType);
|
|
|
|
return nullptr;
|
|
}
|
|
|