VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.5 KB
Line 
1/* $Id: PDMAllQueue.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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(RT_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 *
86 * The item must have been obtained using PDMQueueAlloc(). Once the item
87 * have been passed to this function it must not be touched!
88 *
89 * @param pQueue The queue handle.
90 * @param pItem The item to insert.
91 * @thread Any thread.
92 */
93VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
94{
95 Assert(RT_VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
96 AssertPtr(pItem);
97
98#if 0 /* the paranoid android version: */
99 void *pvNext;
100 do
101 {
102 pvNext = ASMAtomicUoReadPtr((void * volatile *)&pQueue->CTX_SUFF(pPending));
103 ASMAtomicUoWritePtr((void * volatile *)&pItem->CTX_SUFF(pNext), pvNext);
104 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pvNext));
105#else
106 PPDMQUEUEITEMCORE pNext;
107 do
108 {
109 pNext = pQueue->CTX_SUFF(pPending);
110 pItem->CTX_SUFF(pNext) = pNext;
111 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pNext));
112#endif
113
114 if (pQueue->hTimer == NIL_TMTIMERHANDLE)
115 pdmQueueSetFF(pQueue);
116 STAM_REL_COUNTER_INC(&pQueue->StatInsert);
117 STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
118}
119
120
121/**
122 * Queue an item.
123 *
124 * The item must have been obtained using PDMQueueAlloc(). Once the item
125 * have been passed to this function it must not be touched!
126 *
127 * @param pQueue The queue handle.
128 * @param pItem The item to insert.
129 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
130 * This applies only to GC.
131 * @thread Any thread.
132 */
133VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
134{
135 NOREF(NanoMaxDelay);
136 PDMQueueInsert(pQueue, pItem);
137#ifdef IN_RC
138 PVM pVM = pQueue->CTX_SUFF(pVM);
139 /** @todo figure out where to put this, the next bit should go there too.
140 if (NanoMaxDelay)
141 {
142
143 }
144 else */
145 {
146 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
147 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
148 }
149#endif
150}
151
152
153/**
154 * Gets the ring-0 pointer for the specified queue.
155 *
156 * @returns The ring-0 address of the queue.
157 * @returns NULL if pQueue is invalid.
158 * @param pQueue The queue handle.
159 */
160VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
161{
162 AssertPtr(pQueue);
163 Assert(pQueue->pVMR3);
164#ifdef IN_RING0
165 AssertPtr(pQueue->pVMR0);
166 return pQueue;
167#else
168 Assert(pQueue->pVMR0 || SUPR3IsDriverless());
169 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
170#endif
171}
172
173
174/**
175 * Schedule the queue for flushing (processing) if necessary.
176 *
177 * @returns @c true if necessary, @c false if not.
178 * @param pQueue The queue.
179 */
180VMMDECL(bool) PDMQueueFlushIfNecessary(PPDMQUEUE pQueue)
181{
182 AssertPtr(pQueue);
183 if ( pQueue->pPendingR3 != NIL_RTR3PTR
184 || pQueue->pPendingR0 != NIL_RTR0PTR)
185 {
186 pdmQueueSetFF(pQueue);
187 return false;
188 }
189 return false;
190}
191
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