Commit Graph

71 Commits

Author SHA1 Message Date
Mike Ash
1e265c24d7 Merge pull request #80096 from mikeash/task-group-cancellation-lock-fix
[Concurrency] Fix a race when using cancelAll on a task group concurrently with child tasks being removed.
2025-03-20 11:53:31 -04:00
Mike Ash
38c4fce1a8 [Concurrency] Fix a race when using cancelAll on a task group concurrently with child tasks being removed.
_swift_taskGroup_cancelAllChildren relies on there being no concurrent modification when called from the owning task, but this is not guaranteed.

Rearrange things to always take the owning task's status record lock when walking the group's children. Split _swift_taskGroup_cancelAllChildren into two functions, one which assumes/requires the lock is already held, and one which acquires the lock. We don't have the owning task in this case, but we can either get it from the current task, or by looking at the parent of the child task we're working on.

rdar://147172991
2025-03-18 14:52:07 -04:00
Konrad `ktoso` Malawski
85e4685f90 [Concurrency] Adjust task escalation APIs to SE accepted shapes (#79988)
* [Concurrency] Adjust task escalation APIs to SE accepted shapes

* adjust test a little bit

* Fix closure lifetime in withTaskPriorityEscalationHandler

* avoid bringing workaround func into abi by marking AEIC
2025-03-18 07:05:11 +09:00
Konrad `ktoso` Malawski
a92f37998e [freestanding] prefer strncpy with known length (#80005) 2025-03-14 04:44:09 -07:00
Konrad `ktoso` Malawski
fda7f539fb Reapply "Task names" (#79562) (#79600) 2025-03-08 10:58:49 +09:00
Konrad `ktoso` Malawski
09003d6f11 Revert "Merge pull request #77609 from ktoso/wip-task-names" (#79562)
This reverts commit 4ab5d2604f.
2025-02-23 22:59:21 -08:00
Konrad `ktoso` Malawski
4ab5d2604f Merge pull request #77609 from ktoso/wip-task-names
[Concurrency] Task names
2025-02-21 22:28:33 +09:00
Saleem Abdulrasool
8040430bc7 Concurrency: silence some unused variable warnings
This cleans up some warnings from the unused variables. The variables
were referenced by `assert` cases only.
2025-02-03 09:22:50 -08:00
Michael Gottesman
cb8e8b505a Fix syntax highlighting by changing how we include COMPATIBILITY_OVERRIDE_INCLUDE_PATH.
The way that we include COMPATIBILITY_OVERRIDE_INCLUDE_PATH freaks out the
syntax highlighting of editors like emacs. It causes the whole file to be
highlighted like it is part of the include string.

To work around this, this patch creates a separate file called
CompatibilityOverrideIncludePath.h that just includes
COMPATIBILITY_OVERRIDE_INCLUDE_PATH. So its syntax highlighting is borked, but
at least in the actual files that contain real code, the syntax highlighting is
restored.
2024-10-01 16:17:16 -07:00
Konrad `ktoso` Malawski
a3e0b173ea [Concurrency] TaskExecutors may be non-swift objects; dont swift_release them (#75059) 2024-07-09 02:55:11 -07:00
Konrad `ktoso` Malawski
2ec717b115 [Concurrency] TaskExecutor ownership fixes (#74000) 2024-06-14 22:56:33 +09:00
Konrad `ktoso` Malawski
e9b25d1091 [Concurrency] Move innermost record assertion to handle more gracefully 2024-05-28 16:58:38 +09:00
Mike Ash
0f226b6667 [Concurrency] Refine getResumeFunctionForLogging to avoid reading invalid future contexts.
When using a future adapter, the resume context may not be valid after the task starts running. Only peer through the adapter when we're starting to run.

rdar://126298035
2024-05-21 16:22:40 -04:00
cui fliter
127077b3aa chore: fix some comments
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-03-05 17:23:22 +08:00
Rick van Voorden
f8ae46b3f3 [inclusive-language] changed sanity to soundness 2024-01-25 18:18:02 -08:00
Konrad `ktoso` Malawski
828f589be4 Initial Task Executor implementation Task(on:), addTask(on:) etc. (#68793)
Co-authored-by: John McCall <rjmccall@gmail.com>
2023-12-12 17:14:24 +09:00
Rokhini Prabhu
9b6c873239 Escalate an actor if a job in the queue of the actor has been escalated.
Radar-Id: rdar://problem/101864092
2023-02-28 13:52:26 -08:00
Rokhini Prabhu
534811c3dc When a task gets enqueued on an executor, start tracking which executor
it is enqueued on. This way, we have the necessary bookkeeping to
escalate an executor when a task that is enqueued, is escalated.

Radar-Id: rdar://problem/101864092
2023-02-25 17:01:03 -08:00
Rokhini Prabhu
d77306729b Improve TaskDependencyStatusRecord so that it can now track the executor
you are enqueued on

Radar-Id: rdar://problem/101864092
2023-02-25 16:58:02 -08:00
Rokhini Prabhu
d0aa55670a Provide an updateStatusRecord function which allows clients to update a
status record that is already registered with the task. Provide more
versatile removeStatusRecord functions and update clients to use them

Radar-Id: rdar://problem/101864092
2023-02-25 16:55:38 -08:00
Rokhini Prabhu
e8d9fd91f7 Tell TSAN that we know that we're doing with CONSUME semantics so that
it doesn't flag false positive issues

Radar-Id: rdar://problem/105634683
2023-02-23 17:42:00 -08:00
Rokhini Prabhu
3c0f4f79fe Provide a convenience for addStatusRecord for clients who have already
done the load or who need the oldStatus information after adding the
status record.

Change some of the memory barrier logic since we can take advantage of
load-through HW address dependency.

Radar-Id: rdar://problem/105634683
2023-02-20 23:14:47 -08:00
Rokhini Prabhu
e052ccef31 Create the notion of a TaskDependencyStatusRecord which tracks what a
task is blocked on. We can use this information to then perform live
priority escalation to a task future.

Radar-Id: rdar://problem/88093007
2023-02-08 17:29:55 -08:00
Rokhini Prabhu
2e6baf279d Add support to addStatusRecord and removeStatusRecord so that the flags
field of an ActiveTaskStatus can also be modified while the
TaskStatusRecord list is being modified. Make the StatusRecordLock
reentrant.

Radar-Id: rdar://problem/88093007
2023-02-08 17:29:05 -08:00
Rokhini Prabhu
62852262b4 Remove dead code with task nearest deadline logic
Radar-Id: rdar://problem/88093007
2023-02-07 14:34:29 -08:00
John McCall
7f737d235d Synchronize with cancellation when removing a task from a task group
We were detaching the child by just modifying the list, but the cancellation path was assuming that that would not be done without holding the task status lock.

This patch just fixes the current runtime; the back-deployment side is complicated.

Fixes rdar://88398824
2022-10-29 00:10:28 -04:00
Mike Ash
9c849e431c [Concurrency] Fix memory ordering around task cancellation.
Load task status with an acquire when canceling a task, to synchronize with the store-release that comes when updating a task's status.

Add explicit TSan calls in cancellation, as well as withStatusRecordLock and addStatusRecord, to avoid TSan complaining about data races when canceling a task.

Add a test that checks for TSan-reported data races when canceling a task.

rdar://93892417
2022-09-14 13:39:55 -04:00
Alastair Houghton
0e9318cec5 [Threading] Put everything through git clang-format.
Just formatting changes.

rdar://90776105
2022-06-07 07:39:53 +01:00
Alastair Houghton
f5bdb858e0 [Threading] Create new threading library and use it.
Moved all the threading code to one place.  Added explicit support for
Darwin, Linux, Pthreads, C11 threads and Win32 threads, including new
implementations of Once for Linux, Pthreads, C11 and Win32.

rdar://90776105
2022-06-07 07:39:51 +01:00
Alex Hoppen
4aa2bbbf06 Revert "Merge pull request #42447 from al45tair/eng/PR-90776105"
This reverts commit 8bcb71140f, reversing
changes made to c4dd271d36.
2022-06-02 18:03:23 +02:00
Alastair Houghton
b5bd267ff1 [Threading] Put everything through git clang-format.
Just formatting changes.

rdar://90776105
2022-05-24 14:57:41 +01:00
Alastair Houghton
63a09007a1 [Threading] Create new threading library and use it.
Moved all the threading code to one place.  Added explicit support for
Darwin, Linux, Pthreads, C11 threads and Win32 threads, including new
implementations of Once for Linux, Pthreads, C11 and Win32.

rdar://90776105
2022-05-24 14:57:39 +01:00
Kavon Farvardin
22323fbda9 correct format strings when building with SWIFT_TASK_DEBUG_LOG enabled 2022-05-10 13:00:45 -07:00
Rokhini Prabhu
98a8bdbd38 Task Escalation support on arm64_32 Apple platforms
Radar-Id: rdar://problem/88600541
2022-02-10 11:50:31 -08:00
Rokhini Prabhu
66d4af0b01 Task priority escalation on Apple platforms
A task can be in one of 4 states over its lifetime:

    (a) suspended
    (b) enqueued
    (c) running
    (d) completed

This change provides priority inversion avoidance support if a task gets
escalated when it is in state (a), (c), (d).

Radar-Id: rdar://problem/76127624
2022-02-07 16:34:46 -08:00
Rokhini Prabhu
519e60c43e Allow concurrent modifications to the ActiveTaskStatus while another
thread has the task status record lock.

Today, if a thread is holding the StatusRecordLock, then no other
modification of the task status is possible - including a thread
starting to execute the task or stopping execution of the task.
However, the TaskStatusRecordLock is really about protecting the linked
list that is maintained in the ActiveTaskStatus. As such, other
operations which don't need to look at that linked list of us records
really shouldn't have to block on the StatusRecordLock.

This change allows for concurrent modification of the veTaskStatus while
the TaskStatusRecordLock is held. In particular, a task can cancelled,
escalated, start and stop running, all while another ad is holding onto
the task's StatusRecordLock. In the event of cancellation and
escalation, the task's StatusRecordLock must be n in order to propagate
cancellation and escalation to its child tasks is not needed to cancel
or escalate the task itself.

Radar-Id: rdar://problem/76127624
2022-02-07 16:34:46 -08:00
Rokhini Prabhu
90bf37784c NFC: Rename isLocked to isStatusRecordLocked to more explicitly
distinguish from the drain lock of the task that will be added next

Radar-Id: rdar://problem/76127624
2022-02-04 13:45:40 -08:00
Rokhini Prabhu
a2a5c64d4b Change task's base and escalated priority propagation rules for
detached, unstructured and structured concurrency child tasks

Radar-Id: rdar://problem/86100376
2022-01-24 07:50:28 -08:00
Rokhini Prabhu
a4fe57f230 Merge pull request #40606 from apple/rokhinip/86347801-task-creation-escalation-race
Resolve race between task creation and concurrent escalation and cancellation.
2022-01-12 12:14:09 +08:00
Mike Ash
0977920217 [Concurrency] Add tracing for major operations in the concurrency runtime.
Each trace point is declared as a function in the new `Tracing.h` header. These functions are called from the appropriate places in the concurrency runtime.

On Darwin, an implementation of these functions is provided which uses the `os/signpost.h` API to emit signpost events/intervals.

When the signpost API is not available, no-op stub implementations are provided. Implementations for other OSes can be provided by providing implementations of the trace functions for that OS.

rdar://81858487
2022-01-07 11:35:40 -05:00
Rokhini Prabhu
e35eba06d2 Remove old addChild and detachChild stuff from files
Radar-Id: rdar://problem/86347801
2021-12-31 03:23:52 -08:00
Rokhini Prabhu
1947102ebd Change the logic for adding new task status records to a task
This change has two parts to it:

1. Add in a new interface (addStatusRecordWithChecks) for adding task
status records that also takes in a function ref. This function ref will
be used to evaluate if current state of the parent task has any changes
that need to be propagated to the child task that has been created.

This is necessary to prevent the following race between task creation
and concurrent cancellation and escalation:

a. Parent task create child task. It does lazy relaxed loads on its own
   state while doing so and propagates this state to the child.
b. Child task is created but has not been attached to the parent
   task/task group.
c. Parent task gets cancelled by another thread.
d. Child task gets linked into the parent’s task status records but no
   reevaluation has happened to account for changes that might have happened to
   the parent after (a).

2. Move status record management functions from the
Runtime/Concurrency.h to TaskPrivate.h. Remove any corresponding
overrides that are no longer needed. Remove unused tryAddStatusRecord
method whose functionality is provided by addStatusRecordWithChecks.

Radar-Id: rdar://problem/86347801
2021-12-31 03:23:52 -08:00
Rokhini Prabhu
835f274183 Make sure that cancelling a task group does not invoke cancellation
handler of parent task that created the group

Change comment in TaskGroup.swift to enforce that only parent task can
call cancelAll on the group

Add tests to verify mutating of task group in child tasks will fail

Radar-Id: rdar://problem/86346865
2021-12-17 18:35:39 -08:00
John McCall
9221fcec67 Fix priority inversions when waiting on a task status lock.
Since locking the task status is a presumed-uncommon case, the
trade-offs inherent in the allocation patterns of AtomicWaitQueue
are very appropriate here, even more than they are for metadata
completion.

rdar://86100232
2021-12-16 03:07:45 -05:00
Rokhini
7200e0c913 Remove double-log
Co-authored-by: Konrad `ktoso` Malawski <ktoso@apple.com>
2021-12-14 10:28:36 +08:00
Rokhini Prabhu
4bcaa2e7d9 There is no inherent synchronization in the TaskGroupStatusRecord so
when a task is adding adding new children to a task group, we need to
synchronize with the task status record lock of the parent task that has the
task group, to prevent races with concurrent cancellation and escalation.

Radar-Id: rdar://problem/86311782
2021-12-10 20:17:24 -08:00
Konrad `ktoso` Malawski
f336404ae9 [Concurrency] TaskGroup children remove their records as they complete
If we didn't do this (and we didn't), the tasks get released as we
perform the next() impl, and move the value from the ready task to the
waiting task. Then, the ready task gets destroyed.

But as the task group exists, it performs a cancelAll() and that
iterates over all records. Those records were not removed previously
(!!!) which meant we were pointing at now deallocated tasks.

Previously this worked because we didn't deallocate the tasks, so they
leaked, but we didn't crash. With the memory leak fixed, this began to
crash since we'd attempt to cancel already destroyed tasks.

Solution:
- Remove task records whenever they complete a waiting task.
- This can ONLY be done by the "group owning task" itself, becuause
  the contract of ONLY this task being allowed to modify records. o
  It MUST NOT be done by the completing tasks as they complete, as it
  would race with the owning task modifying this linked list of child
  tasks in the group record.
2021-09-04 20:09:55 +09:00
John McCall
3aa04db87b Track whether a task is actively running.
Tracking this as a single bit is actually largely uninteresting
to the runtime.  To handle priority escalation properly, we really
need to track this at a finer grain of detail: recording that the
task is running on a specific thread, enqueued on a specific actor,
or so on.  But starting by tracking a single bit is important for
two reasons:

- First, it's more realistic about the performance overheads of
  tasks: we're going to be doing this tracking eventually, and
  the cost of that tracking will be dominated by the atomic
  access, so doing that access now sets the baseline about right.

- Second, it ensures that we've actually got runtime involvement
  in all the right places to do this tracking.

A propos of the latter: there was no runtime involvement with
awaiting a continuation, which is a point at which the task
potentially transitions from running to suspended.  We must do
the tracking as part of this transition, rather than recognizing
in the run-loops that a task is still active and treating it as
having suspended, because the latter point potentially races with
the resumption of the task.  To do this, I've had to introduce
a runtime function, swift_continuation_await, to do this awaiting
rather than inlining the atomic operation on the continuation.

As part of doing this work, I've also fixed a bug where we failed
to load-acquire in swift_task_escalate before walking the task
status records to invoke escalation actions.

I've also fixed several places where the handling of task statuses
may have accidentally allowed the task to revert to uncancelled.
2021-07-14 20:24:01 -04:00
Konrad `ktoso` Malawski
0e5f0b043f [TaskLocals] dont crash checking for taskgroup when in no task (#37681) 2021-06-08 14:51:05 +09:00
John McCall
db3967f41d Future-proof the layout of AsyncTask. 2021-05-20 15:30:48 -04:00