forked from microsoft/msquic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworker.h
196 lines (165 loc) · 4.07 KB
/
worker.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
--*/
//
// A worker thread for draining queued operations on a connection.
//
typedef struct QUIC_CACHEALIGN QUIC_WORKER {
//
// Context for execution callbacks and state management.
//
CXPLAT_EXECUTION_CONTEXT ExecutionContext;
//
// Event to signal when the execution context (i.e. worker thread) is
// complete.
//
CXPLAT_EVENT Done;
//
// Indicates if this work is handled by an external (to QUIC) execution context.
//
BOOLEAN IsExternal;
//
// TRUE if the worker is currently running.
//
BOOLEAN Enabled;
//
// TRUE if the worker is currently processing connections.
//
BOOLEAN IsActive;
//
// The index into the partition array (of processors).
//
uint16_t PartitionIndex;
//
// The average queue delay connections experience, in microseconds.
//
uint32_t AverageQueueDelay;
//
// Timers for the worker's connections.
//
QUIC_TIMER_WHEEL TimerWheel;
//
// An event to kick the thread.
//
CXPLAT_EVENT Ready;
//
// A thread for draining operations from queued connections.
//
CXPLAT_THREAD Thread;
//
// Serializes access to the connection and operation lists.
//
CXPLAT_DISPATCH_LOCK Lock;
//
// Queue of connections with operations to be processed.
//
CXPLAT_LIST_ENTRY Connections;
//
// Queue of stateless operations to be processed.
//
CXPLAT_LIST_ENTRY Operations;
uint32_t OperationCount;
uint64_t DroppedOperationCount;
CXPLAT_POOL StreamPool; // QUIC_STREAM
CXPLAT_POOL DefaultReceiveBufferPool; // QUIC_DEFAULT_STREAM_RECV_BUFFER_SIZE
CXPLAT_POOL SendRequestPool; // QUIC_SEND_REQUEST
QUIC_SENT_PACKET_POOL SentPacketPool; // QUIC_SENT_PACKET_METADATA
CXPLAT_POOL ApiContextPool; // QUIC_API_CONTEXT
CXPLAT_POOL StatelessContextPool; // QUIC_STATELESS_CONTEXT
CXPLAT_POOL OperPool; // QUIC_OPERATION
} QUIC_WORKER;
//
// A set of workers.
//
typedef struct QUIC_WORKER_POOL {
//
// Number of workers in the pool.
//
uint16_t WorkerCount;
//
// Last least loaded worker.
//
uint16_t LastWorker;
//
// All the workers.
//
_Field_size_(WorkerCount)
QUIC_WORKER Workers[0];
} QUIC_WORKER_POOL;
//
// Returns TRUE if the worker is currently overloaded and shouldn't take on more
// work, if at all possible.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
inline
BOOLEAN
QuicWorkerIsOverloaded(
_In_ QUIC_WORKER* Worker
)
{
return Worker->AverageQueueDelay > MsQuicLib.Settings.MaxWorkerQueueDelayUs;
}
//
// Initializes the worker pool.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicWorkerPoolInitialize(
_In_ const QUIC_REGISTRATION* Registration,
_In_ QUIC_EXECUTION_PROFILE ExecProfile,
_Out_ QUIC_WORKER_POOL** WorkerPool
);
//
// Cleans up the worker pool.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
void
QuicWorkerPoolUninitialize(
_In_ QUIC_WORKER_POOL* WorkerPool
);
//
// Returns TRUE if the all the workers in the pool are currently overloaded.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
QuicWorkerPoolIsOverloaded(
_In_ QUIC_WORKER_POOL* WorkerPool
);
//
// Gets the worker index with the smallest current load.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
uint16_t
QuicWorkerPoolGetLeastLoadedWorker(
_In_ QUIC_WORKER_POOL* WorkerPool
);
//
// Assigns the connection to a worker.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
void
QuicWorkerAssignConnection(
_In_ QUIC_WORKER* Worker,
_In_ QUIC_CONNECTION* Connection
);
//
// Queues the connection onto the worker, and kicks the worker thread if
// necessary.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
void
QuicWorkerQueueConnection(
_In_ QUIC_WORKER* Worker,
_In_ QUIC_CONNECTION* Connection
);
//
// Queues the operation onto the worker, and kicks the worker thread if
// necessary.
//
_IRQL_requires_max_(DISPATCH_LEVEL)
void
QuicWorkerQueueOperation(
_In_ QUIC_WORKER* Worker,
_In_ QUIC_OPERATION* Operation
);