VirtualBox

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

Last change on this file since 5605 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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