VirtualBox

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

Last change on this file since 32035 was 30111, checked in by vboxsync, 14 years ago

iprt/asm.h,*: Revised the ASMAtomic*Ptr functions and macros. The new saves lots of unsafe (void * volatile *) casts as well as adding some type safety when using GCC (typeof rulez).

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