2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <IOKit/IOSharedDataQueue.h>
30 #include <IOKit/IODataQueueShared.h>
31 #include <IOKit/IOLib.h>
32 #include <IOKit/IOMemoryDescriptor.h>
38 #define super IODataQueue
40 OSDefineMetaClassAndStructors(IOSharedDataQueue
, IODataQueue
)
42 IOSharedDataQueue
*IOSharedDataQueue::withCapacity(UInt32 size
)
44 IOSharedDataQueue
*dataQueue
= new IOSharedDataQueue
;
47 if (!dataQueue
->initWithCapacity(size
)) {
56 IOSharedDataQueue
*IOSharedDataQueue::withEntries(UInt32 numEntries
, UInt32 entrySize
)
58 IOSharedDataQueue
*dataQueue
= new IOSharedDataQueue
;
61 if (!dataQueue
->initWithEntries(numEntries
, entrySize
)) {
70 Boolean
IOSharedDataQueue::initWithCapacity(UInt32 size
)
72 IODataQueueAppendix
* appendix
;
78 dataQueue
= (IODataQueueMemory
*)IOMallocAligned(round_page(size
+ DATA_QUEUE_MEMORY_HEADER_SIZE
+ DATA_QUEUE_MEMORY_APPENDIX_SIZE
), PAGE_SIZE
);
83 dataQueue
->queueSize
= size
;
87 appendix
= (IODataQueueAppendix
*)((UInt8
*)dataQueue
+ size
+ DATA_QUEUE_MEMORY_HEADER_SIZE
);
88 appendix
->version
= 0;
89 notifyMsg
= &(appendix
->msgh
);
90 setNotificationPort(MACH_PORT_NULL
);
95 void IOSharedDataQueue::free()
98 IOFreeAligned(dataQueue
, round_page(dataQueue
->queueSize
+ DATA_QUEUE_MEMORY_HEADER_SIZE
+ DATA_QUEUE_MEMORY_APPENDIX_SIZE
));
105 IOMemoryDescriptor
*IOSharedDataQueue::getMemoryDescriptor()
107 IOMemoryDescriptor
*descriptor
= 0;
109 if (dataQueue
!= 0) {
110 descriptor
= IOMemoryDescriptor::withAddress(dataQueue
, dataQueue
->queueSize
+ DATA_QUEUE_MEMORY_HEADER_SIZE
+ DATA_QUEUE_MEMORY_APPENDIX_SIZE
, kIODirectionOutIn
);
117 IODataQueueEntry
* IOSharedDataQueue::peek()
119 IODataQueueEntry
*entry
= 0;
121 if (dataQueue
&& (dataQueue
->head
!= dataQueue
->tail
)) {
122 IODataQueueEntry
* head
= 0;
124 UInt32 headOffset
= dataQueue
->head
;
125 UInt32 queueSize
= dataQueue
->queueSize
;
127 head
= (IODataQueueEntry
*)((char *)dataQueue
->queue
+ headOffset
);
128 headSize
= head
->size
;
130 // Check if there's enough room before the end of the queue for a header.
131 // If there is room, check if there's enough room to hold the header and
134 if ((headOffset
+ DATA_QUEUE_ENTRY_HEADER_SIZE
> queueSize
) ||
135 ((headOffset
+ headSize
+ DATA_QUEUE_ENTRY_HEADER_SIZE
) > queueSize
))
137 // No room for the header or the data, wrap to the beginning of the queue.
138 entry
= dataQueue
->queue
;
147 Boolean
IOSharedDataQueue::dequeue(void *data
, UInt32
*dataSize
)
149 Boolean retVal
= TRUE
;
150 IODataQueueEntry
* entry
= 0;
151 UInt32 entrySize
= 0;
152 UInt32 newHeadOffset
= 0;
155 if (dataQueue
->head
!= dataQueue
->tail
) {
156 IODataQueueEntry
* head
= 0;
158 UInt32 headOffset
= dataQueue
->head
;
159 UInt32 queueSize
= dataQueue
->queueSize
;
161 head
= (IODataQueueEntry
*)((char *)dataQueue
->queue
+ headOffset
);
162 headSize
= head
->size
;
164 // we wraped around to beginning, so read from there
165 // either there was not even room for the header
166 if ((headOffset
+ DATA_QUEUE_ENTRY_HEADER_SIZE
> queueSize
) ||
167 // or there was room for the header, but not for the data
168 ((headOffset
+ headSize
+ DATA_QUEUE_ENTRY_HEADER_SIZE
) > queueSize
)) {
169 entry
= dataQueue
->queue
;
170 entrySize
= entry
->size
;
171 newHeadOffset
= entrySize
+ DATA_QUEUE_ENTRY_HEADER_SIZE
;
172 // else it is at the end
175 entrySize
= entry
->size
;
176 newHeadOffset
= headOffset
+ entrySize
+ DATA_QUEUE_ENTRY_HEADER_SIZE
;
183 if (entrySize
<= *dataSize
) {
184 memcpy(data
, &(entry
->data
), entrySize
);
185 dataQueue
->head
= newHeadOffset
;
193 dataQueue
->head
= newHeadOffset
;
197 *dataSize
= entrySize
;
210 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 0);
211 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 1);
212 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 2);
213 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 3);
214 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 4);
215 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 5);
216 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 6);
217 OSMetaClassDefineReservedUnused(IOSharedDataQueue
, 7);