VirtualBox

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

Last change on this file since 43667 was 41965, checked in by vboxsync, 12 years ago

VMM: ran scm. Mostly svn:keywords changes (adding Revision).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.3 KB
Line 
1/* $Id: PDMAllQueue.cpp 41965 2012-06-29 02:52:49Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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# ifdef VBOX_WITH_REM
27# include <VBox/vmm/rem.h>
28# endif
29# include <VBox/vmm/mm.h>
30#endif
31#include <VBox/vmm/vm.h>
32#include <VBox/err.h>
33#include <VBox/log.h>
34#include <iprt/asm.h>
35#include <iprt/assert.h>
36
37
38/**
39 * Allocate an item from a queue.
40 * The allocated item must be handed on to PDMR3QueueInsert() after the
41 * data have been filled in.
42 *
43 * @returns Pointer to allocated queue item.
44 * @returns NULL on failure. The queue is exhausted.
45 * @param pQueue The queue handle.
46 * @thread Any thread.
47 */
48VMMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue)
49{
50 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
51 PPDMQUEUEITEMCORE pNew;
52 uint32_t iNext;
53 uint32_t i;
54 do
55 {
56 i = pQueue->iFreeTail;
57 if (i == pQueue->iFreeHead)
58 {
59 STAM_REL_COUNTER_INC(&pQueue->StatAllocFailures);
60 return NULL;
61 }
62 pNew = pQueue->aFreeItems[i].CTX_SUFF(pItem);
63 iNext = (i + 1) % (pQueue->cItems + PDMQUEUE_FREE_SLACK);
64 } while (!ASMAtomicCmpXchgU32(&pQueue->iFreeTail, iNext, i));
65 return pNew;
66}
67
68
69/**
70 * Queue an item.
71 * The item must have been obtained using PDMQueueAlloc(). Once the item
72 * have been passed to this function it must not be touched!
73 *
74 * @param pQueue The queue handle.
75 * @param pItem The item to insert.
76 * @thread Any thread.
77 */
78VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
79{
80 Assert(VALID_PTR(pQueue) && pQueue->CTX_SUFF(pVM));
81 Assert(VALID_PTR(pItem));
82
83#if 0 /* the paranoid android version: */
84 void *pvNext;
85 do
86 {
87 pvNext = ASMAtomicUoReadPtr((void * volatile *)&pQueue->CTX_SUFF(pPending));
88 ASMAtomicUoWritePtr((void * volatile *)&pItem->CTX_SUFF(pNext), pvNext);
89 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pvNext));
90#else
91 PPDMQUEUEITEMCORE pNext;
92 do
93 {
94 pNext = pQueue->CTX_SUFF(pPending);
95 pItem->CTX_SUFF(pNext) = pNext;
96 } while (!ASMAtomicCmpXchgPtr(&pQueue->CTX_SUFF(pPending), pItem, pNext));
97#endif
98
99 if (!pQueue->pTimer)
100 {
101 PVM pVM = pQueue->CTX_SUFF(pVM);
102 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
103 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
104 ASMAtomicBitSet(&pVM->pdm.s.fQueueFlushing, PDM_QUEUE_FLUSH_FLAG_PENDING_BIT);
105#ifdef IN_RING3
106# ifdef VBOX_WITH_REM
107 REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
108# endif
109 VMR3NotifyGlobalFFU(pVM->pUVM, VMNOTIFYFF_FLAGS_DONE_REM);
110#endif
111 }
112 STAM_REL_COUNTER_INC(&pQueue->StatInsert);
113 STAM_STATS({ ASMAtomicIncU32(&pQueue->cStatPending); });
114}
115
116
117/**
118 * Queue an item.
119 * The item must have been obtained using PDMQueueAlloc(). Once the item
120 * have been passed to this function it must not be touched!
121 *
122 * @param pQueue The queue handle.
123 * @param pItem The item to insert.
124 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
125 * This applies only to GC.
126 * @thread Any thread.
127 */
128VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
129{
130 NOREF(NanoMaxDelay);
131 PDMQueueInsert(pQueue, pItem);
132#ifdef IN_RC
133 PVM pVM = pQueue->CTX_SUFF(pVM);
134 /** @todo figure out where to put this, the next bit should go there too.
135 if (NanoMaxDelay)
136 {
137
138 }
139 else */
140 {
141 VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_TO_R3);
142 Log2(("PDMQueueInsertEx: Setting VMCPU_FF_TO_R3\n"));
143 }
144#endif
145}
146
147
148
149/**
150 * Gets the RC pointer for the specified queue.
151 *
152 * @returns The RC address of the queue.
153 * @returns NULL if pQueue is invalid.
154 * @param pQueue The queue handle.
155 */
156VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue)
157{
158 Assert(VALID_PTR(pQueue));
159 Assert(pQueue->pVMR3 && pQueue->pVMRC);
160#ifdef IN_RC
161 return pQueue;
162#else
163 return MMHyperCCToRC(pQueue->CTX_SUFF(pVM), pQueue);
164#endif
165}
166
167
168/**
169 * Gets the ring-0 pointer for the specified queue.
170 *
171 * @returns The ring-0 address of the queue.
172 * @returns NULL if pQueue is invalid.
173 * @param pQueue The queue handle.
174 */
175VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue)
176{
177 Assert(VALID_PTR(pQueue));
178 Assert(pQueue->pVMR3 && pQueue->pVMR0);
179#ifdef IN_RING0
180 return pQueue;
181#else
182 return MMHyperCCToR0(pQueue->CTX_SUFF(pVM), pQueue);
183#endif
184}
185
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use