VirtualBox

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

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

Use PDM lock for protecting pdm queue management.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 5.6 KB
 
1/* $Id: PDMAllQueue.cpp 19784 2009-05-18 13:15:46Z 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.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 * 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 *
50 * Note: SMP safe
51 */
52VMMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue)
53{
54 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
55 PPDMQUEUEITEMCORE pNew;
56 uint32_t iNext;
57 uint32_t i;
58 do
59 {
60 i = pQueue->iFreeTail;
61 if (i == pQueue->iFreeHead)
62 return NULL;
63 pNew = pQueue->aFreeItems[i].CTX_SUFF(pItem);
64 iNext = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
65 } while (!ASMAtomicCmpXchgU32(&pQueue->iFreeTail, iNext, i));
66 return pNew;
67}
68
69
70/**
71 * Queue an item.
72 * The item must have been obtained using PDMQueueAlloc(). Once the item
73 * have been passed to this function it must not be touched!
74 *
75 * @param pQueue The queue handle.
76 * @param pItem The item to insert.
77 * @thread Any thread.
78 *
79 * Note: SMP safe
80 */
81VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
82{
83 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
84 Assert(VALID_PTR(pItem));
85
86 PPDMQUEUEITEMCORE pNext;
87 do
88 {
89 pNext = pQueue->CTX_SUFF(pPending);
90 pItem->CTX_SUFF(pNext) = pNext;
91 } while (!ASMAtomicCmpXchgPtr((void * volatile *)&pQueue->CTX_SUFF(pPending), pItem, pNext));
92
93 if (!pQueue->pTimer)
94 {
95 PVM pVM = pQueue->CTX_SUFF(pVM);
96 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
97 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
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}
104
105
106/**
107 * Queue an item.
108 * The item must have been obtained using PDMQueueAlloc(). Once the item
109 * have been passed to this function it must not be touched!
110 *
111 * @param pQueue The queue handle.
112 * @param pItem The item to insert.
113 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
114 * This applies only to GC.
115 * @thread Any thread.
116 */
117VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
118{
119 PDMQueueInsert(pQueue, pItem);
120#ifdef IN_RC
121 PVM pVM = pQueue->CTX_SUFF(pVM);
122 /** @todo figure out where to put this, the next bit should go there too.
123 if (NanoMaxDelay)
124 {
125
126 }
127 else */
128 {
129 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
130 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
131 }
132#endif
133}
134
135
136
137/**
138 * Gets the RC pointer for the specified queue.
139 *
140 * @returns The RC address of the queue.
141 * @returns NULL if pQueue is invalid.
142 * @param pQueue The queue handle.
143 */
144VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
145{
146 Assert(VALID_PTR(pQueue));
147 Assert(pQueue->pVMR3 && pQueue->pVMRC);
148#ifdef IN_RC
149 return pQueue;
150#else
151 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
152#endif
153}
154
155
156/**
157 * Gets the ring-0 pointer for the specified queue.
158 *
159 * @returns The ring-0 address of the queue.
160 * @returns NULL if pQueue is invalid.
161 * @param pQueue The queue handle.
162 */
163VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
164{
165 Assert(VALID_PTR(pQueue));
166 Assert(pQueue->pVMR3 && pQueue->pVMR0);
167#ifdef IN_RING0
168 return pQueue;
169#else
170 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
171#endif
172}
173
174
175/**
176 * Flushes a PDM queue.
177 *
178 * @param pQueue The queue handle.
179 */
180VMMDECL(void) PDMQueueFlush(PPDMQUEUE pQueue)
181{
182 Assert(VALID_PTR(pQueue));
183 Assert(pQueue->pVMR3);
184 PVM pVM = pQueue->CTX_SUFF(pVM);
185
186#ifdef IN_RC
187 Assert(pQueue->pVMRC);
188 pVM->pdm.s.CTX_SUFF(pQueueFlush) = pQueue;
189 VMMGCCallHost(pVM, VMMCALLHOST_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
190
191#elif defined(IN_RING0)
192 Assert(pQueue->pVMR0);
193 pVM->pdm.s.CTX_SUFF(pQueueFlush) = pQueue;
194 VMMR0CallHost(pVM, VMMCALLHOST_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
195
196#else /* IN_RING3: */
197 PVMREQ pReq;
198 Assert(!pdmIsLockOwner(pVM));
199 VMR3ReqCall(pVM, VMCPUID_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PDMR3QueueFlushWorker, 2, pVM, pQueue);
200 VMR3ReqFree(pReq);
201#endif
202}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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