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