mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Concurrency] Emit async task running/waitingOn metadata inline into CPUTrace.
This allows tracking async code execution throughout a task's lifetime. rdar://137230240
This commit is contained in:
@@ -728,10 +728,11 @@ public:
|
|||||||
return record_iterator::rangeBeginning(getInnermostRecord());
|
return record_iterator::rangeBeginning(getInnermostRecord());
|
||||||
}
|
}
|
||||||
|
|
||||||
void traceStatusChanged(AsyncTask *task, bool isStarting) {
|
void traceStatusChanged(AsyncTask *task, bool isStarting, bool wasRunning) {
|
||||||
concurrency::trace::task_status_changed(
|
concurrency::trace::task_status_changed(
|
||||||
task, static_cast<uint8_t>(getStoredPriority()), isCancelled(),
|
task, static_cast<uint8_t>(getStoredPriority()), isCancelled(),
|
||||||
isStoredPriorityEscalated(), isStarting, isRunning(), isEnqueued());
|
isStoredPriorityEscalated(), isStarting, isRunning(), isEnqueued(),
|
||||||
|
wasRunning);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -971,7 +972,7 @@ inline void AsyncTask::flagAsRunning() {
|
|||||||
if (_private()._status().compare_exchange_weak(oldStatus, newStatus,
|
if (_private()._status().compare_exchange_weak(oldStatus, newStatus,
|
||||||
/* success */ std::memory_order_relaxed,
|
/* success */ std::memory_order_relaxed,
|
||||||
/* failure */ std::memory_order_relaxed)) {
|
/* failure */ std::memory_order_relaxed)) {
|
||||||
newStatus.traceStatusChanged(this, true);
|
newStatus.traceStatusChanged(this, true, oldStatus.isRunning());
|
||||||
adoptTaskVoucher(this);
|
adoptTaskVoucher(this);
|
||||||
swift_task_enterThreadLocalContext(
|
swift_task_enterThreadLocalContext(
|
||||||
(char *)&_private().ExclusivityAccessSet[0]);
|
(char *)&_private().ExclusivityAccessSet[0]);
|
||||||
|
|||||||
@@ -94,8 +94,9 @@ static void withStatusRecordLock(
|
|||||||
status, newStatus,
|
status, newStatus,
|
||||||
/*success*/ SWIFT_MEMORY_ORDER_CONSUME,
|
/*success*/ SWIFT_MEMORY_ORDER_CONSUME,
|
||||||
/*failure*/ std::memory_order_relaxed)) {
|
/*failure*/ std::memory_order_relaxed)) {
|
||||||
|
bool wasRunning = status.isRunning();
|
||||||
status = newStatus;
|
status = newStatus;
|
||||||
status.traceStatusChanged(task, false);
|
status.traceStatusChanged(task, false, wasRunning);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +131,7 @@ static void withStatusRecordLock(
|
|||||||
status, newStatus,
|
status, newStatus,
|
||||||
/*success*/ std::memory_order_relaxed,
|
/*success*/ std::memory_order_relaxed,
|
||||||
/*failure*/ std::memory_order_relaxed)) {
|
/*failure*/ std::memory_order_relaxed)) {
|
||||||
newStatus.traceStatusChanged(task, false);
|
newStatus.traceStatusChanged(task, false, status.isRunning());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +197,7 @@ bool swift::addStatusRecord(AsyncTask *task, TaskStatusRecord *newRecord,
|
|||||||
if (task->_private()._status().compare_exchange_weak(oldStatus, newStatus,
|
if (task->_private()._status().compare_exchange_weak(oldStatus, newStatus,
|
||||||
/*success*/ std::memory_order_release,
|
/*success*/ std::memory_order_release,
|
||||||
/*failure*/ std::memory_order_relaxed)) {
|
/*failure*/ std::memory_order_relaxed)) {
|
||||||
newStatus.traceStatusChanged(task, false);
|
newStatus.traceStatusChanged(task, false, oldStatus.isRunning());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Retry
|
// Retry
|
||||||
@@ -302,7 +303,7 @@ void swift::removeStatusRecord(AsyncTask *task, TaskStatusRecord *record,
|
|||||||
oldStatus, newStatus,
|
oldStatus, newStatus,
|
||||||
/*success*/ std::memory_order_relaxed,
|
/*success*/ std::memory_order_relaxed,
|
||||||
/*failure*/ std::memory_order_relaxed)) {
|
/*failure*/ std::memory_order_relaxed)) {
|
||||||
newStatus.traceStatusChanged(task, false);
|
newStatus.traceStatusChanged(task, false, oldStatus.isRunning());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,7 +905,7 @@ static void swift_task_cancelImpl(AsyncTask *task) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newStatus.traceStatusChanged(task, false);
|
newStatus.traceStatusChanged(task, false, oldStatus.isRunning());
|
||||||
if (newStatus.getInnermostRecord() == nullptr) {
|
if (newStatus.getInnermostRecord() == nullptr) {
|
||||||
// No records, nothing to propagate
|
// No records, nothing to propagate
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ void task_create(AsyncTask *task, AsyncTask *parent, TaskGroup *group,
|
|||||||
void task_destroy(AsyncTask *task);
|
void task_destroy(AsyncTask *task);
|
||||||
|
|
||||||
void task_status_changed(AsyncTask *task, uint8_t maxPriority, bool isCancelled,
|
void task_status_changed(AsyncTask *task, uint8_t maxPriority, bool isCancelled,
|
||||||
bool isEscalated, bool isStarting, bool isRunning, bool isEnqueued);
|
bool isEscalated, bool isStarting, bool isRunning,
|
||||||
|
bool isEnqueued, bool wasRunning);
|
||||||
|
|
||||||
void task_flags_changed(AsyncTask *task, uint8_t jobPriority, bool isChildTask,
|
void task_flags_changed(AsyncTask *task, uint8_t jobPriority, bool isChildTask,
|
||||||
bool isFuture, bool isGroupChildTask,
|
bool isFuture, bool isGroupChildTask,
|
||||||
|
|||||||
@@ -28,6 +28,10 @@
|
|||||||
#include <os/log.h>
|
#include <os/log.h>
|
||||||
#include <os/signpost.h>
|
#include <os/signpost.h>
|
||||||
|
|
||||||
|
#if defined(__arm64__) && __has_include(<os/apt_private.h>)
|
||||||
|
#include <os/apt_private.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Compatibility notes:
|
// Compatibility notes:
|
||||||
//
|
//
|
||||||
// These signposts can be read by external software that isn't synced with the
|
// These signposts can be read by external software that isn't synced with the
|
||||||
@@ -210,7 +214,24 @@ inline void task_destroy(AsyncTask *task) {
|
|||||||
|
|
||||||
inline void task_status_changed(AsyncTask *task, uint8_t maxPriority,
|
inline void task_status_changed(AsyncTask *task, uint8_t maxPriority,
|
||||||
bool isCancelled, bool isEscalated,
|
bool isCancelled, bool isEscalated,
|
||||||
bool isStarting, bool isRunning, bool isEnqueued) {
|
bool isStarting, bool isRunning,
|
||||||
|
bool isEnqueued, bool wasRunning) {
|
||||||
|
#if !TARGET_OS_SIMULATOR
|
||||||
|
#if OS_APT_SPI_VERSION >= 20241023
|
||||||
|
uint64_t taskId = task->getTaskId();
|
||||||
|
if (isRunning) {
|
||||||
|
if (SWIFT_RUNTIME_WEAK_CHECK(os_apt_msg_async_task_running_4swift)) {
|
||||||
|
SWIFT_RUNTIME_WEAK_USE(os_apt_msg_async_task_running_4swift(taskId));
|
||||||
|
}
|
||||||
|
} else if (!isRunning && wasRunning) {
|
||||||
|
#if OS_APT_SPI_VERSION >= 20250710
|
||||||
|
if (SWIFT_RUNTIME_WEAK_CHECK(os_apt_msg_async_task_stopped_4swift)) {
|
||||||
|
SWIFT_RUNTIME_WEAK_USE(os_apt_msg_async_task_stopped_4swift(taskId));
|
||||||
|
}
|
||||||
|
#endif // OS_APT_SPI_VERSION >= 20250710
|
||||||
|
}
|
||||||
|
#endif // OS_APT_SPI_VERSION >= 20241023
|
||||||
|
#endif // !TARGET_OS_SIMULATOR
|
||||||
ENSURE_LOGS();
|
ENSURE_LOGS();
|
||||||
auto id = os_signpost_id_make_with_pointer(TaskLog, task);
|
auto id = os_signpost_id_make_with_pointer(TaskLog, task);
|
||||||
os_signpost_event_emit(
|
os_signpost_event_emit(
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ inline void task_resume(AsyncTask *task) {}
|
|||||||
|
|
||||||
inline void task_status_changed(AsyncTask *task, uint8_t maxPriority,
|
inline void task_status_changed(AsyncTask *task, uint8_t maxPriority,
|
||||||
bool isCancelled, bool isEscalated,
|
bool isCancelled, bool isEscalated,
|
||||||
bool isStarting, bool isRunning, bool isEnqueued) {}
|
bool isStarting, bool isRunning,
|
||||||
|
bool isEnqueued, bool wasRunning) {}
|
||||||
|
|
||||||
inline void task_flags_changed(AsyncTask *task, uint8_t jobPriority,
|
inline void task_flags_changed(AsyncTask *task, uint8_t jobPriority,
|
||||||
bool isChildTask, bool isFuture,
|
bool isChildTask, bool isFuture,
|
||||||
|
|||||||
Reference in New Issue
Block a user