VirtualBox

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

最後變更 在這個檔案從80268是 80268,由 vboxsync 提交於 6 年 前

VMM: Refactoring VMMAll/* to use VMCC & VMMCPUCC. bugref:9217

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 6.1 KB
 
1/* $Id: PDMAllQueue.cpp 80268 2019-08-14 11:25:13Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. 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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define VBOX_BUGREF_9217_PART_I
23#define LOG_GROUP LOG_GROUP_PDM_QUEUE
24#include "PDMInternal.h"
25#include <VBox/vmm/pdm.h>
26#ifndef IN_RC
27# ifdef VBOX_WITH_REM
28# include <VBox/vmm/rem.h>
29# endif
30# include <VBox/vmm/mm.h>
31#endif
32#include <VBox/vmm/vmcc.h>
33#include <iprt/errcore.h>
34#include <VBox/log.h>
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37
38
39/**
40 * Allocate an item from a queue.
41 * The allocated item must be handed on to PDMR3QueueInsert() after the
42 * data have been filled in.
43 *
44 * @returns Pointer to allocated queue item.
45 * @returns NULL on failure. The queue is exhausted.
46 * @param pQueue The queue handle.
47 * @thread Any thread.
48 */
49VMMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue)
50{
51 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
52 PPDMQUEUEITEMCORE pNew;
53 uint32_t iNext;
54 uint32_t i;
55 do
56 {
57 i = pQueue->iFreeTail;
58 if (i == pQueue->iFreeHead)
59 {
60 STAM_REL_COUNTER_INC(&pQueue->StatAllocFailures);
61 return NULL;
62 }
63 pNew = pQueue->aFreeItems[i].CTX_SUFF(pItem);
64 iNext = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
65 } while (!ASMAtomicCmpXchgU32(&pQueue->iFreeTail, iNext, i));
66 return pNew;
67}
68
69
70/**
71 * Sets the FFs and fQueueFlushed.
72 *
73 * @param pQueue The PDM queue.
74 */
75static void pdmQueueSetFF(PPDMQUEUE pQueue)
76{
77 PVM pVM = pQueue->CTX_SUFF(pVM);
78 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_IS_SET(pVM, VM_FF_PDM_QUEUES)));
79 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
80 ASMAtomicBitSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
81#ifdef IN_RING3
82# ifdef VBOX_WITH_REM
83 REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
84# endif
85 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
86#endif
87}
88
89
90/**
91 * Queue an item.
92 * The item must have been obtained using PDMQueueAlloc(). Once the item
93 * have been passed to this function it must not be touched!
94 *
95 * @param pQueue The queue handle.
96 * @param pItem The item to insert.
97 * @thread Any thread.
98 */
99VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
100{
101 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
102 Assert(VALID_PTR(pItem));
103
104#if 0 /* the paranoid android version: */
105 void *pvNext;
106 do
107 {
108 pvNext = ASMAtomicUoReadPtr((void * volatile *)&pQueue->CTX_SUFF(pPending));
109 ASMAtomicUoWritePtr((void * volatile *)&pItem->CTX_SUFF(pNext), pvNext);
110 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pvNext));
111#else
112 PPDMQUEUEITEMCORE pNext;
113 do
114 {
115 pNext = pQueue->CTX_SUFF(pPending);
116 pItem->CTX_SUFF(pNext) = pNext;
117 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pNext));
118#endif
119
120 if (!pQueue->pTimer)
121 pdmQueueSetFF(pQueue);
122 STAM_REL_COUNTER_INC(&pQueue->StatInsert);
123 STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
124}
125
126
127/**
128 * Queue an item.
129 * The item must have been obtained using PDMQueueAlloc(). Once the item
130 * have been passed to this function it must not be touched!
131 *
132 * @param pQueue The queue handle.
133 * @param pItem The item to insert.
134 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
135 * This applies only to GC.
136 * @thread Any thread.
137 */
138VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
139{
140 NOREF(NanoMaxDelay);
141 PDMQueueInsert(pQueue, pItem);
142#ifdef IN_RC
143 PVM pVM = pQueue->CTX_SUFF(pVM);
144 /** @todo figure out where to put this, the next bit should go there too.
145 if (NanoMaxDelay)
146 {
147
148 }
149 else */
150 {
151 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
152 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
153 }
154#endif
155}
156
157
158
159/**
160 * Gets the RC pointer for the specified queue.
161 *
162 * @returns The RC address of the queue.
163 * @returns NULL if pQueue is invalid.
164 * @param pQueue The queue handle.
165 */
166VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
167{
168 Assert(VALID_PTR(pQueue));
169 Assert(pQueue->pVMR3 && pQueue->pVMRC);
170#ifdef IN_RC
171 return pQueue;
172#else
173 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
174#endif
175}
176
177
178/**
179 * Gets the ring-0 pointer for the specified queue.
180 *
181 * @returns The ring-0 address of the queue.
182 * @returns NULL if pQueue is invalid.
183 * @param pQueue The queue handle.
184 */
185VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
186{
187 Assert(VALID_PTR(pQueue));
188 Assert(pQueue->pVMR3 && pQueue->pVMR0);
189#ifdef IN_RING0
190 return pQueue;
191#else
192 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
193#endif
194}
195
196
197/**
198 * Schedule the queue for flushing (processing) if necessary.
199 *
200 * @returns @c true if necessary, @c false if not.
201 * @param pQueue The queue.
202 */
203VMMDECL(bool) PDMQueueFlushIfNecessary(PPDMQUEUE pQueue)
204{
205 AssertPtr(pQueue);
206 if ( pQueue->pPendingR3 != NIL_RTR3PTR
207 || pQueue->pPendingR0 != NIL_RTR0PTR
208 || pQueue->pPendingRC != NIL_RTRCPTR)
209 {
210 pdmQueueSetFF(pQueue);
211 return false;
212 }
213 return false;
214}
215
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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