[Concurrency] TaskLocals lookup "skip" optimization

This commit is contained in:
Konrad `ktoso` Malawski
2021-01-07 15:21:54 +09:00
parent 1044723787
commit b811b12246
10 changed files with 309 additions and 133 deletions

View File

@@ -135,11 +135,7 @@ SWIFT_CC(swift)
static void destroyTask(SWIFT_CONTEXT HeapObject *obj) {
auto task = static_cast<AsyncTask*>(obj);
fprintf(stderr, "destroy task (%d): %d\n",
task->hasTaskLocalValues(), task);
// For a group, destroy the queues and results.
// For a group, destroy the queues and results.
if (task->isTaskGroup()) {
task->groupFragment()->destroy();
}
@@ -150,9 +146,7 @@ static void destroyTask(SWIFT_CONTEXT HeapObject *obj) {
}
// release any objects potentially held as task local values.
if (task->hasTaskLocalValues()) {
task->localValuesFragment()->destroy();
}
task->localValuesFragment()->destroy();
// The task execution itself should always hold a reference to it, so
// if we get here, we know the task has finished running, which means
@@ -242,15 +236,9 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
headerSize += sizeof(AsyncTask::ChildFragment);
}
bool needsTaskLocalsFragment =
flags.task_hasLocalValues() || (parent && parent->hasTaskLocalValues());
fprintf(stderr, "error: %s [%s:%d] prepare task taskHasTaskLocals=%d parentHasLocals=%d needsLocals=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
flags.task_hasLocalValues(), (parent && parent->hasTaskLocalValues()), needsTaskLocalsFragment);
if (needsTaskLocalsFragment) {
headerSize += sizeof(AsyncTask::TaskLocalValuesFragment);
fprintf(stderr, "error: %s [%s:%d] adding values fragment size=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
sizeof(AsyncTask::TaskLocalValuesFragment));
}
headerSize += sizeof(AsyncTask::TaskLocalValuesFragment);
fprintf(stderr, "error: %s [%s:%d] adding values fragment size=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
sizeof(AsyncTask::TaskLocalValuesFragment));
if (flags.task_isTaskGroup()) {
headerSize += sizeof(AsyncTask::GroupFragment);
@@ -287,12 +275,9 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
new (childFragment) AsyncTask::ChildFragment(parent);
}
if (needsTaskLocalsFragment) {
assert(task->hasTaskLocalValues());
auto taskLocalsFragment = task->localValuesFragment();
new (taskLocalsFragment) AsyncTask::TaskLocalValuesFragment();
taskLocalsFragment->initializeLinkParent(task, parent);
}
auto taskLocalsFragment = task->localValuesFragment();
new (taskLocalsFragment) AsyncTask::TaskLocalValuesFragment();
taskLocalsFragment->initializeLinkParent(task, parent);
// Initialize the task group fragment if applicable.
if (flags.task_isTaskGroup()) {
@@ -494,7 +479,6 @@ void swift::swift_task_runAndBlockThread(const void *function,
// Set up a task that runs the runAndBlock async function above.
auto flags = JobFlags(JobKind::Task, JobPriority::Default);
flags.task_setHasLocalValues(true);
auto pair = swift_task_create_f(flags,
/*parent*/ nullptr,
&runAndBlock_start,
@@ -515,27 +499,22 @@ size_t swift::swift_task_getJobFlags(AsyncTask *task) {
return task->Flags.getOpaqueValue();
}
void swift::swift_task_localValuePush(AsyncTask *task,
void swift::swift_task_local_value_push(AsyncTask *task,
const Metadata *keyType,
/* +1 */ OpaqueValue *value, const Metadata *valueType) {
fprintf(stderr, "error: %s [%s:%d] PUSH keyType=%d value=%d *value=%d\n",
__FUNCTION__, __FILE_NAME__, __LINE__,
keyType, value, *reinterpret_cast<int*>(value));
assert(task->hasTaskLocalValues());
task->localValuesFragment()->pushValue(task, keyType, value, valueType);
}
void swift::swift_task_localValuePop(AsyncTask *task, int count) {
assert(task->hasTaskLocalValues());
auto fragment = task->localValuesFragment();
for (int i = 0; i < count; i++) {
fprintf(stderr, "error: %s [%s:%d] POP task=%d %d / %d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
task, i, count);
fragment->popValue(task);
}
void swift::swift_task_local_value_pop(AsyncTask *task) {
fprintf(stderr, "error: %s [%s:%d] POP task=%d\n", __FUNCTION__, __FILE_NAME__, __LINE__,
task);
task->localValuesFragment()->popValue(task);
}
OpaqueValue* swift::swift_task_localValueGet(AsyncTask *task,
OpaqueValue* swift::swift_task_local_value_get(AsyncTask *task,
const Metadata *keyType) {
auto value = task->localValueGet(keyType);
fprintf(stderr, "error: %s [%s:%d] lookup keyType=%d value=%d\n",
@@ -544,10 +523,6 @@ OpaqueValue* swift::swift_task_localValueGet(AsyncTask *task,
return value;
}
bool swift::swift_task_hasTaskLocalValues(AsyncTask *task) {
return task->hasTaskLocalValues();
}
namespace {
/// Structure that gets filled in when a task is suspended by `withUnsafeContinuation`.