Skip to content

Commit

Permalink
Convert ScheduledTask to a struct
Browse files Browse the repository at this point in the history
### Motivation:

In my previous PR #2009, I added baseline performance and allocation tests around `scheduleTask` and `execute`. After analysing, the various allocations that happen when scheduling a task there were only a few that could be optimized away potentially.

### Modifications:

This PR converts the `ScheduledTask` class to a struct which will reduce the number of allocations for scheduling tasks by 1. The only thing that needs to be worked around when converting to a struct is giving it an identity so that we can implement `Equatable` conformance properly. I explored two options. First, using an `ObjectIdentifier` passed to the init. Second, using an atomic counter per EventLoop. I went with the latter since the former requires an additional allocation in the case of calling `execute`

### Result:

`scheduleTask` and `execute` require one less allocation
  • Loading branch information
FranzBusch committed Dec 14, 2021
1 parent 213eb68 commit 7e9b916
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 82 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var targets: [PackageDescription.Target] = [
.target(name: "NIOCore",
dependencies: ["NIOConcurrencyHelpers", "CNIOLinux"]),
.target(name: "_NIODataStructures"),
.target(name: "NIOEmbedded", dependencies: ["NIOCore", "_NIODataStructures"]),
.target(name: "NIOEmbedded", dependencies: ["NIOCore", "_NIODataStructures", "NIOConcurrencyHelpers"]),
.target(name: "NIOPosix",
dependencies: ["CNIOLinux",
"CNIODarwin",
Expand Down
18 changes: 12 additions & 6 deletions Sources/NIOEmbedded/Embedded.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
import Dispatch
import _NIODataStructures
import NIOCore
import NIOConcurrencyHelpers

private final class EmbeddedScheduledTask {

private struct EmbeddedScheduledTask {
let id: UInt64
let task: () -> Void
let readyTime: NIODeadline
let insertOrder: UInt64

init(readyTime: NIODeadline, insertOrder: UInt64, task: @escaping () -> Void) {
init(id: UInt64, readyTime: NIODeadline, insertOrder: UInt64, task: @escaping () -> Void) {
self.id = id
self.readyTime = readyTime
self.insertOrder = insertOrder
self.task = task
Expand All @@ -38,7 +42,7 @@ extension EmbeddedScheduledTask: Comparable {
}

static func == (lhs: EmbeddedScheduledTask, rhs: EmbeddedScheduledTask) -> Bool {
return lhs === rhs
return lhs.id == rhs.id
}
}

Expand All @@ -63,6 +67,7 @@ public final class EmbeddedEventLoop: EventLoop {
/// The current "time" for this event loop. This is an amount in nanoseconds.
/* private but tests */ internal var _now: NIODeadline = .uptimeNanoseconds(0)

private var scheduledTaskCounter = NIOAtomic.makeAtomic(value: UInt64(0))
private var scheduledTasks = PriorityQueue<EmbeddedScheduledTask>()

/// Keep track of where promises are allocated to ensure we can identify their source if they leak.
Expand Down Expand Up @@ -92,16 +97,17 @@ public final class EmbeddedEventLoop: EventLoop {
@discardableResult
public func scheduleTask<T>(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled<T> {
let promise: EventLoopPromise<T> = makePromise()
let task = EmbeddedScheduledTask(readyTime: deadline, insertOrder: self.nextTaskNumber()) {
let task = EmbeddedScheduledTask(id: self.scheduledTaskCounter.add(1),readyTime: deadline, insertOrder: self.nextTaskNumber(), task: {
do {
promise.succeed(try task())
} catch let err {
promise.fail(err)
}
}
})

let taskId = task.id
let scheduled = Scheduled(promise: promise, cancellationTask: {
self.scheduledTasks.remove(task)
self.scheduledTasks.removeFirst { $0.id == taskId }
})
scheduledTasks.push(task)
return scheduled
Expand Down
9 changes: 6 additions & 3 deletions Sources/NIOPosix/MultiThreadedEventLoopGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,17 @@ extension MultiThreadedEventLoopGroup: CustomStringConvertible {
}

@usableFromInline
internal final class ScheduledTask {
internal struct ScheduledTask {
@usableFromInline
let id: UInt64
let task: () -> Void
private let failFn: (Error) ->()
@usableFromInline
internal let _readyTime: NIODeadline

@usableFromInline
init(_ task: @escaping () -> Void, _ failFn: @escaping (Error) -> Void, _ time: NIODeadline) {
init(id: UInt64, _ task: @escaping () -> Void, _ failFn: @escaping (Error) -> Void, _ time: NIODeadline) {
self.id = id
self.task = task
self.failFn = failFn
self._readyTime = time
Expand Down Expand Up @@ -378,6 +381,6 @@ extension ScheduledTask: Comparable {

@usableFromInline
static func == (lhs: ScheduledTask, rhs: ScheduledTask) -> Bool {
return lhs === rhs
return lhs.id == rhs.id
}
}
9 changes: 6 additions & 3 deletions Sources/NIOPosix/SelectableEventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ internal final class SelectableEventLoop: EventLoop {
// This may only be read/written while holding the _tasksLock.
internal var _pendingTaskPop = false
@usableFromInline
internal var scheduledTaskCounter = NIOAtomic.makeAtomic(value: UInt64(0))
@usableFromInline
internal var _scheduledTasks = PriorityQueue<ScheduledTask>()
private var tasksCopy = ContiguousArray<() -> Void>()
@usableFromInline
Expand Down Expand Up @@ -261,7 +263,7 @@ Further information:
@inlinable
internal func scheduleTask<T>(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled<T> {
let promise: EventLoopPromise<T> = self.makePromise()
let task = ScheduledTask({
let task = ScheduledTask(id: self.scheduledTaskCounter.add(1), {
do {
promise.succeed(try task())
} catch let err {
Expand All @@ -271,9 +273,10 @@ Further information:
promise.fail(error)
}, deadline)

let taskId = task.id
let scheduled = Scheduled(promise: promise, cancellationTask: {
self._tasksLock.withLockVoid {
self._scheduledTasks.remove(task)
self._scheduledTasks.removeFirst(where: { $0.id == taskId })
}
// We don't need to wake up the selector here, the scheduled task will never be picked up. Waking up the
// selector would mean that we may be able to recalculate the shutdown to a later date. The cost of not
Expand Down Expand Up @@ -301,7 +304,7 @@ Further information:
@inlinable
internal func execute(_ task: @escaping () -> Void) {
// nothing we can do if we fail enqueuing here.
try? self._schedule0(ScheduledTask(task, { error in
try? self._schedule0(ScheduledTask(id: self.scheduledTaskCounter.add(1), task, { error in
// do nothing
}, .now()))
}
Expand Down
15 changes: 14 additions & 1 deletion Sources/_NIODataStructures/Heap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Glibc
@usableFromInline
internal struct Heap<Element: Comparable> {
@usableFromInline
internal private(set) var storage: ContiguousArray<Element>
internal private(set) var storage: Array<Element>

@inlinable
internal init() {
Expand Down Expand Up @@ -115,6 +115,19 @@ internal struct Heap<Element: Comparable> {
return false
}
}

@inlinable
internal mutating func removeFirst(where shouldBeRemoved: (Element) throws -> Bool) rethrows {
guard self.storage.count > 0 else {
return
}

guard let index = try self.storage.firstIndex(where: shouldBeRemoved) else {
return
}

self._remove(index: index)
}

@discardableResult
/* private but */ @inlinable
Expand Down
5 changes: 5 additions & 0 deletions Sources/_NIODataStructures/PriorityQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public struct PriorityQueue<Element: Comparable> {
public mutating func remove(_ key: Element) {
self._heap.remove(value: key)
}

@inlinable
public mutating func removeFirst(where shouldBeRemoved: (Element) throws -> Bool) rethrows {
try self._heap.removeFirst(where: shouldBeRemoved)
}

@inlinable
public mutating func push(_ key: Element) {
Expand Down
28 changes: 14 additions & 14 deletions docker/docker-compose.1604.53.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ services:
test:
image: swift-nio:16.04-5.3
environment:
- MAX_ALLOCS_ALLOWED_1000_addHandlers=47050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=48050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=41050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=9050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=29050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=25050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet_sync=0
- MAX_ALLOCS_ALLOWED_1000_getHandlers=9050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=37
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30450
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=38
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30400
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=170050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=163050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12000
- MAX_ALLOCS_ALLOWED_1000_udpbootstraps=2050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=95050
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=450050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=89500
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=428000
- MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2050
- MAX_ALLOCS_ALLOWED_creating_10000_headers=0
- MAX_ALLOCS_ALLOWED_decode_1000_ws_frames=2050
Expand All @@ -50,12 +50,12 @@ services:
- MAX_ALLOCS_ALLOWED_modifying_1000_circular_buffer_elements=0
- MAX_ALLOCS_ALLOWED_modifying_byte_buffer_view=2050
- MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4400
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=190050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=90150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=100050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=20150
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=180050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=80150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=90050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=10150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=188050
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=177050
- SANITIZER_ARG=--sanitize=thread

performance-test:
Expand Down
28 changes: 14 additions & 14 deletions docker/docker-compose.1804.52.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ services:
test:
image: swift-nio:18.04-5.2
environment:
- MAX_ALLOCS_ALLOWED_1000_addHandlers=47050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=48050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=41050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=9050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=32050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=28050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet_sync=0
- MAX_ALLOCS_ALLOWED_1000_getHandlers=9050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=37
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=38
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30450
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=171050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=164050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12000
- MAX_ALLOCS_ALLOWED_1000_udpbootstraps=2050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=96050
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=455000
- MAX_ALLOCS_ALLOWED_1000_udpconnections=90500
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=433000
- MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2050
- MAX_ALLOCS_ALLOWED_creating_10000_headers=0
- MAX_ALLOCS_ALLOWED_decode_1000_ws_frames=2050
Expand All @@ -50,12 +50,12 @@ services:
- MAX_ALLOCS_ALLOWED_modifying_1000_circular_buffer_elements=0
- MAX_ALLOCS_ALLOWED_modifying_byte_buffer_view=2050
- MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4400
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=200050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=90150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=100050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=20150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=188050
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=190050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=80150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=90050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=10150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12150
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=177050
# - SANITIZER_ARG=--sanitize=thread broken on 18.04
- INTEGRATION_TESTS_ARG=-f tests_0[013-9]

Expand Down
28 changes: 14 additions & 14 deletions docker/docker-compose.2004.54.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ services:
test:
image: swift-nio:20.04-5.4
environment:
- MAX_ALLOCS_ALLOWED_1000_addHandlers=47050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=48050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=41050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=9050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=29050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=25050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet_sync=0
- MAX_ALLOCS_ALLOWED_1000_getHandlers=9050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=37
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=38
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30450
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=172050 # regression from 5.3 which was 170050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=165050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12500
- MAX_ALLOCS_ALLOWED_1000_udpbootstraps=2050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=96050
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=453050 # regression from 5.3 which was 450050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=89950
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=431000
- MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2050
- MAX_ALLOCS_ALLOWED_creating_10000_headers=0
- MAX_ALLOCS_ALLOWED_decode_1000_ws_frames=2050
Expand All @@ -50,12 +50,12 @@ services:
- MAX_ALLOCS_ALLOWED_modifying_1000_circular_buffer_elements=0
- MAX_ALLOCS_ALLOWED_modifying_byte_buffer_view=2050
- MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4400
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=190050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=90150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=100050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=20150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=190050
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=180050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=80150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=90050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=10150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12150
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=179050
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

performance-test:
Expand Down
27 changes: 14 additions & 13 deletions docker/docker-compose.2004.55.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,30 @@ services:
test:
image: swift-nio:20.04-5.5
environment:
- MAX_ALLOCS_ALLOWED_1000_addHandlers=47050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=48050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=41050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=9050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=9050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=29050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet=25050
- MAX_ALLOCS_ALLOWED_1000_autoReadGetAndSet_sync=0
- MAX_ALLOCS_ALLOWED_1000_getHandlers=9050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=37
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=38
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=30450
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=172050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=165050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=12050
- MAX_ALLOCS_ALLOWED_1000_udpbootstraps=2050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=96050
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=453000
- MAX_ALLOCS_ALLOWED_1000_udpconnections=90500
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=431000
- MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2050
- MAX_ALLOCS_ALLOWED_creating_10000_headers=0
- MAX_ALLOCS_ALLOWED_decode_1000_ws_frames=2050
- MAX_ALLOCS_ALLOWED_encode_1000_ws_frames_holding_buffer=3
- MAX_ALLOCS_ALLOWED_encode_1000_ws_frames_holding_buffer_with_space=3
- MAX_ALLOCS_ALLOWED_encode_1000_ws_frames_new_buffer=3050
- MAX_ALLOCS_ALLOWED_encode_1000_ws_frames_new_buffer_with_space=3050
- MAX_ALLOCS_ALLOWED_future_erase_result=4050
- MAX_ALLOCS_ALLOWED_future_lots_of_callbacks=60050
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=700050
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form_trimming_whitespace=700050
Expand All @@ -49,12 +50,12 @@ services:
- MAX_ALLOCS_ALLOWED_modifying_1000_circular_buffer_elements=0
- MAX_ALLOCS_ALLOWED_modifying_byte_buffer_view=2050
- MAX_ALLOCS_ALLOWED_ping_pong_1000_reqs_1_conn=4400
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=190050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=90150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=100050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=20150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=190050
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=180050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=80150
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=90050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=10150
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=12150
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=179050
# - SANITIZER_ARG=--sanitize=thread # TSan broken still

performance-test:
Expand Down
Loading

0 comments on commit 7e9b916

Please sign in to comment.