The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/iokit/Kernel/IOSharedDataQueue.cpp

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    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.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   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.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 
   29 #include <IOKit/IOSharedDataQueue.h>
   30 #include <IOKit/IODataQueueShared.h>
   31 #include <IOKit/IOLib.h>
   32 #include <IOKit/IOMemoryDescriptor.h>
   33 
   34 #ifdef dequeue
   35 #undef dequeue
   36 #endif
   37 
   38 #define super IODataQueue
   39 
   40 OSDefineMetaClassAndStructors(IOSharedDataQueue, IODataQueue)
   41 
   42 IOSharedDataQueue *IOSharedDataQueue::withCapacity(UInt32 size)
   43 {
   44     IOSharedDataQueue *dataQueue = new IOSharedDataQueue;
   45 
   46     if (dataQueue) {
   47         if  (!dataQueue->initWithCapacity(size)) {
   48             dataQueue->release();
   49             dataQueue = 0;
   50         }
   51     }
   52 
   53     return dataQueue;
   54 }
   55 
   56 IOSharedDataQueue *IOSharedDataQueue::withEntries(UInt32 numEntries, UInt32 entrySize)
   57 {
   58     IOSharedDataQueue *dataQueue = new IOSharedDataQueue;
   59 
   60     if (dataQueue) {
   61         if (!dataQueue->initWithEntries(numEntries, entrySize)) {
   62             dataQueue->release();
   63             dataQueue = 0;
   64         }
   65     }
   66 
   67     return dataQueue;
   68 }
   69 
   70 Boolean IOSharedDataQueue::initWithCapacity(UInt32 size)
   71 {
   72     IODataQueueAppendix *   appendix;
   73     
   74     if (!super::init()) {
   75         return false;
   76     }
   77     
   78     dataQueue = (IODataQueueMemory *)IOMallocAligned(round_page_32(size + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE), PAGE_SIZE);
   79     if (dataQueue == 0) {
   80         return false;
   81     }
   82 
   83     dataQueue->queueSize    = size;
   84     dataQueue->head         = 0;
   85     dataQueue->tail         = 0;
   86     
   87     appendix            = (IODataQueueAppendix *)((UInt8 *)dataQueue + size + DATA_QUEUE_MEMORY_HEADER_SIZE);
   88     appendix->version   = 0;
   89     notifyMsg           = &(appendix->msgh);
   90     setNotificationPort(MACH_PORT_NULL);
   91 
   92     return true;
   93 }
   94 
   95 void IOSharedDataQueue::free()
   96 {
   97     if (dataQueue) {
   98         IOFreeAligned(dataQueue, round_page_32(dataQueue->queueSize + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE));
   99         dataQueue = NULL;
  100     }
  101 
  102     super::free();
  103 }
  104 
  105 IOMemoryDescriptor *IOSharedDataQueue::getMemoryDescriptor()
  106 {
  107     IOMemoryDescriptor *descriptor = 0;
  108 
  109     if (dataQueue != 0) {
  110         descriptor = IOMemoryDescriptor::withAddress(dataQueue, dataQueue->queueSize + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE, kIODirectionOutIn);
  111     }
  112 
  113     return descriptor;
  114 }
  115 
  116 
  117 IODataQueueEntry * IOSharedDataQueue::peek()
  118 {
  119     IODataQueueEntry *entry = 0;
  120 
  121     if (dataQueue && (dataQueue->head != dataQueue->tail)) {
  122         IODataQueueEntry *  head                = 0;
  123         UInt32              headSize    = 0;
  124         UInt32              headOffset  = dataQueue->head;
  125         UInt32              queueSize   = dataQueue->queueSize;
  126 
  127         head            = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
  128         headSize        = head->size;
  129         
  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
  132         // the data.
  133 
  134         if ((headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize) ||
  135             ((headOffset + headSize + DATA_QUEUE_ENTRY_HEADER_SIZE) > queueSize))
  136         {
  137             // No room for the header or the data, wrap to the beginning of the queue.
  138             entry = dataQueue->queue;
  139         } else {
  140             entry = head;
  141         }
  142     }
  143 
  144     return entry;
  145 }
  146 
  147 Boolean IOSharedDataQueue::dequeue(void *data, UInt32 *dataSize)
  148 {
  149     Boolean             retVal          = TRUE;
  150     IODataQueueEntry *  entry           = 0;
  151     UInt32              entrySize       = 0;
  152     UInt32              newHeadOffset   = 0;
  153 
  154     if (dataQueue) {
  155         if (dataQueue->head != dataQueue->tail) {
  156             IODataQueueEntry *  head            = 0;
  157             UInt32              headSize    = 0;
  158             UInt32              headOffset  = dataQueue->head;
  159             UInt32              queueSize   = dataQueue->queueSize;
  160 
  161             head                = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
  162             headSize    = head->size;
  163             
  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
  173             } else {
  174                 entry           = head;
  175                 entrySize       = entry->size;
  176                 newHeadOffset   = headOffset + entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE;
  177             }
  178         }
  179 
  180         if (entry) {
  181             if (data) {
  182                 if (dataSize) {
  183                     if (entrySize <= *dataSize) {
  184                         memcpy(data, &(entry->data), entrySize);
  185                         dataQueue->head = newHeadOffset;
  186                     } else {
  187                         retVal = FALSE;
  188                     }
  189                 } else {
  190                     retVal = FALSE;
  191                 }
  192             } else {
  193                 dataQueue->head = newHeadOffset;
  194             }
  195 
  196             if (dataSize) {
  197                 *dataSize = entrySize;
  198             }
  199         } else {
  200             retVal = FALSE;
  201         }
  202     } else {
  203         retVal = FALSE;
  204     }
  205     
  206     return retVal;
  207 }
  208 
  209 
  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);

Cache object: a24890bb5aeaabfce026e3fdcea3b76a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.