1e13b1fa5SApple OSS Distributions /* 2e13b1fa5SApple OSS Distributions * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3e13b1fa5SApple OSS Distributions * 4e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5e13b1fa5SApple OSS Distributions * 6e13b1fa5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7e13b1fa5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8e13b1fa5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9e13b1fa5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10e13b1fa5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11e13b1fa5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12e13b1fa5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13e13b1fa5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14e13b1fa5SApple OSS Distributions * 15e13b1fa5SApple OSS Distributions * Please obtain a copy of the License at 16e13b1fa5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17e13b1fa5SApple OSS Distributions * 18e13b1fa5SApple OSS Distributions * The Original Code and all software distributed under the License are 19e13b1fa5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20e13b1fa5SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21e13b1fa5SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22e13b1fa5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23e13b1fa5SApple OSS Distributions * Please see the License for the specific language governing rights and 24e13b1fa5SApple OSS Distributions * limitations under the License. 25e13b1fa5SApple OSS Distributions * 26e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27e13b1fa5SApple OSS Distributions */ 28e13b1fa5SApple OSS Distributions 29e13b1fa5SApple OSS Distributions #include <IOKit/IOSharedDataQueue.h> 30e13b1fa5SApple OSS Distributions #include <IOKit/IODataQueueShared.h> 31e13b1fa5SApple OSS Distributions #include <IOKit/IOLib.h> 32e13b1fa5SApple OSS Distributions #include <IOKit/IOMemoryDescriptor.h> 33e13b1fa5SApple OSS Distributions 34*a3bb9fccSApple OSS Distributions #ifdef enqueue 35*a3bb9fccSApple OSS Distributions #undef enqueue 36*a3bb9fccSApple OSS Distributions #endif 37*a3bb9fccSApple OSS Distributions 38e13b1fa5SApple OSS Distributions #ifdef dequeue 39e13b1fa5SApple OSS Distributions #undef dequeue 40e13b1fa5SApple OSS Distributions #endif 41e13b1fa5SApple OSS Distributions 42e13b1fa5SApple OSS Distributions #define super IODataQueue 43e13b1fa5SApple OSS Distributions 44e13b1fa5SApple OSS Distributions OSDefineMetaClassAndStructors(IOSharedDataQueue, IODataQueue) 45e13b1fa5SApple OSS Distributions 46e13b1fa5SApple OSS Distributions IOSharedDataQueue *IOSharedDataQueue::withCapacity(UInt32 size) 47e13b1fa5SApple OSS Distributions { 48e13b1fa5SApple OSS Distributions IOSharedDataQueue *dataQueue = new IOSharedDataQueue; 49e13b1fa5SApple OSS Distributions 50e13b1fa5SApple OSS Distributions if (dataQueue) { 51e13b1fa5SApple OSS Distributions if (!dataQueue->initWithCapacity(size)) { 52e13b1fa5SApple OSS Distributions dataQueue->release(); 53e13b1fa5SApple OSS Distributions dataQueue = 0; 54e13b1fa5SApple OSS Distributions } 55e13b1fa5SApple OSS Distributions } 56e13b1fa5SApple OSS Distributions 57e13b1fa5SApple OSS Distributions return dataQueue; 58e13b1fa5SApple OSS Distributions } 59e13b1fa5SApple OSS Distributions 60e13b1fa5SApple OSS Distributions IOSharedDataQueue *IOSharedDataQueue::withEntries(UInt32 numEntries, UInt32 entrySize) 61e13b1fa5SApple OSS Distributions { 62e13b1fa5SApple OSS Distributions IOSharedDataQueue *dataQueue = new IOSharedDataQueue; 63e13b1fa5SApple OSS Distributions 64e13b1fa5SApple OSS Distributions if (dataQueue) { 65e13b1fa5SApple OSS Distributions if (!dataQueue->initWithEntries(numEntries, entrySize)) { 66e13b1fa5SApple OSS Distributions dataQueue->release(); 67e13b1fa5SApple OSS Distributions dataQueue = 0; 68e13b1fa5SApple OSS Distributions } 69e13b1fa5SApple OSS Distributions } 70e13b1fa5SApple OSS Distributions 71e13b1fa5SApple OSS Distributions return dataQueue; 72e13b1fa5SApple OSS Distributions } 73e13b1fa5SApple OSS Distributions 74e13b1fa5SApple OSS Distributions Boolean IOSharedDataQueue::initWithCapacity(UInt32 size) 75e13b1fa5SApple OSS Distributions { 76e13b1fa5SApple OSS Distributions IODataQueueAppendix * appendix; 77*a3bb9fccSApple OSS Distributions vm_size_t allocSize; 78e13b1fa5SApple OSS Distributions 79e13b1fa5SApple OSS Distributions if (!super::init()) { 80e13b1fa5SApple OSS Distributions return false; 81e13b1fa5SApple OSS Distributions } 82e13b1fa5SApple OSS Distributions 83*a3bb9fccSApple OSS Distributions _reserved = (ExpansionData *)IOMalloc(sizeof(struct ExpansionData)); 84*a3bb9fccSApple OSS Distributions if (!_reserved) { 85*a3bb9fccSApple OSS Distributions return false; 86*a3bb9fccSApple OSS Distributions } 87*a3bb9fccSApple OSS Distributions 88*a3bb9fccSApple OSS Distributions if (size > UINT32_MAX - DATA_QUEUE_MEMORY_HEADER_SIZE - DATA_QUEUE_MEMORY_APPENDIX_SIZE) { 89*a3bb9fccSApple OSS Distributions return false; 90*a3bb9fccSApple OSS Distributions } 91*a3bb9fccSApple OSS Distributions 92*a3bb9fccSApple OSS Distributions allocSize = round_page(size + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE); 93*a3bb9fccSApple OSS Distributions 94*a3bb9fccSApple OSS Distributions if (allocSize < size) { 95*a3bb9fccSApple OSS Distributions return false; 96*a3bb9fccSApple OSS Distributions } 97*a3bb9fccSApple OSS Distributions 98*a3bb9fccSApple OSS Distributions dataQueue = (IODataQueueMemory *)IOMallocAligned(allocSize, PAGE_SIZE); 99e13b1fa5SApple OSS Distributions if (dataQueue == 0) { 100e13b1fa5SApple OSS Distributions return false; 101e13b1fa5SApple OSS Distributions } 102e13b1fa5SApple OSS Distributions 103e13b1fa5SApple OSS Distributions dataQueue->queueSize = size; 104e13b1fa5SApple OSS Distributions dataQueue->head = 0; 105e13b1fa5SApple OSS Distributions dataQueue->tail = 0; 106e13b1fa5SApple OSS Distributions 107*a3bb9fccSApple OSS Distributions if (!setQueueSize(size)) { 108*a3bb9fccSApple OSS Distributions return false; 109*a3bb9fccSApple OSS Distributions } 110*a3bb9fccSApple OSS Distributions 111e13b1fa5SApple OSS Distributions appendix = (IODataQueueAppendix *)((UInt8 *)dataQueue + size + DATA_QUEUE_MEMORY_HEADER_SIZE); 112e13b1fa5SApple OSS Distributions appendix->version = 0; 113e13b1fa5SApple OSS Distributions notifyMsg = &(appendix->msgh); 114e13b1fa5SApple OSS Distributions setNotificationPort(MACH_PORT_NULL); 115e13b1fa5SApple OSS Distributions 116e13b1fa5SApple OSS Distributions return true; 117e13b1fa5SApple OSS Distributions } 118e13b1fa5SApple OSS Distributions 119e13b1fa5SApple OSS Distributions void IOSharedDataQueue::free() 120e13b1fa5SApple OSS Distributions { 121e13b1fa5SApple OSS Distributions if (dataQueue) { 122*a3bb9fccSApple OSS Distributions IOFreeAligned(dataQueue, round_page(getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE)); 123e13b1fa5SApple OSS Distributions dataQueue = NULL; 124e13b1fa5SApple OSS Distributions } 125e13b1fa5SApple OSS Distributions 126*a3bb9fccSApple OSS Distributions if (_reserved) { 127*a3bb9fccSApple OSS Distributions IOFree (_reserved, sizeof(struct ExpansionData)); 128*a3bb9fccSApple OSS Distributions _reserved = NULL; 129*a3bb9fccSApple OSS Distributions } 130*a3bb9fccSApple OSS Distributions 131e13b1fa5SApple OSS Distributions super::free(); 132e13b1fa5SApple OSS Distributions } 133e13b1fa5SApple OSS Distributions 134e13b1fa5SApple OSS Distributions IOMemoryDescriptor *IOSharedDataQueue::getMemoryDescriptor() 135e13b1fa5SApple OSS Distributions { 136e13b1fa5SApple OSS Distributions IOMemoryDescriptor *descriptor = 0; 137e13b1fa5SApple OSS Distributions 138e13b1fa5SApple OSS Distributions if (dataQueue != 0) { 139*a3bb9fccSApple OSS Distributions descriptor = IOMemoryDescriptor::withAddress(dataQueue, getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE, kIODirectionOutIn); 140e13b1fa5SApple OSS Distributions } 141e13b1fa5SApple OSS Distributions 142e13b1fa5SApple OSS Distributions return descriptor; 143e13b1fa5SApple OSS Distributions } 144e13b1fa5SApple OSS Distributions 145e13b1fa5SApple OSS Distributions 146e13b1fa5SApple OSS Distributions IODataQueueEntry * IOSharedDataQueue::peek() 147e13b1fa5SApple OSS Distributions { 148e13b1fa5SApple OSS Distributions IODataQueueEntry *entry = 0; 149e13b1fa5SApple OSS Distributions 150e13b1fa5SApple OSS Distributions if (dataQueue && (dataQueue->head != dataQueue->tail)) { 151e13b1fa5SApple OSS Distributions IODataQueueEntry * head = 0; 152e13b1fa5SApple OSS Distributions UInt32 headSize = 0; 153e13b1fa5SApple OSS Distributions UInt32 headOffset = dataQueue->head; 154*a3bb9fccSApple OSS Distributions UInt32 queueSize = getQueueSize(); 155*a3bb9fccSApple OSS Distributions 156*a3bb9fccSApple OSS Distributions if (headOffset >= queueSize) { 157*a3bb9fccSApple OSS Distributions return NULL; 158*a3bb9fccSApple OSS Distributions } 159e13b1fa5SApple OSS Distributions 160e13b1fa5SApple OSS Distributions head = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset); 161e13b1fa5SApple OSS Distributions headSize = head->size; 162e13b1fa5SApple OSS Distributions 163e13b1fa5SApple OSS Distributions // Check if there's enough room before the end of the queue for a header. 164e13b1fa5SApple OSS Distributions // If there is room, check if there's enough room to hold the header and 165e13b1fa5SApple OSS Distributions // the data. 166e13b1fa5SApple OSS Distributions 167*a3bb9fccSApple OSS Distributions if ((headOffset > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) || 168*a3bb9fccSApple OSS Distributions (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize) || 169*a3bb9fccSApple OSS Distributions (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > UINT32_MAX - headSize) || 170*a3bb9fccSApple OSS Distributions (headOffset + headSize + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize)) { 171e13b1fa5SApple OSS Distributions // No room for the header or the data, wrap to the beginning of the queue. 172*a3bb9fccSApple OSS Distributions // Note: wrapping even with the UINT32_MAX checks, as we have to support 173*a3bb9fccSApple OSS Distributions // queueSize of UINT32_MAX 174e13b1fa5SApple OSS Distributions entry = dataQueue->queue; 175e13b1fa5SApple OSS Distributions } else { 176e13b1fa5SApple OSS Distributions entry = head; 177e13b1fa5SApple OSS Distributions } 178e13b1fa5SApple OSS Distributions } 179e13b1fa5SApple OSS Distributions 180e13b1fa5SApple OSS Distributions return entry; 181e13b1fa5SApple OSS Distributions } 182e13b1fa5SApple OSS Distributions 183*a3bb9fccSApple OSS Distributions Boolean IOSharedDataQueue::enqueue(void * data, UInt32 dataSize) 184*a3bb9fccSApple OSS Distributions { 185*a3bb9fccSApple OSS Distributions const UInt32 head = dataQueue->head; // volatile 186*a3bb9fccSApple OSS Distributions const UInt32 tail = dataQueue->tail; 187*a3bb9fccSApple OSS Distributions const UInt32 entrySize = dataSize + DATA_QUEUE_ENTRY_HEADER_SIZE; 188*a3bb9fccSApple OSS Distributions IODataQueueEntry * entry; 189*a3bb9fccSApple OSS Distributions 190*a3bb9fccSApple OSS Distributions // Check for overflow of entrySize 191*a3bb9fccSApple OSS Distributions if (dataSize > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) { 192*a3bb9fccSApple OSS Distributions return false; 193*a3bb9fccSApple OSS Distributions } 194*a3bb9fccSApple OSS Distributions // Check for underflow of (getQueueSize() - tail) 195*a3bb9fccSApple OSS Distributions if (getQueueSize() < tail) { 196*a3bb9fccSApple OSS Distributions return false; 197*a3bb9fccSApple OSS Distributions } 198*a3bb9fccSApple OSS Distributions 199*a3bb9fccSApple OSS Distributions if ( tail >= head ) 200*a3bb9fccSApple OSS Distributions { 201*a3bb9fccSApple OSS Distributions // Is there enough room at the end for the entry? 202*a3bb9fccSApple OSS Distributions if ((entrySize <= UINT32_MAX - tail) && 203*a3bb9fccSApple OSS Distributions ((tail + entrySize) <= getQueueSize()) ) 204*a3bb9fccSApple OSS Distributions { 205*a3bb9fccSApple OSS Distributions entry = (IODataQueueEntry *)((UInt8 *)dataQueue->queue + tail); 206*a3bb9fccSApple OSS Distributions 207*a3bb9fccSApple OSS Distributions entry->size = dataSize; 208*a3bb9fccSApple OSS Distributions memcpy(&entry->data, data, dataSize); 209*a3bb9fccSApple OSS Distributions 210*a3bb9fccSApple OSS Distributions // The tail can be out of bound when the size of the new entry 211*a3bb9fccSApple OSS Distributions // exactly matches the available space at the end of the queue. 212*a3bb9fccSApple OSS Distributions // The tail can range from 0 to dataQueue->queueSize inclusive. 213*a3bb9fccSApple OSS Distributions 214*a3bb9fccSApple OSS Distributions OSAddAtomic(entrySize, (SInt32 *)&dataQueue->tail); 215*a3bb9fccSApple OSS Distributions } 216*a3bb9fccSApple OSS Distributions else if ( head > entrySize ) // Is there enough room at the beginning? 217*a3bb9fccSApple OSS Distributions { 218*a3bb9fccSApple OSS Distributions // Wrap around to the beginning, but do not allow the tail to catch 219*a3bb9fccSApple OSS Distributions // up to the head. 220*a3bb9fccSApple OSS Distributions 221*a3bb9fccSApple OSS Distributions dataQueue->queue->size = dataSize; 222*a3bb9fccSApple OSS Distributions 223*a3bb9fccSApple OSS Distributions // We need to make sure that there is enough room to set the size before 224*a3bb9fccSApple OSS Distributions // doing this. The user client checks for this and will look for the size 225*a3bb9fccSApple OSS Distributions // at the beginning if there isn't room for it at the end. 226*a3bb9fccSApple OSS Distributions 227*a3bb9fccSApple OSS Distributions if ( ( getQueueSize() - tail ) >= DATA_QUEUE_ENTRY_HEADER_SIZE ) 228*a3bb9fccSApple OSS Distributions { 229*a3bb9fccSApple OSS Distributions ((IODataQueueEntry *)((UInt8 *)dataQueue->queue + tail))->size = dataSize; 230*a3bb9fccSApple OSS Distributions } 231*a3bb9fccSApple OSS Distributions 232*a3bb9fccSApple OSS Distributions memcpy(&dataQueue->queue->data, data, dataSize); 233*a3bb9fccSApple OSS Distributions OSCompareAndSwap(dataQueue->tail, entrySize, &dataQueue->tail); 234*a3bb9fccSApple OSS Distributions } 235*a3bb9fccSApple OSS Distributions else 236*a3bb9fccSApple OSS Distributions { 237*a3bb9fccSApple OSS Distributions return false; // queue is full 238*a3bb9fccSApple OSS Distributions } 239*a3bb9fccSApple OSS Distributions } 240*a3bb9fccSApple OSS Distributions else 241*a3bb9fccSApple OSS Distributions { 242*a3bb9fccSApple OSS Distributions // Do not allow the tail to catch up to the head when the queue is full. 243*a3bb9fccSApple OSS Distributions // That's why the comparison uses a '>' rather than '>='. 244*a3bb9fccSApple OSS Distributions 245*a3bb9fccSApple OSS Distributions if ( (head - tail) > entrySize ) 246*a3bb9fccSApple OSS Distributions { 247*a3bb9fccSApple OSS Distributions entry = (IODataQueueEntry *)((UInt8 *)dataQueue->queue + tail); 248*a3bb9fccSApple OSS Distributions 249*a3bb9fccSApple OSS Distributions entry->size = dataSize; 250*a3bb9fccSApple OSS Distributions memcpy(&entry->data, data, dataSize); 251*a3bb9fccSApple OSS Distributions OSAddAtomic(entrySize, (SInt32 *)&dataQueue->tail); 252*a3bb9fccSApple OSS Distributions } 253*a3bb9fccSApple OSS Distributions else 254*a3bb9fccSApple OSS Distributions { 255*a3bb9fccSApple OSS Distributions return false; // queue is full 256*a3bb9fccSApple OSS Distributions } 257*a3bb9fccSApple OSS Distributions } 258*a3bb9fccSApple OSS Distributions 259*a3bb9fccSApple OSS Distributions // Send notification (via mach message) that data is available. 260*a3bb9fccSApple OSS Distributions 261*a3bb9fccSApple OSS Distributions if ( ( head == tail ) /* queue was empty prior to enqueue() */ 262*a3bb9fccSApple OSS Distributions || ( dataQueue->head == tail ) ) /* queue was emptied during enqueue() */ 263*a3bb9fccSApple OSS Distributions { 264*a3bb9fccSApple OSS Distributions sendDataAvailableNotification(); 265*a3bb9fccSApple OSS Distributions } 266*a3bb9fccSApple OSS Distributions 267*a3bb9fccSApple OSS Distributions return true; 268*a3bb9fccSApple OSS Distributions } 269*a3bb9fccSApple OSS Distributions 270e13b1fa5SApple OSS Distributions Boolean IOSharedDataQueue::dequeue(void *data, UInt32 *dataSize) 271e13b1fa5SApple OSS Distributions { 272e13b1fa5SApple OSS Distributions Boolean retVal = TRUE; 273e13b1fa5SApple OSS Distributions IODataQueueEntry * entry = 0; 274e13b1fa5SApple OSS Distributions UInt32 entrySize = 0; 275e13b1fa5SApple OSS Distributions UInt32 newHeadOffset = 0; 276e13b1fa5SApple OSS Distributions 277e13b1fa5SApple OSS Distributions if (dataQueue) { 278e13b1fa5SApple OSS Distributions if (dataQueue->head != dataQueue->tail) { 279e13b1fa5SApple OSS Distributions IODataQueueEntry * head = 0; 280e13b1fa5SApple OSS Distributions UInt32 headSize = 0; 281e13b1fa5SApple OSS Distributions UInt32 headOffset = dataQueue->head; 282*a3bb9fccSApple OSS Distributions UInt32 queueSize = getQueueSize(); 283*a3bb9fccSApple OSS Distributions 284*a3bb9fccSApple OSS Distributions if (headOffset > queueSize) { 285*a3bb9fccSApple OSS Distributions return false; 286*a3bb9fccSApple OSS Distributions } 287e13b1fa5SApple OSS Distributions 288e13b1fa5SApple OSS Distributions head = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset); 289e13b1fa5SApple OSS Distributions headSize = head->size; 290e13b1fa5SApple OSS Distributions 291*a3bb9fccSApple OSS Distributions // we wrapped around to beginning, so read from there 292e13b1fa5SApple OSS Distributions // either there was not even room for the header 293*a3bb9fccSApple OSS Distributions if ((headOffset > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) || 294*a3bb9fccSApple OSS Distributions (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize) || 295e13b1fa5SApple OSS Distributions // or there was room for the header, but not for the data 296*a3bb9fccSApple OSS Distributions (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > UINT32_MAX - headSize) || 297*a3bb9fccSApple OSS Distributions (headOffset + headSize + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize)) { 298*a3bb9fccSApple OSS Distributions // Note: we have to wrap to the beginning even with the UINT32_MAX checks 299*a3bb9fccSApple OSS Distributions // because we have to support a queueSize of UINT32_MAX. 300e13b1fa5SApple OSS Distributions entry = dataQueue->queue; 301e13b1fa5SApple OSS Distributions entrySize = entry->size; 302*a3bb9fccSApple OSS Distributions if ((entrySize > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) || 303*a3bb9fccSApple OSS Distributions (entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize)) { 304*a3bb9fccSApple OSS Distributions return false; 305*a3bb9fccSApple OSS Distributions } 306e13b1fa5SApple OSS Distributions newHeadOffset = entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE; 307e13b1fa5SApple OSS Distributions // else it is at the end 308e13b1fa5SApple OSS Distributions } else { 309e13b1fa5SApple OSS Distributions entry = head; 310e13b1fa5SApple OSS Distributions entrySize = entry->size; 311*a3bb9fccSApple OSS Distributions if ((entrySize > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) || 312*a3bb9fccSApple OSS Distributions (entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE > UINT32_MAX - headOffset) || 313*a3bb9fccSApple OSS Distributions (entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE + headOffset > queueSize)) { 314*a3bb9fccSApple OSS Distributions return false; 315*a3bb9fccSApple OSS Distributions } 316e13b1fa5SApple OSS Distributions newHeadOffset = headOffset + entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE; 317e13b1fa5SApple OSS Distributions } 318e13b1fa5SApple OSS Distributions } 319e13b1fa5SApple OSS Distributions 320e13b1fa5SApple OSS Distributions if (entry) { 321e13b1fa5SApple OSS Distributions if (data) { 322e13b1fa5SApple OSS Distributions if (dataSize) { 323e13b1fa5SApple OSS Distributions if (entrySize <= *dataSize) { 324e13b1fa5SApple OSS Distributions memcpy(data, &(entry->data), entrySize); 325*a3bb9fccSApple OSS Distributions OSCompareAndSwap( dataQueue->head, newHeadOffset, (SInt32 *)&dataQueue->head); 326e13b1fa5SApple OSS Distributions } else { 327e13b1fa5SApple OSS Distributions retVal = FALSE; 328e13b1fa5SApple OSS Distributions } 329e13b1fa5SApple OSS Distributions } else { 330e13b1fa5SApple OSS Distributions retVal = FALSE; 331e13b1fa5SApple OSS Distributions } 332e13b1fa5SApple OSS Distributions } else { 333*a3bb9fccSApple OSS Distributions OSCompareAndSwap( dataQueue->head, newHeadOffset, (SInt32 *)&dataQueue->head); 334e13b1fa5SApple OSS Distributions } 335e13b1fa5SApple OSS Distributions 336e13b1fa5SApple OSS Distributions if (dataSize) { 337e13b1fa5SApple OSS Distributions *dataSize = entrySize; 338e13b1fa5SApple OSS Distributions } 339e13b1fa5SApple OSS Distributions } else { 340e13b1fa5SApple OSS Distributions retVal = FALSE; 341e13b1fa5SApple OSS Distributions } 342e13b1fa5SApple OSS Distributions } else { 343e13b1fa5SApple OSS Distributions retVal = FALSE; 344e13b1fa5SApple OSS Distributions } 345e13b1fa5SApple OSS Distributions 346e13b1fa5SApple OSS Distributions return retVal; 347e13b1fa5SApple OSS Distributions } 348e13b1fa5SApple OSS Distributions 349*a3bb9fccSApple OSS Distributions UInt32 IOSharedDataQueue::getQueueSize() 350*a3bb9fccSApple OSS Distributions { 351*a3bb9fccSApple OSS Distributions if (!_reserved) { 352*a3bb9fccSApple OSS Distributions return 0; 353*a3bb9fccSApple OSS Distributions } 354*a3bb9fccSApple OSS Distributions return _reserved->queueSize; 355*a3bb9fccSApple OSS Distributions } 356*a3bb9fccSApple OSS Distributions 357*a3bb9fccSApple OSS Distributions Boolean IOSharedDataQueue::setQueueSize(UInt32 size) 358*a3bb9fccSApple OSS Distributions { 359*a3bb9fccSApple OSS Distributions if (!_reserved) { 360*a3bb9fccSApple OSS Distributions return false; 361*a3bb9fccSApple OSS Distributions } 362*a3bb9fccSApple OSS Distributions _reserved->queueSize = size; 363*a3bb9fccSApple OSS Distributions return true; 364*a3bb9fccSApple OSS Distributions } 365e13b1fa5SApple OSS Distributions 366e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 0); 367e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 1); 368e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 2); 369e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 3); 370e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 4); 371e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 5); 372e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 6); 373e13b1fa5SApple OSS Distributions OSMetaClassDefineReservedUnused(IOSharedDataQueue, 7); 374