VirtualBox

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

Last change on this file since 21161 was 21128, checked in by vboxsync, 16 years ago

PDMQueue: Fixed the flushing loop when a consumer (NAT?) had had enough.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1/* $Id: PDMAllQueue.cpp 21128 2009-07-01 14:46:19Z 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 return NULL;
61 pNew = pQueue->aFreeItems[i].CTX_SUFF(pItem);
62 iNext = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
63 } while (!ASMAtomicCmpXchgU32(&pQueue->iFreeTail, iNext, i));
64 return pNew;
65}
66
67
68/**
69 * Queue an item.
70 * The item must have been obtained using PDMQueueAlloc(). Once the item
71 * have been passed to this function it must not be touched!
72 *
73 * @param pQueue The queue handle.
74 * @param pItem The item to insert.
75 * @thread Any thread.
76 */
77VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
78{
79 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
80 Assert(VALID_PTR(pItem));
81
82 PPDMQUEUEITEMCORE pNext;
83 do
84 {
85 pNext = pQueue->CTX_SUFF(pPending);
86 pItem->CTX_SUFF(pNext) = pNext;
87 } while (!ASMAtomicCmpXchgPtr((void * volatile *)&pQueue->CTX_SUFF(pPending), pItem, pNext));
88
89 if (!pQueue->pTimer)
90 {
91 PVM pVM = pQueue->CTX_SUFF(pVM);
92 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
93 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
94 ASMAtomicBitSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
95#ifdef IN_RING3
96 REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
97 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
98#endif
99 }
100}
101
102
103/**
104 * Queue an item.
105 * The item must have been obtained using PDMQueueAlloc(). Once the item
106 * have been passed to this function it must not be touched!
107 *
108 * @param pQueue The queue handle.
109 * @param pItem The item to insert.
110 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
111 * This applies only to GC.
112 * @thread Any thread.
113 */
114VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
115{
116 PDMQueueInsert(pQueue, pItem);
117#ifdef IN_RC
118 PVM pVM = pQueue->CTX_SUFF(pVM);
119 /** @todo figure out where to put this, the next bit should go there too.
120 if (NanoMaxDelay)
121 {
122
123 }
124 else */
125 {
126 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
127 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
128 }
129#endif
130}
131
132
133
134/**
135 * Gets the RC pointer for the specified queue.
136 *
137 * @returns The RC address of the queue.
138 * @returns NULL if pQueue is invalid.
139 * @param pQueue The queue handle.
140 */
141VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
142{
143 Assert(VALID_PTR(pQueue));
144 Assert(pQueue->pVMR3 && pQueue->pVMRC);
145#ifdef IN_RC
146 return pQueue;
147#else
148 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
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 Assert(VALID_PTR(pQueue));
163 Assert(pQueue->pVMR3 && pQueue->pVMR0);
164#ifdef IN_RING0
165 return pQueue;
166#else
167 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
168#endif
169}
170
171
172/**
173 * Flushes a PDM queue.
174 *
175 * @param pQueue The queue handle.
176 */
177VMMDECL(void) PDMQueueFlush(PPDMQUEUE pQueue)
178{
179 Assert(VALID_PTR(pQueue));
180 Assert(pQueue->pVMR3);
181 PVM pVM = pQueue->CTX_SUFF(pVM);
182
183#if defined(IN_RC) || defined(IN_RING0)
184 Assert(pQueue->CTX_SUFF(pVM));
185 pVM->pdm.s.CTX_SUFF(pQueueFlush) = pQueue;
186 VMMRZCallRing3NoCpu(pVM, VMMCALLRING3_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
187
188#else /* IN_RING3: */
189 PVMREQ pReq;
190 VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PDMR3QueueFlushWorker, 2, pVM, pQueue);
191 VMR3ReqFree(pReq);
192#endif
193}
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