VirtualBox

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

Last change on this file since 4050 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
1/* $Id: PDMAllQueue.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 * PDM Queue - Transport data and tasks to EMT and R3.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#define LOG_GROUP LOG_GROUP_PDM_QUEUE
26#include "PDMInternal.h"
27#include <VBox/pdm.h>
28#ifndef IN_GC
29# include <VBox/rem.h>
30# include <VBox/mm.h>
31#endif
32#include <VBox/vm.h>
33#include <VBox/err.h>
34#include <VBox/log.h>
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37
38
39/**
40 * Allocate an item from a queue.
41 * The allocated item must be handed on to PDMR3QueueInsert() after the
42 * data have been filled in.
43 *
44 * @returns Pointer to allocated queue item.
45 * @returns NULL on failure. The queue is exhausted.
46 * @param pQueue The queue handle.
47 * @thread Any thread.
48 */
49PDMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue)
50{
51 Assert(VALID_PTR(pQueue) && pQueue->CTXSUFF(pVM));
52 PPDMQUEUEITEMCORE pNew;
53 uint32_t iNext;
54 uint32_t i;
55 do
56 {
57 i = pQueue->iFreeTail;
58 if (i == pQueue->iFreeHead)
59 return NULL;
60 pNew = pQueue->aFreeItems[i].CTXSUFF(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 */
76PDMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem)
77{
78 Assert(VALID_PTR(pQueue) && pQueue->CTXSUFF(pVM));
79 Assert(VALID_PTR(pItem));
80
81 PPDMQUEUEITEMCORE pNext;
82 do
83 {
84 pNext = pQueue->CTXSUFF(pPending);
85 pItem->CTXSUFF(pNext) = pNext;
86 } while (!ASMAtomicCmpXchgPtr((void * volatile *)&pQueue->CTXSUFF(pPending), pItem, pNext));
87
88 if (!pQueue->pTimer)
89 {
90 PVM pVM = pQueue->CTXSUFF(pVM);
91 Log2(("PDMQueueInsert: VM_FF_PDM_QUEUES %d -> 1\n", VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES)));
92 VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
93#ifdef IN_RING3
94 REMR3NotifyQueuePending(pVM); /** @todo r=bird: we can remove REMR3NotifyQueuePending and let VMR3NotifyFF do the work. */
95 VMR3NotifyFF(pVM, true);
96#endif
97 }
98}
99
100
101/**
102 * Queue an item.
103 * The item must have been obtained using PDMQueueAlloc(). Once the item
104 * have been passed to this function it must not be touched!
105 *
106 * @param pQueue The queue handle.
107 * @param pItem The item to insert.
108 * @param NanoMaxDelay The maximum delay before processing the queue, in nanoseconds.
109 * This applies only to GC.
110 * @thread Any thread.
111 */
112PDMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay)
113{
114 PDMQueueInsert(pQueue, pItem);
115#ifdef IN_GC
116 PVM pVM = pQueue->CTXSUFF(pVM);
117 /** @todo figure out where to put this, the next bit should go there too.
118 if (NanoMaxDelay)
119 {
120
121 }
122 else */
123 {
124 VM_FF_SET(pVM, VM_FF_TO_R3);
125 Log2(("PDMQueueInsertEx: Setting VM_FF_TO_R3\n"));
126 }
127#endif
128}
129
130
131
132/**
133 * Gets the GC pointer for the specified queue.
134 *
135 * @returns The GC address of the queue.
136 * @returns NULL if pQueue is invalid.
137 * @param pQueue The queue handle.
138 */
139PDMDECL(GCPTRTYPE(PPDMQUEUE)) PDMQueueGCPtr(PPDMQUEUE pQueue)
140{
141 Assert(VALID_PTR(pQueue));
142 Assert(pQueue->pVMHC && pQueue->pVMGC);
143#ifdef IN_GC
144 return pQueue;
145#else
146 return MMHyperHC2GC(pQueue->pVMHC, pQueue);
147#endif
148}
149
150
151/**
152 * Flushes a PDM queue.
153 *
154 * @param pQueue The queue handle.
155 */
156PDMDECL(void) PDMQueueFlush(PPDMQUEUE pQueue)
157{
158 Assert(VALID_PTR(pQueue));
159 Assert(pQueue->pVMHC && pQueue->pVMGC);
160 PVM pVM = CTXSUFF(pQueue->pVM);
161#ifdef IN_GC
162 pVM->pdm.s.CTXSUFF(pQueueFlush) = pQueue;
163 VMMGCCallHost(pVM, VMMCALLHOST_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
164#elif defined(IN_RING0)
165 pVM->pdm.s.CTXSUFF(pQueueFlush) = pQueue;
166 VMMR0CallHost(pVM, VMMCALLHOST_PDM_QUEUE_FLUSH, (uintptr_t)pQueue);
167#else /* IN_RING3: */
168 PVMREQ pReq;
169 VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PDMR3QueueFlushWorker, 2, pVM, pQueue);
170 VMR3ReqFree(pReq);
171#endif
172}
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