VirtualBox

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

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

VMM,/Makefile.kmk: Kicked out more recompiler related code. bugref:9576

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

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