VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/PDMAllQueue.cpp@ 21363

Last change on this file since 21363 was 21363, checked in by vboxsync, 16 years ago

PDMQueue&users-thereof: Named the queues and added statistics.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* $Id: PDMAllQueue.cpp 21363 2009-07-07 17:10:52Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_PDM_QUEUE
27#include "PDMInternal.h"
28#include <VBox/pdm.h>
29#ifndef IN_RC
30# include <VBox/rem.h>
31# include <VBox/mm.h>
32#endif
33#include <VBox/vm.h>
34#include <VBox/err.h>
35#include <VBox/log.h>
36#include <iprt/asm.h>
37#include <iprt/assert.h>
38
39
40/**
41 * Allocate an item from a queue.
42 * The allocated item must be handed on to PDMR3QueueInsert() after the
43 * data have been filled in.
44 *
45 * @returns Pointer to allocated queue item.
46 * @returns NULL on failure. The queue is exhausted.
47 * @param pQueue The queue handle.
48 * @thread Any thread.
49 */
50VMMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue)
51{
52 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
53 PPDMQUEUEITEMCORE pNew;
54 uint32_t iNext;
55 uint32_t i;
56 do
57 {
58 i = pQueue->iFreeTail;
59 if (i == pQueue->iFreeHead)
60 {
61 STAM_REL_COUNTER_INC(&pQueue->StatAllocFailures);
62 return NULL;
63 }
64 pNew = pQueue->aFreeItems[i].CTX_SUFF(pItem);
65 iNext = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
66 } while (!ASMAtomicCmpXchgU32(&pQueue->iFreeTail, iNext, i));
67 return pNew;
68}
69
70
71/**
72 * Queue an item.
73 * The item must have been obtained using PDMQueueAlloc(). Once the item
74 * have been passed to this function it must not be touched!
75 *
76 * @param pQueue The queue handle.
77 * @param pItem The item to insert.
78 * @thread Any thread.
79 */
80VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
81{
82 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
83 Assert(VALID_PTR(pItem));
84
85 PPDMQUEUEITEMCORE pNext;
86 do
87 {
88 pNext = pQueue->CTX_SUFF(pPending);
89 pItem->CTX_SUFF(pNext) = pNext;
90 } while (!ASMAtomicCmpXchgPtr((void * volatile *)&pQueue->CTX_SUFF(pPending), pItem, pNext));
91
92 if (!pQueue->pTimer)
93 {
94 PVM pVM = pQueue->CTX_SUFF(pVM);
95 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
96 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
97 ASMAtomicBitSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
98#ifdef IN_RING3
99 REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
100 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
101#endif
102 }
103 STAM_REL_COUNTER_INC(&pQueue->StatInsert);
104}
105
106
107/**
108 * Queue an item.
109 * The item must have been obtained using PDMQueueAlloc(). Once the item
110 * have been passed to this function it must not be touched!
111 *
112 * @param pQueue The queue handle.
113 * @param pItem The item to insert.
114 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
115 * This applies only to GC.
116 * @thread Any thread.
117 */
118VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
119{
120 PDMQueueInsert(pQueue, pItem);
121#ifdef IN_RC
122 PVM pVM = pQueue->CTX_SUFF(pVM);
123 /** @todo figure out where to put this, the next bit should go there too.
124 if (NanoMaxDelay)
125 {
126
127 }
128 else */
129 {
130 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
131 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
132 }
133#endif
134}
135
136
137
138/**
139 * Gets the RC pointer for the specified queue.
140 *
141 * @returns The RC address of the queue.
142 * @returns NULL if pQueue is invalid.
143 * @param pQueue The queue handle.
144 */
145VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
146{
147 Assert(VALID_PTR(pQueue));
148 Assert(pQueue->pVMR3 && pQueue->pVMRC);
149#ifdef IN_RC
150 return pQueue;
151#else
152 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
153#endif
154}
155
156
157/**
158 * Gets the ring-0 pointer for the specified queue.
159 *
160 * @returns The ring-0 address of the queue.
161 * @returns NULL if pQueue is invalid.
162 * @param pQueue The queue handle.
163 */
164VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
165{
166 Assert(VALID_PTR(pQueue));
167 Assert(pQueue->pVMR3 && pQueue->pVMR0);
168#ifdef IN_RING0
169 return pQueue;
170#else
171 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
172#endif
173}
174
175
176/**
177 * Flushes a PDM queue.
178 *
179 * @param pQueue The queue handle.
180 */
181VMMDECL(void) PDMQueueFlush(PPDMQUEUE pQueue)
182{
183 Assert(VALID_PTR(pQueue));
184 Assert(pQueue->pVMR3);
185 PVM pVM = pQueue->CTX_SUFF(pVM);
186
187#if defined(IN_RC) || defined(IN_RING0)
188 Assert(pQueue->CTX_SUFF(pVM));
189 pVM->pdm.s.CTX_SUFF(pQueueFlush) = pQueue;
190 VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
191
192#else /* IN_RING3: */
193 PVMREQ pReq;
194 VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PDMR3QueueFlushWorker, 2, pVM, pQueue);
195 VMR3ReqFree(pReq);
196#endif
197}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette