Commit Graph
62 Commits
Author SHA1 Message Date
Kushal Pisavadia 9b92dcd5c2 Replace ConditionLock with wake-one signalling NIOThreadPoolWorkAvailable (#3507)
**TL;DR** This change leads to a ~90% reduction in observed system CPU
time for some use cases by waking a single thread, instead of all idle
threads.

# Changes

Inlining the commit messages here.

## Add NIOThreadPool submit throughput benchmarks

### Motivation

`NIOThreadPool` had no benchmarks measuring submit overhead. This makes
it difficult to evaluate the cost of signalling changes or to catch
latency regressions.

### Modifications

Add thread pool submit benchmarks, covering use cases with 4-thread and
16-thread pools.

### Result

`NIOThreadPool` submit throughput and context-switch overhead are now
tracked by benchmarks.

### Benchmark Results

<details>

```
NIOThreadPool.serial_wakeup(16 threads)
╒══════════════════════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╕
│ Metric                   │        p0 │       p25 │       p50 │       p75 │       p90 │       p99 │      p100 │   Samples │
╞══════════════════════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡
│ Context switches (K)     │        77 │        78 │        79 │        80 │        80 │        92 │        92 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Syscalls (total) (K) *   │       106 │       107 │       108 │       109 │       110 │       116 │       116 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (system CPU) (ms) * │      1649 │      1752 │      1768 │      1795 │      1826 │      1929 │      1929 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (total CPU) (ms) *  │      1701 │      1805 │      1821 │      1849 │      1879 │      1987 │      1987 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (user CPU) (ms) *   │        51 │        52 │        52 │        53 │        53 │        57 │        57 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (wall clock) (ms) * │       167 │       177 │       178 │       181 │       183 │       200 │       200 │        30 │
╘══════════════════════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╛

NIOThreadPool.serial_wakeup(4 threads)
╒══════════════════════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╕
│ Metric                   │        p0 │       p25 │       p50 │       p75 │       p90 │       p99 │      p100 │   Samples │
╞══════════════════════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡
│ Context switches (K)     │        44 │        44 │        44 │        45 │        45 │        45 │        45 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Syscalls (total) (K) *   │        65 │        65 │        65 │        66 │        66 │        67 │        67 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (system CPU) (ms) * │       159 │       162 │       163 │       165 │       166 │       169 │       169 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (total CPU) (ms) *  │       178 │       182 │       183 │       185 │       186 │       190 │       190 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (user CPU) (ms) *   │        19 │        19 │        20 │        20 │        20 │        21 │        21 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (wall clock) (ms) * │        76 │        79 │        79 │        80 │        80 │        82 │        82 │        30 │
╘══════════════════════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╛
```

</details>

## Replace `ConditionLock` with wake-one signalling
`NIOThreadPoolWorkAvailable`

### Motivation

`NIOThreadPool` used `ConditionLock` which calls
`pthread_cond_broadcast` on every state change, waking all threads when
only one work item is enqueued. This causes a thundering-herd problem.

### Modifications

Add `NIOThreadPoolWorkAvailable` in NIOConcurrencyHelpers that uses
`pthread_cond_signal` (wake-one) for work submission and
`pthread_cond_broadcast` only for shutdown. Replace
`ConditionLock<_WorkState>` and the `_WorkState` enum in `NIOThreadPool`
with this new primitive.

### Result

Submitting a work item wakes exactly **one** thread instead of all
threads.

### Benchmark Results

<details>

```
NIOThreadPool.serial_wakeup(16 threads)
╒══════════════════════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╕
│ Metric                   │        p0 │       p25 │       p50 │       p75 │       p90 │       p99 │      p100 │   Samples │
╞══════════════════════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡
│ Context switches (K)     │        20 │        20 │        20 │        20 │        20 │        20 │        20 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Syscalls (total) (K) *   │        40 │        40 │        40 │        40 │        40 │        40 │        40 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (system CPU) (ms) * │        47 │        49 │        49 │        50 │        50 │        55 │        55 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (total CPU) (ms) *  │        57 │        58 │        59 │        60 │        61 │        67 │        67 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (user CPU) (ms) *   │        10 │        10 │        10 │        10 │        10 │        12 │        12 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (wall clock) (ms) * │        54 │        55 │        56 │        56 │        57 │        65 │        65 │        30 │
╘══════════════════════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╛

NIOThreadPool.serial_wakeup(4 threads)
╒══════════════════════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╤═══════════╕
│ Metric                   │        p0 │       p25 │       p50 │       p75 │       p90 │       p99 │      p100 │   Samples │
╞══════════════════════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╪═══════════╡
│ Context switches (K)     │        20 │        20 │        20 │        20 │        20 │        20 │        20 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Syscalls (total) (K) *   │        40 │        40 │        40 │        40 │        40 │        40 │        40 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (system CPU) (ms) * │        45 │        46 │        46 │        47 │        57 │        75 │        75 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (total CPU) (ms) *  │        54 │        55 │        56 │        57 │        68 │        87 │        87 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (user CPU) (μs) *   │      9055 │      9372 │      9478 │      9765 │     10887 │     12585 │     12585 │        30 │
├──────────────────────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤
│ Time (wall clock) (ms) * │        52 │        53 │        53 │        54 │        64 │       124 │       124 │        30 │
╘══════════════════════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╧═══════════╛
```

</details>
2026-02-10 20:01:35 +00:00
scottmarchant c337170d91 chore: Elide mutex variable from Lock class when it is unused (#3483)
### Motivation:

In reviewing a copy of this file in swift-log, @czechboy0
[noticed](https://github.com/apple/swift-log/pull/398#discussion_r2685605800)
that the `mutex` variable is essentially unused and unnecessarily
allocated for certain conditions. It is possible the compiler elided
usage. But given the unconditional variable reference in the `deinit`,
the compiler may not be able to.

This change ensures the `mutex` property is completely elided except in
the conditions where it is used.

### Modifications:

- Adjusted compiler directive pattern to completely elide the `mutex`
property for conditions where it would be unused.
- Adjusted `deinit` to avoid referencing `mutex` unless it is compiled
into the `Lock` class

### Result:

The `mutex` property is no longer allocated or even compiled into the
`Lock` class for unsupported configurations. All unit tests and checks
pass.

### Research:

The `deinit` used to have a blanket call to `mutex.deallocate()`. This
has been moved into the platform-specific checks within the `deinit`.
This allows complete elision of the `mutex` property altogether. The
`_runtime(_multithreaded)` condition [appears to be rooted to this
implementation](https://github.com/swiftlang/swift/blob/ffc51b914602765c5d680241796dbd3c3711fa6b/lib/Basic/LangOptions.cpp#L490).
Diving deeper, all [operating systems in this
list](https://github.com/swiftlang/swift/blob/ffc51b914602765c5d680241796dbd3c3711fa6b/lib/Basic/LangOptions.cpp#L554)
except for UnknownOS and WASI result in `_runtime(_multithreaded)`
returning true. That means that `OpenBSD` (and many other operating
systems besides windows) were almost certainly using the `#elseif
(compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) &&
_runtime(_multithreaded))` condition in the `deinit`. In conclusion,
moving `mutex.deallocate()` up into the conditional clauses inside
`deinit` should be identical to the previous implementation for all
operating systems except `llvm::Triple::UnknownOS`. And
`llvm::Triple::UnknownOS` is likely not to have every compiled anyways
due to the [check on line
32](https://github.com/apple/swift-nio/blob/main/Sources/NIOConcurrencyHelpers/lock.swift#L32).

So in summary, it is expected that this clean up will compile identical
to the previous implementation for all platforms except WASI platforms
that don't have pthread support. For non-pthread WASI platforms, the
unused `mutex` is properly elided from compilation altogether.

### Testing Done:

- Confirmed that unit tests pass locally using Xcode
- Verified [PR checks
pass](https://github.com/PassiveLogic/swift-nio/actions/runs/21149729751)
2026-01-22 17:57:10 +00:00
3405691582 233f61bc2c Initialize the mutexattr before use. (#3482)
As observed by @kkebo, this was missing from the implementation.

### Motivation:

Correct pthread API usage. 

### Modifications:

Initialize the pthread_mutexattr_t with pthread_mutexattr_init before
passed to pthread_mutex_init.

### Result:

Even though this lock API appears to be deprecated, we'll correct the
usage anyway. The non-deprecated NIOLock class doesn't have this
problem.
2026-01-19 18:18:38 +00:00
scottmarchant 6ce9173261 fix: Ensure pthread_mutexattr_t is properly cleaned up with pthread_mutexattr_destroy in Lock (#3480)
### Motivation:

In reviewing a copy of this file in swift-log, @czechboy0 noticed that
the call to `pthread_mutexattr_destroy` is missing. Since
pthread_mutexattr_t is like allocated on the stack rather than heap on
most platforms, this is likely not a memory leak. But for correctness
the missing destroy call should be added.

This change is the start of a resolution
[requested](https://github.com/apple/swift-log/pull/398#discussion_r2689459360)
in a corresponding Lock rollout in swift-log

### Modifications:

- Added missing call to `pthread_mutexattr_destroy`
- Duplicated test for `NIOLock` to also test `Lock`, as a sanity test.

### Result:

The new sanity test passes. If there are other ways this change can be
realistically verified as safe and proper, please feel free to provide
feedback in the PR.
2026-01-19 08:13:02 +00:00
3405691582andRick Newton-Rogers 2bc71a6aff Partial OpenBSD support. (#3394)
### Motivation:

Additional partial platform support.

### Modifications: 

* Create a new CNIOBSD module for OpenBSD, for general cleanliness, and
make use of it throughout. Some of the changes are borrowed directly
from CNIOLinux; some may technically be unnecessary; I am erring
somewhat on expediency to functionality.

* Since `malloc_size` is unavailable on OpenBSD, and some of the helpers
make use of ManagedBufferPointer which makes use of it, mark some of
this as unavailable as well.

* Usual pthread optional typing changes, since pthread types are
pointers on this platform.

* Add conditionals to exclude other functionality not available here,
like IP_RECVPKTINFO or IP_PKTINFO.

* d_ino is a backwards-compatibility macro valued token for dirent, so
instead, just expand with a conditional.

* Use kqueue on OpenBSD. This necessitates adding some conditionals for
type and feature compatibility.

* The vsock API is unavailable on OpenBSD.

### Result:

Tested the NIOTCPEchoClient and NIOTCPEchoServer appears to work and
that swift-nio-ssh (hopefully wlog) builds with a local repository with
these changes.

Because NIOFS/_NIOFileSystem depend on some non-portable components,
such as extended attributes, sendfile, non-portable linkat flags, and
renameat2, this is only just partial OpenBSD support, which means that
`swift build` on the full swift-nio project won't build cleanly, but at
least the portable parts can be used to build servers and clients. This
commit will mark the linked bug as fixed; I will open a new bug for file
system support.

Fixes #3383.

---------

Co-authored-by: Rick Newton-Rogers <rnro@apple.com>
2025-11-26 09:07:02 +00:00
Fabian FettandCory Benfield a3ed8e10ab Drop Swift 5.10 (#3393)
This PR drops Swift 5.10 and enables Swift 6 language mode.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-10-06 10:58:33 +01:00
Rafael Cepeda 02be63c7f4 Fixes all warnings when -require-explicit-sendable flag is enabled (#3320)
Fixes all warnings when `-require-explicit-sendable` flag is enabled and
enables the flag on macOS CI.

### Motivation:

We want to ensure our public API is either explicitly marked as
`Sendable` or not.

### Modifications:

Marked appropriate public types as `Sendable`, or explicitly defined
their conformance to the `Sendable` protocol as unavailable.

### Result:

We can now enable `-require-explicit-sendable` compiler flag in our
codebase.
2025-07-30 11:50:28 +01:00
Luke HowardandCory Benfield 8d265e31fc Support for 64-bit timespec seconds on 32-bit platforms (#3277)
Modern 32-bit platforms (such as embedded Linux builds) support 64-bit
timestamps in `time_t` and `timespec`. Accommodate this.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-06-30 17:08:50 +00:00
Johannes Weiss 40ee44c6b9 always @preconcurrency import Glibc/Musl/Android/Bionic/WASILibc (#3153)
### Motivation:

The non-`Darwin` libcs don't have the correct concurrency annotations.
But due to these Swift bugs, it's important that the _first_ importer
uses `@preconcurrency`:

- https://github.com/swiftlang/swift/issues/79414
- https://github.com/swiftlang/swift/issues/77866

### Modifications:

Much like the Foundation (& corelibs) PRs such as
https://github.com/swiftlang/swift-foundation/pull/1175 , use
`@preconcurrency import` for the non-`Darwin` libcs.

### Result:

Fewer bad warnings/errors in user code.
2025-03-21 15:35:05 +00:00
George Barnett 6d30ec4738 Remove sendable checking from NIOLock and NIOLockedValueBox (#2968)
Motivation:

ManagedBuffer is marked as explicitly not sendable on Swift nightly
builds. NIOLock and NIOLockedValueBox used a type derived from
ManagedBuffer and must be Sendable. Currently the derived type is marked
as `@unchecked Sendable`. However on nightly toolchains this now
conflicts with being explicitly not Sendable.

Modifications:

- Remove Sendable checking on NIOLock and NIOLockedValueBox

Result:

Fewer warnings
2024-11-07 14:52:06 +00:00
Rick Newton-Rogers adfd61adc5 Use Swift 6.0 docs pipeline (#2966)
### Motivation:

Documentation checking catches more issues in Swift 6.0.

### Modifications:

Adopt the Swift 6.0 image and fix the errors.

### Result:

More accurate docs.
2024-11-07 13:03:47 +00:00
Jeff 8b66b22895 Fix Windows build break. (#2935)
Use `withLockPrimitive` to access the underlying lock.

### Motivation:

The current method of accessing the lock doesn't build.
This fixes bug #2934.

### Modifications:

Access the lock via `withLockPrimitive`.

### Result:

Now it builds! :)
2024-10-19 09:25:51 +00:00
Rick Newton-Rogers 665206000b ConditionLock deallocs its pthread_cond_t in more cases (#2901)
### Motivation:

Recently we changed the init and deinit behavior of `ConditionLock`, at
that time the `UnsafeMutablePointer` allocation of the held
`pthread_cond_t` was put behind a conditional compiler and runtime
check. The deallocation of the same object was also put behind a
conditional, however the conditions were mismatched leading to a leak on
some platforms. Notably this surfaced when `wait`ing on an event loop
future.

### Modifications:

`ConditionLock.deinit` now deallocs the held `pthread_cond_t` under the
same conditions in which it allocs it.

### Result:

Creating a `ConditionLock` no longer leaks memory.
2024-10-02 14:21:48 +01:00
Max DesiatovandFranz Busch 730713e47f Add support for WASILibc (#2671)
Dispatch is not supported on WASI, and only Unix domain sockets are
supported, which means we have to exclude those APIs on this platform.

There's work in progress to enable tests for this on CI, but nothing I
can provide for this PR at the current moment.

---------

Co-authored-by: Franz Busch <f.busch@apple.com>
2024-09-12 13:18:25 +01:00
Cory Benfield 4ea1f30406 Adopt strict concurrency and Sendable in NIOConcurrencyHelpers (#2832)
Motivation:

This patch adds strict concurrency and Sendable support to
NIOConcurrencyHelpers. This is a useful first step in adding full
support across the ecosystem.

Modifications:

- Added some explicit Sendable conformances that were missing.
- Fixed some declarations to make them Strict Sendable safe.

Result:

One step towards strict concurrency
2024-08-08 12:57:49 +01:00
Franz Busch 6630cc6c6f Change unsafeDownCast to as! (#2802)
# Motivation

In Swift 5.10 the usage of `unsafeDownCast` can lead to a miss-compile which will result in bad runtime behaviour.

# Modification

This PR changes the `unsafeDownCast` to use a `as!` instead. This is safe and should result in the same performance when done with `ManagedBuffer` which is inlinable.

# Result

No more miss compiles in 5.10
2024-07-24 09:35:35 +01:00
finagolfin 4feff3c2f6 Use the new Android overlay and Bionic module from Swift 6 (#2784)
Motivation:

Get this repo building again for Android with the new overlay

Modifications:

- Import the new module or overlay wherever `Glibc` is used
- Keep this repo building with Swift 5 by duplicating some declarations

Result:

All the same tests keep passing on my Android CI, finagolfin/swift-android-sdk#158
2024-07-22 09:58:09 +00:00
Franz Busch c9756e1083 Adopt swift-format (#2794)
* Apply formatting

* Apply no block comments rule

* Apply OmitExplicitReturns

* Apple OnlyOneTrailingClosureArgument

* Apply NoAssignmentInExpressions

* Fix up DontRepeatTypeInStaticProperties lint errors

* Apply `OrderedImports`

* Apply `ReplaceForEachWithForLoop`

* format file

* Enable the formatting pipeline

* Adopt `AmbiguousTrailingClosureOverload`

* Fix license header

* Fix format check

* Fix `EndOfLineComment`

* Fix CI

* Adapt CI script to check if changes when running formatting

* Separate lint and format into to steps

* Fix format

* Adopt `UseEarlyExits`

* Revert "Adopt `UseEarlyExits`"

This reverts commit d1ac5bbe12.
2024-07-19 11:48:17 +02:00
George Barnett 223b0e8eac Add manual control to NIOLockedValueBox (#2786)
Motivation:

NIOLockedValueBox has a 'safer' API than NIOLock as it only provides
scoped access to its boxed value. NIOLock requires users to only access
protected state while the lock is acquired. As such NIOLockedValueBox
should be preferred where possible. However, there are cases where
manual control must be used (such as storing a continuation) and users
must use a NIOLock for this.

There are two downsides to this:

1. All other access to the protected state must use the NIOLock API
   putting the onus on the developer to only access the protected state
   while the lock is held.
2. NIOLock can't store its protected state inline which typically
   results in users storing it on a class.

Modifications:

- Add an 'unsafe' view to NIOLockedValueBox which allows users to
  manually control the lock and access its protected state
- Update NIOAsyncWriter and NIOThrowingAsyncSequenceProducer to use NIOLockedValueBox

Result:

- Safer locking API is used in more places
- Fewer allocations
2024-07-18 01:16:59 -07:00
Franz Busch 17eab37e93 Fix Sendable conformance for Lock (#2556)
# Motivation
The latest nightly toolchains have merged the patch that removes `Sendable` conformance from the various `Unsafe*Pointer` APIs. Our `Lock` type was using such a type internally and had a `Sendable` conformance. This conformance was now failing since the pointer was no longer `Sendable`.

# Modification
This PR changes the `Sendable` conformance of `Lock` to `@unchecked Sendable`.

# Result
No more `Sendable` warnings in non-strict mode on nightly toolchains
2023-10-16 03:48:45 -07:00
finagolfin 231902a295 Correct a few Musl additions from #2449 for Android, plus error if libc not found (#2451)
Motivation

Fix build errors on Android

Modifications

- Fix previous Musl modifications that assumed Glibc wasn't imported on Android
- Add errors for all libc imports, so new platform ports error out early

Result

NIO builds natively on Android again, with all the same tests passing
2023-06-26 02:52:18 -07:00
Max Desiatov 43b1f59fde Add support for Musl libc (#2449)
* Add support for Musl libc

Since Musl is sufficiently different from Glibc (see https://wiki.musl-libc.org/functional-differences-from-glibc.html), it requires a different import, which now should be applied to files that have `import Glibc` in them.

* Fix `msghdr` initialization

* Fix msghdr mutability

* Fix `UnsafeMutableRawPointer` type conversions
2023-06-23 08:20:14 +01:00
Franz Busch e865f6163f Use #if canImport(Darwin) where possible (#2446) 2023-06-22 10:12:01 +01:00
Cory Benfield 8423040a9b Mildly rework the NIOLock storage (#2395)
Motivation:

NIOLock uses a storage object constructed from a ManagedBuffer. In
general this is fine, but it's a tricky API to use safely and we want to
avoid violating any of its guarantees.

Modifications:

- Store the value in the header and the lock in the elements
- Add debug assertions on alignment

Result:

We'll be a bit more confident of the use of NIOLock
2023-03-27 16:37:09 +01:00
Philip Brown 59e1f6f375 Tail allocate mutex and a generic value using ManagedBuffer (#2349)
Motivation:

Currently, NIOLock and NIOLockedValueBox incur unnecessary allocation and indirection costs.

Modifications:

Create namespace LockOperations for organization
Create LockStorage<Value>, a subclass of ManagedBuffer<LockPrimitive, Value>
Store the mutex as the header and the generic value as the first and only element
Update NIOLock and NIOLockedValueBox to use LockStorage

Result:

Optimal lock and value memory layout
Fewer allocations and less indirection
Code generation is excellent
2023-01-17 16:11:10 +00:00
David Nadoba c7b4989b02 Remove #if compiler(>=5.5) (#2292)
### Motivation
We only support Swift 5.5.2+.

### Modification
Remove all `#if swift(>=5.5)` conditional compilation blocks.

### Result
less branching
2022-10-13 07:17:46 -07:00
Florian Friedrich 41f0b2d398 Improve diagnostics for depracted Lock. (#2285)
Motivation:

When using a `Lock` instance handed by another library and calling `withLock` or `withLockVoid` on it,
the compiler will issue an incorrect fix-it warning that `withLock` (or `withLockVoid`) was renamed to `NIOLock`.

Modifications:

The warning results from annotating the extension that adds `withLock` and `withLockVoid` with `@available(*, deprecated, renamed: "NIOLock")`.
This removes the annotation and moves these two methods into the main declaration of `Lock`.

Result:

The fix-it warning no longer appears when using `withLock` or `withLockVoid`.
2022-10-07 06:53:19 -07:00
David Nadoba cdeffe8c5b Remove wrong comment about performance (#2281) 2022-10-06 08:55:08 +01:00
toluRV dee448ac8b Fixed compile errors on windows (#2278)
Compile error seems to be caused by https://github.com/apple/swift-nio/pull/2266/
2022-10-05 01:55:40 -07:00
Mahdi Bahrami e9eeaadf11 add withLockVoid(_:) to NIOLock (#2276) 2022-10-04 02:59:27 -07:00
Johannes Weiss 5ce13ea045 address additional NIOLockedValueBox review comments (#2270) 2022-09-23 10:26:20 +01:00
Johannes Weiss 4ed8e1e228 rename class Lock to struct NIOLock (#2266) 2022-09-21 07:36:42 -07:00
Franz Busch 0080954998 Fixup docs for the NIOAsyncWriter (#2271)
# Motivation
We went through a lot of changes for the API of the `NIOAsyncWriter` and some doc comments suffered from this.

# Modification
Update doc comments for the `NIOAsyncWriter`.

Small fixup for the docs of the `NIOLockedValueBox`

# Result
More accurate docs
2022-09-21 16:19:41 +02:00
Johannes WeissandCory Benfield 26afcecdc2 NIOConcurrency: add NIOLockedValueBox (#2265)
Motivation:

`LockedValueBox` can help programmers to not forget to actually take a
`Lock` when they should.

Modifications:

Add `LockedValue`.

Result:

Hopefully fewer concurrency bugs.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-09-16 09:16:21 -07:00
YR ChenandCory Benfield a501353ef6 Deprecate NIOAtomics in favor of Atomics (#2204)
Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-07-01 02:31:14 -07:00
David Evans 71f60c4fd5 Make NIOConcurrencyHelpers Sendable (#2090)
Stop Sendable related warnings when using types defined inside NIOConcurrencyHelpers. All the code should actually already be thread safe, so no changes needed other than labelling some classes as either Sendable or @unchecked Sendable.
2022-04-28 17:04:46 +01:00
BenedictSt d489d9f38f Fixed some typos (#2051)
Fixed some typos.
2022-02-22 01:37:47 -08:00
Johannes Weiss a326de5a9c atomics: make add/sub @discardableResult (#2048) 2022-02-17 08:03:12 -08:00
Johannes WeissandCory Benfield d08e8ff938 disable PTHREAD_MUTEX_ERRORCHECK in release mode (#1995)
Motivation:

`pthread_mutex_t` locks can do advanced error checking with
`PTHREAD_MUTEX_ERRORCHECK`, the cost of which was unknown. With #1994 I
could now measure it.

The differences from my local machine (M1 MBP) for uncontended locks
are:

- on Linux: 10% faster without `PTHREAD_MUTEX_ERRORCHECK`
- on macOS: 25% faster without `PTHREAD_MUTEX_ERRORCHECK`!

Modification:

Do the extended error checking only in debug mode. Note that we still
`precondition` on all pthread return values (which is basically free).

Result:

Faster code.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-11-29 09:49:07 +00:00
Gwynne Raskind 25db3ea68b Correct the behavior comment for the Windows implementation of Lock.deinit. Add a Windows-specific note to Lock's documentation comment. Trim spurious semicolons appearing in Lock.init(). (#1582) 2020-06-30 08:36:05 +01:00
Saleem AbdulrasoolandJohannes Weiss 5e728b5786 NIOConcurrencyHelpers: port to Windows (#1403)
Add support for Windows to the `NIOConcurrencyHelpers`, replacing the
`pthreads` usage for Windows threading primitives.

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2020-03-03 19:18:59 +00:00
Kyle Browning 06cdd7f619 Allow discardable results on NIOAtomic for mutating functions (#1417)
* Allow discardable results on NIOAtomic for mutating functions

* Address nits.

* add a tests.

* Removes discards.
2020-02-26 21:43:35 +00:00
2c555d144a NIOConcurrencyHelpers: make LLP64 friendly (#1402)
On LLP64 platforms, `Int` is mapped to `intptr_t` and `UInt` is mapped
to `uintptr_t`.  Use the newly minted `CNIOAtomics` operations to
support these semantics.

Co-authored-by: Cory Benfield <lukasa@apple.com>
Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2020-02-19 19:05:58 +00:00
Johannes Weiss e208ab9555 fix AtomicBox by deprecating it and implementing it with a CAS loop (#1287)
Motivation:

Atomic references cannot easily be maintained correctly because the
`load` operation gets a pointer value that might (before the loader gets
a change to retain the returned reference) be destroyed by another
thread.

Modifications:

- Deprecate `AtomicBox`
- Implement `NIOCASLoopBox` with functionality similar to AtomicBox (but
  implemented using a CAS loop :( ).

Result:

- fixes #1286
2019-12-06 17:41:14 +00:00
Jake 3c879ebbaf Fast atomics (#1263)
Motivation:

The existing Atomic class holds an UnsafeEmbeddedAtomic which holds an OpaquePointer to raw memory for the C atomic. This results in multiple allocations on init. The new NIOAtomic class uses ManagedBufferPointer which tail allocates memory for the C atomic as part of the NIOAtomic class allocation.

Modifications:

Created NIOAtomic class that uses ManagedBufferPointer to allocate memory for the C atomic. Created version of catmc_atomic_* C functions that expect memory to be allocated/deallocated by caller. Created NIOAtomicPrimitive protocol for the new version of catmc_atomic_* functions.

Result:

Purely additive. NIOAtomic is available as a replacement for Atomic which results in fewer memory allocations.
2019-11-28 07:45:05 +00:00
Johannes Weiss cee3db7072 Lock: guarantee crash instead of undefined behaviour (#1131)
Motivation:

NIO's Lock currently just deadlocks if a thread which already holds a
lock tries to reacquire it. This however isn't even really defined
behaviour.

Modifications:

Switch us to a guaranteed crash from a unguarnateed hang.

Result:

Easier to debug deadlocks with NIO's lock.
2019-09-09 09:50:03 +01:00
Johannes Weiss bf2598d193 iOS & simulator compatibility (#1037)
Motivation:

We should have better iOS compatibility.

Modifications:

- make all OS-conditional imports the same
- don't check TSI_S_ESTABLISHED (which is unavailable on iOS)
- update availability to reflect the OS versions we actually support
- make sure temporary UDS paths aren't too long

Result:

better iOS compatibility
2019-06-18 10:38:39 +01:00
Johannes Weiss d55c582e5c improve documentation (#919)
Motivation:

Spotted a couple of issues with the documentation and fixed them.

Modifications:

- explicitly marked all `public class`es as `public final class` to get
  consistency in the Jazzy documentation.
- removed `public` extension methods of the `internal struct
  PriorityQueue` which Jazzy showed in the docs.
- improved the largely missing `EmbeddedChannel` and `EmbeddedEventLoop`
  documentation.
- clear up lies in the B2MD docs
- add some other missing docs

Result:

better docs makes happier users
2019-03-25 12:09:16 +02:00
Johannes Weiss fa2ebe4a56 remove backports of newer Swift functionality (#738)
Motivation:

We now depend on Swift 5.0, so we can remove all the backporting of
functionality.

Modifications:

deleted all backported Swift functionality

Result:

less code
2019-01-07 12:32:58 +00:00
Sergo Beruashvili e91dacbd54 Removed specialisations from Atomics functions and added @inlinable attribute instead. (#698)
Access level of properties used from @inlinable functions are now internal and they are marked as @usableFromInline.
2018-12-12 09:43:46 +00:00