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 _IOPACKETQUEUE_H
24#define _IOPACKETQUEUE_H
25
26#include <libkern/c++/OSObject.h>
27#include <IOKit/IOLocks.h>
28extern "C" {
29#include <sys/kpi_mbuf.h>
30}
31// Forward declarations.
32//
33struct mbuf;
34struct IOMbufQueue;
35
36// We do not want the enqueue/dequeue macros defined in queue.h.
37//
38// #warning queue.h should not be included
39#undef enqueue
40#undef dequeue
41
42/*! @class IOPacketQueue
43    @abstract Implements a bounded FIFO queue of mbuf packets.
44    @discussion Packets are
45    removed from the head of the queue (dequeue), and new packets are added
46    to the tail of the queue (enqueue). A spinlock is used to synchronize
47    access to the queue between methods that have a "lock" prefix.
48*/
49
50class IOPacketQueue : public OSObject
51{
52    OSDeclareDefaultStructors( IOPacketQueue )
53
54protected:
55    IOMbufQueue *   _queue;   // mbuf queue
56    IOSimpleLock *  _lock;    // spinlock for synchronized methods
57
58    struct ExpansionData { };
59    /*! @var reserved
60        Reserved for future use.  (Internal use only)  */
61    ExpansionData *_reserved;
62
63/*! @function free
64    @abstract Frees the IOPacketQueue object.
65    @discussion All packets held by the queue are released back to the free
66    pool, resource are deallocated, then super::free() is called.
67*/
68
69    virtual void free();
70
71/*! @var IOPacketQueueDefaultCapacity
72    @abstract Describes the default capacity of the
73    queue object.
74    @discussion The capacity is only observed by the enqueue() method.
75    Therefore, it is possible for the size of the queue to exceed its
76    capacity when other methods, such as prepend(), are used to add packets
77    to the queue.
78*/
79
80    static const UInt32 IOPacketQueueDefaultCapacity = 100;
81
82public:
83
84/*! @function withCapacity
85    @abstract Factory method that constructs and initializes an
86    IOPacketQueue object.
87    @param capacity The initial capacity of the queue object. Can be
88    later changed by calling the setCapacity() method.
89    @result Returns an IOPacketQueue instance on success, or 0 otherwise.
90*/
91
92    static IOPacketQueue * withCapacity(UInt32 capacity =
93                                        IOPacketQueueDefaultCapacity);
94
95/*! @function initWithCapacity
96    @abstract Initializes an IOPacketQueue object.
97    @discussion This method initializes an IOPacketQueue object with the given capacity.
98    @param capacity The initial capacity of the queue. Can be later changed
99    by calling the setCapacity() method.
100    @result Returns true if initialized successfully, false otherwise.
101*/
102
103    virtual bool initWithCapacity(UInt32 capacity =
104                                  IOPacketQueueDefaultCapacity);
105
106/*! @function getSize
107    @abstract Gets the size of the queue.
108    @result Returns the number of packets currently held by the queue.
109*/
110
111    virtual UInt32 getSize() const;
112
113/*! @function setCapacity
114    @abstract Changes the capacity of the queue.
115    @param capacity The new capacity.
116    @result Returns true if the new capacity was accepted, false otherwise.
117*/
118
119    virtual bool setCapacity(UInt32 capacity);
120
121/*! @function getCapacity
122    @abstract Gets the current capacity of the queue.
123    @result Returns the current queue capacity.
124*/
125
126    virtual UInt32 getCapacity() const;
127
128/*! @function peek
129    @abstract Examines the packet at the head of the queue without
130    removing it from the queue.
131    @discussion A following call to peek() or dequeue() will return
132    the same packet. The caller must never modify the mbuf packet returned.
133    @result Returns the packet at the head of the queue.
134*/
135
136    virtual const mbuf_t peek() const;
137
138/*! @function prepend
139    @abstract Adds a chain of packets to the head of the queue.
140    @param m A chain of packets to add to the head of the queue.
141*/
142
143    virtual void prepend(mbuf_t m);
144
145/*! @function prepend
146    @abstract Removes all packets from the specified queue, and adds them
147    to the head of this queue.
148    @param queue The source IOPacketQueue object containing the packets to
149    be transferred.
150*/
151
152    virtual void prepend(IOPacketQueue * queue);
153
154/*! @function lockPrepend
155    @abstract Adds a chain of packets to the head of a synchronized queue.
156    @discussion A spinlock is used to synchronize access to the queue.
157    @param m A chain of packets to add to the head of the queue.
158    @result Always returns true.
159*/
160
161    virtual void lockPrepend(mbuf_t m);
162
163/*! @function enqueue
164    @abstract Adds a chain of packets to the tail of the queue.
165    @discussion Packets are not added if the size of the queue has reached
166    its capacity.
167    @param m A chain of packets to add to the tail of the queue.
168    @result Returns true on success, or false to indicate over-capacity and refusal
169    to accept the packet chain provided.
170*/
171
172    virtual bool enqueue(mbuf_t m);
173
174/*! @function enqueue
175    @abstract Removes all packets from the specified queue, and adds them
176    to the tail of this queue.
177    @param queue The source IOPacketQueue object containing the packets to
178    be transferred.
179    @result Always returns true.
180*/
181
182    virtual bool enqueue(IOPacketQueue * queue);
183
184/*! @function enqueueWithDrop
185    @abstract Adds a chain of packets to the tail of the queue.
186    @discussion Packets are
187    dropped if the size of the queue has reached its capacity.
188    @param m A chain of packets to add to the tail of the queue.
189    @result Returns the number of packets dropped and freed by the queue.
190*/
191
192    virtual UInt32 enqueueWithDrop(mbuf_t m);
193
194/*! @function lockEnqueue
195    @abstract Adds a chain of packets to the tail of a synchronized queue.
196    @discussion Packets are not added if the size of the queue has reached
197    its capacity. A spinlock is used to synchronize access to the queue.
198    @param m A chain of packets to add to the tail of the queue.
199    @result Returns true on success, or false to indicate over-capacity and refusal
200    to accept the packet chain provided.
201*/
202
203    virtual bool lockEnqueue(mbuf_t m);
204
205/*! @function lockEnqueueWithDrop
206    @abstract Adds a chain of packets to the tail of a synchronized queue.
207    @discussion Packets are dropped if the size of the queue has reached its capacity.  A spinlock is used to synchronize access to the queue.
208    @param m A chain of packets to add to the tail of the queue.
209    @result Returns the number of packets dropped and freed by the queue.
210*/
211
212    virtual UInt32 lockEnqueueWithDrop(mbuf_t m);
213
214/*! @function dequeue
215    @abstract Removes a single packet from the head of the queue.
216    @result Returns a packet removed from the head of the queue, or NULL if the
217    queue was empty.
218*/
219
220    virtual mbuf_t dequeue();
221
222/*! @function lockDequeue
223    @abstract Removes a single packet from the head of a synchronized queue.
224    @discussion A spinlock is used to synchronize access to the queue.
225    @result Returns a packet removed from the head of the queue, or NULL if the
226    queue was empty.
227*/
228
229    virtual mbuf_t lockDequeue();
230
231/*! @function dequeueAll
232    @abstract Removes all packets from the queue and returns the head of the
233    packet chain.
234    @discussion The size of the queue is cleared to zero.
235    @result Returns the head of a packet chain linking all packets that were held
236    in the queue, or NULL if the queue was empty.
237*/
238
239    virtual mbuf_t dequeueAll();
240
241/*! @function lockDequeueAll
242    @abstract Removes all packets from a synchronized queue and returns the
243    head of the packet chain.
244    @discussion The size of the queue is cleared to zero. A spinlock is used
245    to synchronize access to the queue.
246    @result Returns the head of a packet chain linking all packets that were held
247    in the queue, or NULL if the queue was empty.
248*/
249
250    virtual mbuf_t lockDequeueAll();
251
252/*! @function flush
253    @abstract Frees all packets currently held in the queue and releases them
254    back to the free mbuf pool.
255    @discussion The size of the queue is cleared to zero.
256    @result Returns the number of packets freed.
257*/
258
259    virtual UInt32 flush();
260
261/*! @function lockFlush
262    @abstract Frees all packets currently held in a synchronized queue and
263    releases them back to the free mbuf pool.
264    @discussion The size of the queue is cleared to zero. A spinlock is used
265    to synchronize access to the queue.
266    @result Returns the number of packets freed.
267*/
268
269    virtual UInt32 lockFlush();
270
271    // Virtual Pad functions
272    OSMetaClassDeclareReservedUnused( IOPacketQueue,  0);
273    OSMetaClassDeclareReservedUnused( IOPacketQueue,  1);
274    OSMetaClassDeclareReservedUnused( IOPacketQueue,  2);
275    OSMetaClassDeclareReservedUnused( IOPacketQueue,  3);
276    OSMetaClassDeclareReservedUnused( IOPacketQueue,  4);
277    OSMetaClassDeclareReservedUnused( IOPacketQueue,  5);
278    OSMetaClassDeclareReservedUnused( IOPacketQueue,  6);
279    OSMetaClassDeclareReservedUnused( IOPacketQueue,  7);
280    OSMetaClassDeclareReservedUnused( IOPacketQueue,  8);
281    OSMetaClassDeclareReservedUnused( IOPacketQueue,  9);
282    OSMetaClassDeclareReservedUnused( IOPacketQueue, 10);
283    OSMetaClassDeclareReservedUnused( IOPacketQueue, 11);
284    OSMetaClassDeclareReservedUnused( IOPacketQueue, 12);
285    OSMetaClassDeclareReservedUnused( IOPacketQueue, 13);
286    OSMetaClassDeclareReservedUnused( IOPacketQueue, 14);
287    OSMetaClassDeclareReservedUnused( IOPacketQueue, 15);
288};
289
290#endif /* !_IOPACKETQUEUE_H */
291