mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This commit changes JobFlags storage to be 32bits, but leaves the runtime API expressed in terms of size_t. This allows us to pack an Id in the 32bits we freed up. The offset of this Id in the AsyncTask is an ABI constant. This way introspection tools can extract the currently running task identifier without any need for special APIs.
178 lines
5.7 KiB
C++
178 lines
5.7 KiB
C++
//===--- TaskPrivate.h - Concurrency library internal interface -*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Internal functions for the concurrency library.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_CONCURRENCY_TASKPRIVATE_H
|
|
#define SWIFT_CONCURRENCY_TASKPRIVATE_H
|
|
|
|
#include "swift/Runtime/Concurrency.h"
|
|
#include "swift/ABI/Task.h"
|
|
#include "swift/ABI/Metadata.h"
|
|
#include "swift/Runtime/HeapObject.h"
|
|
#include "swift/Runtime/Error.h"
|
|
|
|
namespace swift {
|
|
|
|
// Uncomment to enable helpful debug spew to stderr
|
|
//#define SWIFT_TASK_PRINTF_DEBUG 1
|
|
|
|
class AsyncTask;
|
|
class TaskGroup;
|
|
|
|
/// Initialize the task-local allocator in the given task.
|
|
void _swift_task_alloc_initialize(AsyncTask *task);
|
|
|
|
void _swift_task_alloc_initialize_with_slab(AsyncTask *task,
|
|
void *firstSlabBuffer,
|
|
size_t bufferCapacity);
|
|
|
|
/// Destroy the task-local allocator in the given task.
|
|
void _swift_task_alloc_destroy(AsyncTask *task);
|
|
|
|
/// Allocate task-local memory on behalf of a specific task,
|
|
/// not necessarily the current one. Generally this should only be
|
|
/// done on behalf of a child task.
|
|
void *_swift_task_alloc_specific(AsyncTask *task, size_t size);
|
|
|
|
/// dellocate task-local memory on behalf of a specific task,
|
|
/// not necessarily the current one. Generally this should only be
|
|
/// done on behalf of a child task.
|
|
void _swift_task_dealloc_specific(AsyncTask *task, void *ptr);
|
|
|
|
/// Given that we've already set the right executor as the active
|
|
/// executor, run the given job. This does additional bookkeeping
|
|
/// related to the active task.
|
|
void runJobInEstablishedExecutorContext(Job *job);
|
|
|
|
/// Clear the active task reference for the current thread.
|
|
AsyncTask *_swift_task_clearCurrent();
|
|
|
|
AsyncTaskAndContext swift_task_create_async_let_future(size_t flags,
|
|
const Metadata *futureResultType,
|
|
void *closureEntry,
|
|
void *closureContext);
|
|
|
|
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
|
|
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 1
|
|
#else
|
|
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 0
|
|
#endif
|
|
|
|
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
|
|
/// Donate this thread to the global executor until either the
|
|
/// given condition returns true or we've run out of cooperative
|
|
/// tasks to run.
|
|
void donateThreadToGlobalExecutorUntil(bool (*condition)(void*),
|
|
void *context);
|
|
#endif
|
|
|
|
/// release() establishes a happens-before relation with a preceding acquire()
|
|
/// on the same address.
|
|
void _swift_tsan_acquire(void *addr);
|
|
void _swift_tsan_release(void *addr);
|
|
|
|
/// Special values used with DispatchQueueIndex to indicate the global and main
|
|
/// executors.
|
|
#define DISPATCH_QUEUE_GLOBAL_EXECUTOR (void *)1
|
|
#define DISPATCH_QUEUE_MAIN_EXECUTOR (void *)2
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
|
// FIXME: remove this and switch to a representation that uses
|
|
// _dispatch_main_q somehow
|
|
extern "C" SWIFT_CC(swift)
|
|
ExecutorRef _swift_task_getMainExecutor();
|
|
#pragma clang diagnostic pop
|
|
|
|
// ==== ------------------------------------------------------------------------
|
|
|
|
namespace {
|
|
|
|
/// The layout of a context to call one of the following functions:
|
|
///
|
|
/// @_silgen_name("swift_task_future_wait")
|
|
/// func _taskFutureGet<T>(_ task: Builtin.NativeObject) async -> T
|
|
///
|
|
/// @_silgen_name("swift_task_future_wait_throwing")
|
|
/// func _taskFutureGetThrowing<T>(_ task: Builtin.NativeObject) async throws -> T
|
|
///
|
|
/// @_silgen_name("swift_asyncLet_wait")
|
|
/// func _asyncLetGet<T>(_ task: Builtin.RawPointer) async -> T
|
|
///
|
|
/// @_silgen_name("swift_asyncLet_waitThrowing")
|
|
/// func _asyncLetGetThrowing<T>(_ task: Builtin.RawPointer) async throws -> T
|
|
///
|
|
class TaskFutureWaitAsyncContext : public AsyncContext {
|
|
public:
|
|
SwiftError *errorResult;
|
|
|
|
OpaqueValue *successResultPointer;
|
|
|
|
AsyncVoidClosureResumeEntryPoint *__ptrauth_swift_task_resume_function
|
|
asyncResumeEntryPoint;
|
|
|
|
void fillWithSuccess(AsyncTask::FutureFragment *future) {
|
|
fillWithSuccess(future->getStoragePtr(), future->getResultType(),
|
|
successResultPointer);
|
|
}
|
|
void fillWithSuccess(OpaqueValue *src, const Metadata *successType,
|
|
OpaqueValue *result) {
|
|
successType->vw_initializeWithCopy(result, src);
|
|
}
|
|
|
|
void fillWithError(AsyncTask::FutureFragment *future) {
|
|
fillWithError(future->getError());
|
|
}
|
|
void fillWithError(SwiftError *error) {
|
|
errorResult = error;
|
|
swift_errorRetain(error);
|
|
}
|
|
};
|
|
|
|
/// The layout of a frame to call the following function:
|
|
///
|
|
/// @_silgen_name("swift_taskGroup_wait_next_throwing")
|
|
/// func _taskGroupWaitNext<T>(group: Builtin.RawPointer) async throws -> T?
|
|
///
|
|
class TaskGroupNextAsyncContext : public AsyncContext {
|
|
public:
|
|
SwiftError *errorResult;
|
|
|
|
OpaqueValue *successResultPointer;
|
|
|
|
AsyncVoidClosureResumeEntryPoint *__ptrauth_swift_task_resume_function
|
|
asyncResumeEntryPoint;
|
|
|
|
// Arguments.
|
|
TaskGroup *group;
|
|
|
|
const Metadata *successType;
|
|
|
|
void fillWithSuccess(OpaqueValue *src, const Metadata *successType) {
|
|
successType->vw_initializeWithCopy(successResultPointer, src);
|
|
}
|
|
|
|
void fillWithError(SwiftError *error) {
|
|
errorResult = error;
|
|
swift_errorRetain(error);
|
|
}
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|