VirtualBox

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

Last change on this file since 26616 was 23012, checked in by vboxsync, 15 years ago

VMM,Devices,Main: VMR3ReqCall w/ RT_INDEFINITE_WAIT -> VMR3ReqCallWait.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* $Id: PDMAllQueue.cpp 23012 2009-09-14 16:38:13Z 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.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 * 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 STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
105}
106
107
108/**
109 * Queue an item.
110 * The item must have been obtained using PDMQueueAlloc(). Once the item
111 * have been passed to this function it must not be touched!
112 *
113 * @param pQueue The queue handle.
114 * @param pItem The item to insert.
115 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
116 * This applies only to GC.
117 * @thread Any thread.
118 */
119VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
120{
121 PDMQueueInsert(pQueue, pItem);
122#ifdef IN_RC
123 PVM pVM = pQueue->CTX_SUFF(pVM);
124 /** @todo figure out where to put this, the next bit should go there too.
125 if (NanoMaxDelay)
126 {
127
128 }
129 else */
130 {
131 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
132 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
133 }
134#endif
135}
136
137
138
139/**
140 * Gets the RC pointer for the specified queue.
141 *
142 * @returns The RC address of the queue.
143 * @returns NULL if pQueue is invalid.
144 * @param pQueue The queue handle.
145 */
146VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
147{
148 Assert(VALID_PTR(pQueue));
149 Assert(pQueue->pVMR3 && pQueue->pVMRC);
150#ifdef IN_RC
151 return pQueue;
152#else
153 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
154#endif
155}
156
157
158/**
159 * Gets the ring-0 pointer for the specified queue.
160 *
161 * @returns The ring-0 address of the queue.
162 * @returns NULL if pQueue is invalid.
163 * @param pQueue The queue handle.
164 */
165VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
166{
167 Assert(VALID_PTR(pQueue));
168 Assert(pQueue->pVMR3 && pQueue->pVMR0);
169#ifdef IN_RING0
170 return pQueue;
171#else
172 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
173#endif
174}
175
176
177/**
178 * Flushes a PDM queue.
179 *
180 * @param pQueue The queue handle.
181 */
182VMMDECL(void) PDMQueueFlush(PPDMQUEUE pQueue)
183{
184 Assert(VALID_PTR(pQueue));
185 Assert(pQueue->pVMR3);
186 PVM pVM = pQueue->CTX_SUFF(pVM);
187
188#if defined(IN_RC) || defined(IN_RING0)
189 Assert(pQueue->CTX_SUFF(pVM));
190 pVM->pdm.s.CTX_SUFF(pQueueFlush) = pQueue;
191 VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
192
193#else /* IN_RING3: */
194 VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)PDMR3QueueFlushWorker, 2, pVM, pQueue);
195#endif
196}
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