|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, 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: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24: *
25: * IOOutputQueue.h
26: *
27: * HISTORY
28: * 2-Feb-1999 Joe Liu (jliu) created.
29: *
30: */
31:
32: #ifndef _IOOUTPUTQUEUE_H
33: #define _IOOUTPUTQUEUE_H
34:
35: #include <IOKit/network/IOPacketQueue.h>
36: #include <IOKit/network/IONetworkInterface.h>
37:
38: // Forward declarations.
39: //
40: struct mbuf;
41: class IONetworkData;
42:
43: // FIXME - We do not want the enqueue/dequeue macros defined in queue.h.
44: //
45: // #warning queue.h should not be included
46: #undef enqueue(queue,elt)
47: #undef dequeue(queue)
48:
49:
50: /*! @enum IOOQReturnStatus The target's output handler is responsible
51: for generating a return code containing the status, and an action
52: for the queue. The target's output handler must never call any of
53: the queue methods. The defined status codes are:
54: @constant kIOOQReturnStatusMask A mask for the status field in the
55: 32-bit return value.
56: @constant kIOOQReturnStatusSuccess Packet was accepted.
57: @constant kIOOQReturnStatusDropped Packet accepted, but was also
58: dropped.
59: @constant kIOOQReturnStatusRetry Packet not accepted, retry sending the
60: same packet.
61: */
62:
63: enum IOOQReturnStatus {
64: kIOOQReturnStatusMask = 0x00ff,
65: kIOOQReturnStatusSuccess = 0x0000,
66: kIOOQReturnStatusDropped = 0x0001,
67: kIOOQReturnStatusRetry = 0x0002,
68: };
69:
70: /*! @enum IOOQReturnAction The target's output handler is responsible
71: for generating a return code containing the status, and an action
72: for the queue. The target's output handler must never call any of
73: the queue methods. The defined action codes are:
74: @constant kIOOQReturnActionMask A mask for the action field in the
75: 32-bit return value.
76: @constant kIOOQReturnActionNone No action is required.
77: @constant kIOOQReturnActionStall Stall the queue. A service() call
78: will restart the queue.
79: */
80:
81: enum IOOQReturnAction {
82: kIOOQReturnActionMask = 0xff00,
83: kIOOQReturnActionNone = 0x0000,
84: kIOOQReturnActionStall = 0x0100,
85: // kIOOQReturnActionDefer = 0x0200, /* (not used) */
86: };
87:
88: /*
89: * Commonly used return codes containing both a status and an action code.
90: */
91: /*! @constant kIOOQReturnSuccess Same as
92: (kIOOQReturnStatusSuccess | kIOOQReturnActionNone).
93: Packet was accepted. */
94:
95: #define kIOOQReturnSuccess (kIOOQReturnStatusSuccess | kIOOQReturnActionNone)
96:
97: /*! @constant kIOOQReturnDropped Same as
98: (kIOOQReturnStatusDropped | kIOOQReturnActionNone).
99: Packet was dropped. */
100:
101: #define kIOOQReturnDropped (kIOOQReturnStatusDropped | kIOOQReturnActionNone)
102:
103: /*! @constant kIOOQReturnStall Same as
104: (kIOOQReturnStatusRetry | kIOOQReturnActionStall).
105: Stall the queue and retry the same packet when the queue is restarted. */
106:
107: #define kIOOQReturnStall (kIOOQReturnStatusRetry | kIOOQReturnActionStall)
108:
109: /*
110: * Output queue states.
111: */
112: /*! @enum IOOQState
113: @constant kIOOQStateStopped The queue is not running. A start() call
114: will start the queue.
115: @constant kIOOQStateRunning The queue is currently running. A stop()
116: call will stop it.
117: @constant kIOOQStateStalled A running queue was stalled. Call service()
118: or stop(), to respectively restart or stop the queue. */
119:
120: enum IOOQState {
121: kIOOQStateStopped = 0,
122: kIOOQStateRunning,
123: kIOOQStateStalled,
124: };
125:
126:
127: /*! @class IOOutputQueue
128: @abstract An object that queues output packets on behalf of its target,
129: usually an IONetworkController instance, and allows the target to control
130: the packet flow. IOOutputQueue is is an abstract class that provides an
131: interface for its subclasses. Concrete subclasses will complete the
132: implementation while providing unique synchronization options.
133: */
134:
135: class IOOutputQueue : public OSObject
136: {
137: OSDeclareAbstractStructors(IOOutputQueue)
138:
139: private:
140: IOReturn dataReadAndResetHandler(IONetworkData * data,
141: UInt32 opFlag,
142: void * arg);
143:
144: protected:
145: OSObject * _target; // target object.
146: IOOutputAction _outAction; // target's output function.
147: volatile IOOQState _state; // queue's state.
148: IOOutputQueueStats * _stats; // output queue statistics.
149: IONetworkData * _statsData; // statistics data object.
150: thread_call_t _callEntry; // callout entry structure.
151: IOPacketQueue * _queue; // packet queue.
152:
153: /*! @function init
154: @discussion Initialize an IOOutputQueue instance.
155: @param target The object that shall receive packets from the queue,
156: and is usually a subclass of IONetworkController. If the target is
157: not an IONetworkController instance, then the target must immediately
158: call registerOutputHandler() after initializing the queue.
159: @param capacity The initial capacity of the output queue, defined as
160: the number of packets that the queue can hold without dropping.
161: @result true if initialized successfully, false otherwise. */
162:
163: virtual bool init(OSObject * target, UInt32 capacity);
164:
165: /*! @function free
166: @discussion Frees the IOOutputQueue instance. */
167:
168: virtual void free();
169:
170: /*! @function runServiceThread
171: @discussion A glue function that is registered as the service thread
172: callout handler. This function in turn will call the serviceThread()
173: method.
174: @param self An argument previously registered with the callout to
175: identify the IOOutputQueue instance associated with the callout. */
176:
177: static void runServiceThread(IOOutputQueue * self, thread_call_param_t);
178:
179: /*! @function scheduleServiceThread
180: @discussion Schedule a service thread callout, which will then
181: execute the serviceThread() method. Subclasses should not override
182: this method.
183: @result true if scheduling the thread callout was successful, false
184: otherwise. */
185:
186: virtual bool scheduleServiceThread();
187:
188: /*! @function cancelServiceThread
189: @discussion Cancel the service thread callout. Subclasses should not
190: override this method.
191: @result true if a previously scheduled thread callout was canceled,
192: false otherwise. */
193:
194: virtual bool cancelServiceThread();
195:
196: /*! @function serviceThread
197: @discussion Must be implemented by subclasses that calls
198: scheduleServiceThread(). The default implementation is a placeholder and
199: performs no useful action. */
200:
201: virtual void serviceThread();
202:
203: /*! @function createPacketQueue
204: @discussion Allows subclasses to override the default action, which
205: is to allocate and return an IOPacketQueue instance. The returned
206: object is used to implement the queueing behavior of the IOOutputQueue.
207: @param capacity The initial capacity of the queue.
208: @result A newly allocated and initialized IOPacketQueue instance. */
209:
210: virtual IOPacketQueue * createPacketQueue(UInt32 capacity) const;
211:
212: public:
213:
214: /*! @function enqueue
215: @discussion Handles packet (or a packet chain) sent to the queue.
216: This method can handle calls from multiple simultaneous client threads.
217: A pointer to this function is written to the "output" field in the
218: IOOutputHandler structure by getOutputHandler(), thus allowing client
219: objects to call this method in order to process the output packet.
220: @param m The packet (or a packet chain) to be queued for transmission.
221: @result The number of dropped packets. */
222:
223: virtual UInt32 enqueue(struct mbuf * m) = 0;
224:
225: /*! @function start
226: @discussion This method is called by the target to start the queue.
227: Once started, the queue will be allowed to call the target's
228: output handler. Before that, with the queue stopped, the queue will
229: absorb incoming packets sent to the enqueue() method, but no packets
230: will be dequeued, and the target's output handler will not be called.
231: @result true if the queue was successfully started, false otherwise. */
232:
233: virtual bool start() = 0;
234:
235: /*! @function stop
236: @discussion Stops the queue to prevent it from calling the target's
237: output handler. This call is synchronous the caller may block.
238: The target's output handler must never call this method, or any other
239: queue methods. */
240:
241: virtual void stop() = 0;
242:
243: /*! @function service
244: @discussion If the queue becomes stalled, then service() must be called
245: to restart the queue when the target is ready to accept more packets.
246: Note that if the target never sends a kIOOQReturnActionStall action code
247: to the queue, then the queue will never stall on its own accord.
248: Calling this method on a running queue that is not stalled is harmless.
249: @param sync True if the service action should be performed synchronously,
250: false to perform the action asynchronously without blocking the caller,
251: but with a much higher latency cost.
252: @result true if the queue needed servicing, false otherwise. */
253:
254: virtual bool service(bool sync = true) = 0;
255:
256: /*! @function flush
257: @discussion Release all packets held in the queue. The size of the queue
258: is reset to zero. The drop packet counter is incremented by the number
259: of packets freed. See getDropCount().
260: @result The number of packets freed. */
261:
262: virtual UInt32 flush();
263:
264: /*! @function getState
265: @result The current state of the queue object. See IOOQState enumeration.
266: */
267:
268: virtual IOOQState getState() const;
269:
270: /*! @function setCapacity
271: @param capacity The new capacity of the queue.
272: @result true if the new capacity was accepted, false otherwise. */
273:
274: virtual bool setCapacity(UInt32 capacity);
275:
276: /*! @function getCapacity
277: @result The current queue capacity. */
278:
279: virtual UInt32 getCapacity() const;
280:
281: /*! @function getSize
282: @result The current queue size. */
283:
284: virtual UInt32 getSize() const;
285:
286: /*! @function getPeakSize
287: @param reset Resets the counter if true.
288: @result The peak queue size. */
289:
290: virtual UInt32 getPeakSize(bool reset = false);
291:
292: /*! @function getDropCount
293: @discussion This method returns the number of times that a
294: kIOOQReturnStatusDropped status code is received from the target's
295: output handler, indicating that the packet given was dropped. This
296: count is also incremented when the queue drops a packet due to
297: overcapacity, or by an explicit flush() call.
298: @param reset Resets the counter if true.
299: @result The number of dropped packets. */
300:
301: virtual UInt32 getDropCount(bool reset = false);
302:
303: /*! @function getOutputCount
304: @discussion This method returns the number of times that a
305: kIOOQReturnStatusSuccess status code is received from the target's
306: output handler, indicating that the packet given was accepted,
307: and is ready to be (or already has been) transmitted.
308: @param reset Resets the counter if true.
309: @result The number of packets accepted by our target. */
310:
311: virtual UInt32 getOutputCount(bool reset = false);
312:
313: /*! @function getRetryCount
314: @discussion This method returns the number of times that a
315: kIOOQReturnStatusRetry status code is received from the target's
316: output handler, indicating that the target is temporarily unable
317: to handle the packet given, and the queue should try to resend the
318: same packet at some later time.
319: @param reset Resets the counter if true.
320: @result The number of retries issued by the target. */
321:
322: virtual UInt32 getRetryCount(bool reset = false);
323:
324: /*! @function getStallCount
325: @discussion Each time the queue is stalled, when a kIOOQReturnActionStall
326: action code is received from the target's output handler, a counter is
327: incremented. This method returns the value stored in this counter.
328: @param reset Resets the counter if true.
329: @result The number of times that the queue was stalled. */
330:
331: virtual UInt32 getStallCount(bool reset = false);
332:
333: /*! @function registerOutputHandler
334: @discussion Register the target object and method to call to
335: handle packets removed from the queue.
336: @param target Target object that implements the output action.
337: @param action The action to call to handle the output packet.
338: @result true if the handler provided was accepted, false otherwise. */
339:
340: virtual bool registerOutputHandler(OSObject * target,
341: IOOutputAction action);
342:
343: /*! @function getOutputHandler
344: @discussion Return an address of a method that is designated to handle
345: packets sent to the queue object.
346: @result Address of the output packet handler. */
347:
348: IOOutputAction getOutputHandler() const;
349:
350: /*! @function getStatisticsData
351: @result An IONetworkData object containing an IOOutputQueueStats structure.
352: */
353:
354: IONetworkData * getStatisticsData() const;
355: };
356:
357: #endif /* !_IOOUTPUTQUEUE_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.