VirtualBox

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

Last change on this file since 88638 was 87766, checked in by vboxsync, 4 years ago

VMM/TM,VMM/*: Refactored the TM timer APIs to use 'handles' and take a pVM parameter. Only internal callbacks have been updated with a hTimer parameter, so far. bugref:9943

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.9 KB
Line 
1/* $Id: PDMAllQueue.cpp 87766 2021-02-16 14:27:43Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.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 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
79#endif
80}
81
82
83/**
84 * Queue an item.
85 * The item must have been obtained using PDMQueueAlloc(). Once the item
86 * have been passed to this function it must not be touched!
87 *
88 * @param pQueue The queue handle.
89 * @param pItem The item to insert.
90 * @thread Any thread.
91 */
92VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
93{
94 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
95 Assert(VALID_PTR(pItem));
96
97#if 0 /* the paranoid android version: */
98 void *pvNext;
99 do
100 {
101 pvNext = ASMAtomicUoReadPtr((void * volatile *)&pQueue->CTX_SUFF(pPending));
102 ASMAtomicUoWritePtr((void * volatile *)&pItem->CTX_SUFF(pNext), pvNext);
103 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pvNext));
104#else
105 PPDMQUEUEITEMCORE pNext;
106 do
107 {
108 pNext = pQueue->CTX_SUFF(pPending);
109 pItem->CTX_SUFF(pNext) = pNext;
110 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pNext));
111#endif
112
113 if (pQueue->hTimer == NIL_TMTIMERHANDLE)
114 pdmQueueSetFF(pQueue);
115 STAM_REL_COUNTER_INC(&pQueue->StatInsert);
116 STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
117}
118
119
120/**
121 * Queue an item.
122 * The item must have been obtained using PDMQueueAlloc(). Once the item
123 * have been passed to this function it must not be touched!
124 *
125 * @param pQueue The queue handle.
126 * @param pItem The item to insert.
127 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
128 * This applies only to GC.
129 * @thread Any thread.
130 */
131VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
132{
133 NOREF(NanoMaxDelay);
134 PDMQueueInsert(pQueue, pItem);
135#ifdef IN_RC
136 PVM pVM = pQueue->CTX_SUFF(pVM);
137 /** @todo figure out where to put this, the next bit should go there too.
138 if (NanoMaxDelay)
139 {
140
141 }
142 else */
143 {
144 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
145 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
146 }
147#endif
148}
149
150
151
152/**
153 * Gets the RC pointer for the specified queue.
154 *
155 * @returns The RC address of the queue.
156 * @returns NULL if pQueue is invalid.
157 * @param pQueue The queue handle.
158 */
159VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
160{
161 Assert(VALID_PTR(pQueue));
162 Assert(pQueue->pVMR3 && pQueue->pVMRC);
163#ifdef IN_RC
164 return pQueue;
165#else
166 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
167#endif
168}
169
170
171/**
172 * Gets the ring-0 pointer for the specified queue.
173 *
174 * @returns The ring-0 address of the queue.
175 * @returns NULL if pQueue is invalid.
176 * @param pQueue The queue handle.
177 */
178VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
179{
180 Assert(VALID_PTR(pQueue));
181 Assert(pQueue->pVMR3 && pQueue->pVMR0);
182#ifdef IN_RING0
183 return pQueue;
184#else
185 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
186#endif
187}
188
189
190/**
191 * Schedule the queue for flushing (processing) if necessary.
192 *
193 * @returns @c true if necessary, @c false if not.
194 * @param pQueue The queue.
195 */
196VMMDECL(bool) PDMQueueFlushIfNecessary(PPDMQUEUE pQueue)
197{
198 AssertPtr(pQueue);
199 if ( pQueue->pPendingR3 != NIL_RTR3PTR
200 || pQueue->pPendingR0 != NIL_RTR0PTR
201 || pQueue->pPendingRC != NIL_RTRCPTR)
202 {
203 pdmQueueSetFF(pQueue);
204 return false;
205 }
206 return false;
207}
208
Note: See TracBrowser for help on using the repository browser.

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