Skip to content

Implement a simple library for task cancellation and status management #34198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmake/modules/AddSwiftUnittests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ function(add_swift_unittest test_dirname)
endif()

if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
# Add an @rpath to the swift library directory.
set_target_properties(${test_dirname} PROPERTIES
BUILD_RPATH ${SWIFT_LIBRARY_OUTPUT_INTDIR}/swift/macosx)
# Force all the swift libraries to be found via rpath.
add_custom_command(TARGET "${test_dirname}" POST_BUILD
COMMAND "${SWIFT_SOURCE_DIR}/utils/swift-rpathize.py"
"$<TARGET_FILE:${test_dirname}>")
elseif("${SWIFT_HOST_VARIANT}" STREQUAL "android")
swift_android_lib_for_arch(${SWIFT_HOST_VARIANT_ARCH} android_system_libs)
set_property(TARGET "${test_dirname}" APPEND PROPERTY LINK_DIRECTORIES
Expand Down
171 changes: 171 additions & 0 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,16 @@ namespace SpecialPointerAuthDiscriminators {

/// Actor enqueue(partialTask:).
const uint16_t ActorEnqueuePartialTask = 0x8f3d;

/// Jobs, tasks, and continuations.
const uint16_t JobInvokeFunction = 0xcc64; // = 52324
const uint16_t TaskResumeFunction = 0x2c42; // = 11330
const uint16_t TaskResumeContext = 0x753a; // = 30010
const uint16_t AsyncContextParent = 0xbda2; // = 48546
const uint16_t AsyncContextResume = 0xd707; // = 55047
const uint16_t AsyncContextYield = 0xe207; // = 57863
const uint16_t CancellationNotificationFunction = 0x1933; // = 6451
const uint16_t EscalationNotificationFunction = 0x5be4; // = 23524
}

/// The number of arguments that will be passed directly to a generic
Expand Down Expand Up @@ -1867,6 +1877,167 @@ class IntegerLiteralFlags {
}
};

/// Kinds of schedulable job.s
enum class JobKind : size_t {
// There are 256 possible job kinds.

/// An AsyncTask.
Task = 0,

/// Job kinds >= 192 are private to the implementation.
First_Reserved = 192
};

/// The priority of a job. Higher priorities are larger values.
enum class JobPriority : size_t {
// This is modelled off of Dispatch.QoS, and the values are directly
// stolen from there.
UserInteractive = 0x21,
UserInitiated = 0x19,
Default = 0x15,
Utility = 0x11,
Background = 0x09,
Unspecified = 0x00,
};

/// Flags for schedulable jobs.
class JobFlags : public FlagSet<size_t> {
public:
enum {
Kind = 0,
Kind_width = 8,

Priority = 8,
Priority_width = 8,

// 8 bits reserved for more generic job flags.

// Kind-specific flags.

Task_IsHeapObject = 24,
Task_IsChildTask = 25,
Task_IsFuture = 26
};

explicit JobFlags(size_t bits) : FlagSet(bits) {}
JobFlags(JobKind kind) { setKind(kind); }
constexpr JobFlags() {}

FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, JobKind,
getKind, setKind)

FLAGSET_DEFINE_FIELD_ACCESSORS(Priority, Priority_width, JobPriority,
getPriority, setPriority)

bool isAsyncTask() const {
return getKind() == JobKind::Task;
}

FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsHeapObject,
task_isHeapObject,
task_setIsHeapObject)
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsChildTask,
task_isChildTask,
task_setIsChildTask)
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsFuture,
task_isFuture,
task_setIsFuture)

};

/// Kinds of task status record.
enum class TaskStatusRecordKind : uint8_t {
/// A DeadlineStatusRecord, which represents an active deadline.
Deadline = 0,

/// A ChildTaskStatusRecord, which represents the potential for
/// active child tasks.
ChildTask = 1,

/// A CancellationNotificationStatusRecord, which represents the
/// need to call a custom function when the task is cancelled.
CancellationNotification = 2,

/// An EscalationNotificationStatusRecord, which represents the
/// need to call a custom function when the task's priority is
/// escalated.
EscalationNotification = 3,

// Kinds >= 192 are private to the implementation.
First_Reserved = 192,
Private_RecordLock = 192
};

/// Flags for cancellation records.
class TaskStatusRecordFlags : public FlagSet<size_t> {
public:
enum {
Kind = 0,
Kind_width = 8,
};

explicit TaskStatusRecordFlags(size_t bits) : FlagSet(bits) {}
constexpr TaskStatusRecordFlags() {}
TaskStatusRecordFlags(TaskStatusRecordKind kind) {
setKind(kind);
}

FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, TaskStatusRecordKind,
getKind, setKind)
};

/// Kinds of async context.
enum class AsyncContextKind {
/// An ordinary asynchronous function.
Ordinary = 0,

/// A context which can yield to its caller.
Yielding = 1,

// Other kinds are reserved for interesting special
// intermediate contexts.

// Kinds >= 192 are private to the implementation.
First_Reserved = 192
};

/// Flags for async contexts.
class AsyncContextFlags : public FlagSet<uint32_t> {
public:
enum {
Kind = 0,
Kind_width = 8,

CanThrow = 8,
ShouldNotDeallocate = 9
};

explicit AsyncContextFlags(uint32_t bits) : FlagSet(bits) {}
constexpr AsyncContextFlags() {}
AsyncContextFlags(AsyncContextKind kind) {
setKind(kind);
}

/// The kind of context this represents.
FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, AsyncContextKind,
getKind, setKind)

/// Whether this context is permitted to throw.
FLAGSET_DEFINE_FLAG_ACCESSORS(CanThrow, canThrow, setCanThrow)

/// Whether a function should avoid deallocating its context before
/// returning. It should still pass its caller's context to its
/// return continuation.
///
/// This flag can be set in the caller to optimize context allocation,
/// e.g. if the callee's context size is known statically and simply
/// allocated as part of the caller's context, or if the callee will
/// be called multiple times.
FLAGSET_DEFINE_FLAG_ACCESSORS(ShouldNotDeallocate,
shouldNotDeallocateInCaller,
setShouldNotDeallocateInCaller)
};

} // end namespace swift

#endif // SWIFT_ABI_METADATAVALUES_H
Loading