Root/
Source at commit 1086 created 13 years 14 hours ago. By meklort, More disk changes... more to come too | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1998-2008 Apple Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * The contents of this file constitute Original Code as defined in and␊ |
7 | * are subject to the Apple Public Source License Version 1.1 (the␊ |
8 | * "License"). You may not use this file except in compliance with the␊ |
9 | * License. Please obtain a copy of the License at␊ |
10 | * http://www.apple.com/publicsource and read it before using this file.␊ |
11 | * ␊ |
12 | * This Original Code and all software distributed under the License are␊ |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
17 | * License for the specific language governing rights and limitations␊ |
18 | * under the License.␊ |
19 | * ␊ |
20 | * @APPLE_LICENSE_HEADER_END@␊ |
21 | */␊ |
22 | ␊ |
23 | #ifndef _IOBASICOUTPUTQUEUE_H␊ |
24 | #define _IOBASICOUTPUTQUEUE_H␊ |
25 | ␊ |
26 | #include <IOKit/IOLocks.h>␊ |
27 | #include <IOKit/network/IOOutputQueue.h>␊ |
28 | #include <IOKit/network/IOPacketQueue.h> // FIXME - remove␊ |
29 | ␊ |
30 | struct IOMbufQueue;␊ |
31 | ␊ |
32 | /*! @class IOBasicOutputQueue␊ |
33 | @abstract A concrete implementation of an IOOutputQueue. ␊ |
34 | @discussion This object uses a spinlock to protect the packet queue from multiple producers.␊ |
35 | A single producer is promoted to become a consumer when the queue is␊ |
36 | not active. Otherwise, the producer will simply queue the packet and␊ |
37 | return without blocking.␊ |
38 | ␊ |
39 | The flow of packets from the queue to its target can be controlled␊ |
40 | by calling methods such as start(), stop(), or service(). The target␊ |
41 | is expected to call those methods from a single threaded context,␊ |
42 | i.e. the work loop context in a network driver. In addition, the␊ |
43 | target must also return a status for every packet delivered by the␊ |
44 | consumer thread. This return value is the only mechanism that the␊ |
45 | target can use to manage the queue when it is running on the␊ |
46 | consumer thread. ␊ |
47 | */␊ |
48 | ␊ |
49 | class IOBasicOutputQueue : public IOOutputQueue␊ |
50 | {␊ |
51 | OSDeclareDefaultStructors( IOBasicOutputQueue )␊ |
52 | ␊ |
53 | private:␊ |
54 | ␉static IOReturn dispatchNetworkDataNotification(void * target,␊ |
55 | void * param,␊ |
56 | IONetworkData * data,␊ |
57 | UInt32 type);␊ |
58 | ␊ |
59 | void dequeue();␊ |
60 | ␊ |
61 | protected:␊ |
62 | OSObject * _target;␊ |
63 | IOOutputAction _action;␊ |
64 | IOOutputQueueStats * _stats;␊ |
65 | IONetworkData * _statsData;␊ |
66 | ␉IOSimpleLock * _spinlock;␊ |
67 | IOMbufQueue * _inQueue;␊ |
68 | IOMbufQueue * _queues[2];␊ |
69 | volatile bool _waitDequeueDone;␊ |
70 | volatile UInt32 _state;␊ |
71 | volatile UInt32 _serviceCount;␊ |
72 | ␊ |
73 | /*! @function serviceThread␊ |
74 | @abstract Provides an implementation for the serviceThread() method␊ |
75 | defined in IOOutputQueue.␊ |
76 | @discussion This method is called by the scheduled service thread when it␊ |
77 | starts to run. The service thread is scheduled by service()␊ |
78 | to restart a stalled queue when the kServiceAsync option is given.␊ |
79 | @param param A parameter that was given to scheduleServiceThread().␊ |
80 | This parameter is not used. ␊ |
81 | */␊ |
82 | ␊ |
83 | virtual void serviceThread(void * param);␊ |
84 | ␊ |
85 | /*! @function output␊ |
86 | @abstract Transfers all packets in the mbuf queue to the target.␊ |
87 | @param queue A queue of output packets.␊ |
88 | @param state Returns a state bit defined by IOBasicOutputQueue that␊ |
89 | declares the new state of the queue following this method call.␊ |
90 | A kStateStalled is returned if the queue should stall, otherwise 0␊ |
91 | is returned. ␊ |
92 | */␊ |
93 | ␊ |
94 | virtual void output(IOMbufQueue * queue, UInt32 * state);␊ |
95 | ␊ |
96 | /*! @function free␊ |
97 | @abstract Frees the IOBasicOutputQueue object.␊ |
98 | @discussion This function releases allocated resources, then call super::free(). ␊ |
99 | */␊ |
100 | ␊ |
101 | virtual void free();␊ |
102 | ␊ |
103 | /*! @function handleNetworkDataAccess␊ |
104 | @abstract Handles an external access to the IONetworkData object␊ |
105 | returned by getStatisticsData().␊ |
106 | @param data The IONetworkData object being accessed.␊ |
107 | @param type Description of the type of access being performed.␊ |
108 | @param param An optional parameter for the handler.␊ |
109 | @result Returns kIOReturnSuccess on success, or an error code otherwise.␊ |
110 | */␊ |
111 | ␊ |
112 | virtual IOReturn handleNetworkDataAccess(IONetworkData * data,␊ |
113 | UInt32 type,␊ |
114 | void * param);␊ |
115 | ␊ |
116 | public:␊ |
117 | ␊ |
118 | /*! @function init␊ |
119 | @abstract Initializes an IOBasicOutputQueue object.␊ |
120 | @param target The object that will handle packets removed from the␊ |
121 | queue, which is usually a subclass of IONetworkController.␊ |
122 | @param action The function that will handle packets removed from the␊ |
123 | queue.␊ |
124 | @param capacity The initial capacity of the output queue.␊ |
125 | @result Returns true if initialized successfully, false otherwise. ␊ |
126 | */␊ |
127 | ␊ |
128 | virtual bool init(OSObject * target,␊ |
129 | IOOutputAction action,␊ |
130 | UInt32 capacity = 0);␊ |
131 | ␊ |
132 | /*! @function withTarget␊ |
133 | @abstract Factory method that constructs and initializes an␊ |
134 | IOBasicOutputQueue object.␊ |
135 | @param target An IONetworkController object that will handle packets␊ |
136 | removed from the queue.␊ |
137 | @param capacity The initial capacity of the output queue.␊ |
138 | @result Returns an IOBasicOutputQueue object on success, or 0 otherwise. ␊ |
139 | */␊ |
140 | ␊ |
141 | static IOBasicOutputQueue * withTarget(IONetworkController * target,␊ |
142 | UInt32 capacity = 0);␊ |
143 | ␊ |
144 | /*! @function withTarget␊ |
145 | @abstract Factory method that constructs and initializes an␊ |
146 | IOBasicOutputQueue object.␊ |
147 | @param target The object that will handle packets removed from the␊ |
148 | queue.␊ |
149 | @param action The function that will handle packets removed from the␊ |
150 | queue.␊ |
151 | @param capacity The initial capacity of the output queue.␊ |
152 | @result Returns an IOBasicOutputQueue object on success, or 0 otherwise. ␊ |
153 | */␊ |
154 | ␊ |
155 | static IOBasicOutputQueue * withTarget(OSObject * target,␊ |
156 | IOOutputAction action,␊ |
157 | UInt32 capacity = 0);␊ |
158 | ␊ |
159 | /*! @function enqueue␊ |
160 | @abstract Adds a packet, or a chain of packets,␊ |
161 | to the queue.␊ |
162 | @discussion This method is called by a client to add a packet, or a chain of packets,␊ |
163 | to the queue. A packet is described by an mbuf chain, while a chain␊ |
164 | of packets is constructed by linking multiple mbuf chains via the␊ |
165 | m_nextpkt field. This method can be called by multiple client␊ |
166 | threads.␊ |
167 | @param m A single packet, or a chain of packets.␊ |
168 | @param param A parameter provided by the caller.␊ |
169 | @result Always returns 0. ␊ |
170 | */␊ |
171 | ␊ |
172 | virtual UInt32 enqueue(mbuf_t m, void * param);␊ |
173 | ␊ |
174 | /*! @function start␊ |
175 | @abstract Starts up the packet flow between the queue and its target.␊ |
176 | @discussion Called by the target to start the queue. This will allow␊ |
177 | packets to be removed from the queue, and then delivered to the target.␊ |
178 | @result Returns true if the queue was started successfully, false otherwise. */␊ |
179 | ␊ |
180 | virtual bool start();␊ |
181 | ␊ |
182 | /*! @function stop␊ |
183 | @abstract Stops the packet flow between the queue and its target.␊ |
184 | @discussion This method stops the queue and prevents it from sending packets to its␊ |
185 | target. This call is synchronous and it may block. After this method␊ |
186 | returns, the queue will no longer call the registered target/action,␊ |
187 | even as new packets are added to the queue. The queue will continue to␊ |
188 | absorb new packets until the size of the queue reaches its capacity.␊ |
189 | The registered action must never call stop(), or a deadlock will occur.␊ |
190 | @result Returns the previous running state of the queue,␊ |
191 | true if the queue was running, false if the queue was already stopped. ␊ |
192 | */␊ |
193 | ␊ |
194 | virtual bool stop();␊ |
195 | ␊ |
196 | /*! @enum ServiceAsync␊ |
197 | @abstract The option bits recognized by service().␊ |
198 | @constant kServiceAsync Set this option to service the queue in␊ |
199 | an asynchronous manner. The service() call will not block, but a␊ |
200 | scheduling latency will be introduced before the queue is serviced. ␊ |
201 | */␊ |
202 | ␊ |
203 | enum {␊ |
204 | kServiceAsync = 0x1␊ |
205 | };␊ |
206 | ␊ |
207 | /*! @function service␊ |
208 | @abstract Services a queue that was stalled by the target.␊ |
209 | @discussion A target that stalls the queue must call service() when␊ |
210 | it becomes ready to accept more packets. Calling this method when the␊ |
211 | queue is not stalled is harmless.␊ |
212 | @result Returns true if the queue was stalled and there were packets sitting in␊ |
213 | the queue awaiting delivery, false otherwise. ␊ |
214 | */␊ |
215 | ␊ |
216 | virtual bool service(IOOptionBits options = 0);␊ |
217 | ␊ |
218 | /*! @function flush␊ |
219 | @abstract Drops and frees all packets currently held by the queue.␊ |
220 | @discussion To ensure that all packets are removed from the queue,␊ |
221 | stop() should be called prior to flush(), to make sure there are␊ |
222 | no packets in-flight and being delivered to the target.␊ |
223 | @result Returns the number of packets that were dropped and freed. ␊ |
224 | */␊ |
225 | ␊ |
226 | virtual UInt32 flush();␊ |
227 | ␊ |
228 | /*! @function setCapacity␊ |
229 | @abstract Changes the number of packets that the queue can hold␊ |
230 | before it begins to drop excess packets.␊ |
231 | @param capacity The new desired capacity.␊ |
232 | @result Returns true if the new capacity was accepted, false otherwise. ␊ |
233 | */␊ |
234 | ␊ |
235 | virtual bool setCapacity(UInt32 capacity);␊ |
236 | ␊ |
237 | /*! @function getCapacity␊ |
238 | @abstract Gets the number of packets that the queue can hold.␊ |
239 | @discussion The queue will begin to drop incoming packets when the␊ |
240 | size of the queue reaches its capacity.␊ |
241 | @result Returns the current queue capacity. ␊ |
242 | */␊ |
243 | ␊ |
244 | virtual UInt32 getCapacity() const;␊ |
245 | ␊ |
246 | /*! @function getSize␊ |
247 | @abstract Gets the number of packets currently held in the queue.␊ |
248 | @result Returns the size of the queue. ␊ |
249 | */␊ |
250 | ␊ |
251 | virtual UInt32 getSize() const;␊ |
252 | ␊ |
253 | /*! @function getDropCount␊ |
254 | @abstract Gets the number of packets dropped by the queue.␊ |
255 | @result Returns the number of packets dropped due to over-capacity, or by␊ |
256 | external calls to the flush() method. ␊ |
257 | */␊ |
258 | ␊ |
259 | virtual UInt32 getDropCount();␊ |
260 | ␊ |
261 | /*! @function getOutputCount␊ |
262 | @abstract Gets the number of packets accepted by the target.␊ |
263 | @result Returns the number of times that kIOOutputStatusAccepted is returned by␊ |
264 | the target. ␊ |
265 | */␊ |
266 | ␊ |
267 | virtual UInt32 getOutputCount();␊ |
268 | ␊ |
269 | /*! @function getRetryCount␊ |
270 | @abstract Gets the number of instances when the target has refused to␊ |
271 | accept the packet provided.␊ |
272 | @result Returns the number of times that kIOOutputStatusRetry is returned by the␊ |
273 | target. ␊ |
274 | */␊ |
275 | ␊ |
276 | virtual UInt32 getRetryCount();␊ |
277 | ␊ |
278 | /*! @function getStallCount␊ |
279 | @abstract Gets the number of instances when the target has stalled the␊ |
280 | queue.␊ |
281 | @result Returns the number of times that kIOOutputCommandStall is returned by the␊ |
282 | target. ␊ |
283 | */␊ |
284 | ␊ |
285 | virtual UInt32 getStallCount();␊ |
286 | ␊ |
287 | /*! @enum GetStateBits␊ |
288 | @abstract The bits in the value returned by getState().␊ |
289 | @constant kStateRunning Set when the queue is running. Calling start()␊ |
290 | and stop() will set or clear this bit.␊ |
291 | @constant kStateStalled Set when the queue is stalled by the target.␊ |
292 | @constant kStateActive Set when a consumer thread is actively removing␊ |
293 | packets from the queue and passing them to the target. ␊ |
294 | */␊ |
295 | ␊ |
296 | enum {␊ |
297 | kStateRunning = 0x1,␊ |
298 | kStateOutputStalled = 0x2,␊ |
299 | kStateOutputActive = 0x4,␊ |
300 | kStateOutputServiceMask = 0xff00␊ |
301 | };␊ |
302 | ␊ |
303 | /*! @function getState␊ |
304 | @abstract Gets the state of the queue object.␊ |
305 | @result Returns the current state of the queue object. ␊ |
306 | */ ␊ |
307 | ␊ |
308 | virtual UInt32 getState() const;␊ |
309 | ␊ |
310 | /*! @function getStatisticsData␊ |
311 | @abstract Returns an IONetworkData object containing statistics counters␊ |
312 | updated by the queue.␊ |
313 | @result Returns an IONetworkData object. ␊ |
314 | */␊ |
315 | ␊ |
316 | ␉virtual IONetworkData * getStatisticsData() const;␊ |
317 | };␊ |
318 | ␊ |
319 | #endif /* !_IOBASICOUTPUTQUEUE_H */␊ |
320 |