VirtualBox

source: vbox/trunk/src/VBox/VMM/VMInternal.h@ 4403

Last change on this file since 4403 was 4296, checked in by vboxsync, 17 years ago

vmR3SetState must accessible of course.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.1 KB
Line 
1/* $Id: VMInternal.h 4296 2007-08-22 20:23:31Z vboxsync $ */
2/** @file
3 * VM - Internal header file.
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#ifndef ___VMInternal_h
19#define ___VMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/vmapi.h>
23#include <setjmp.h>
24
25#if !defined(IN_VM_R3) && !defined(IN_VM_R0) && !defined(IN_VM_GC)
26# error "Not in VM! This is an internal header!"
27#endif
28
29
30/** @defgroup grp_vm_int Internals
31 * @ingroup grp_vm
32 * @internal
33 * @{
34 */
35
36
37/**
38 * At-reset callback type.
39 */
40typedef enum VMATRESETTYPE
41{
42 /** Device callback. */
43 VMATRESETTYPE_DEV = 1,
44 /** Internal callback . */
45 VMATRESETTYPE_INTERNAL,
46 /** External callback. */
47 VMATRESETTYPE_EXTERNAL
48} VMATRESETTYPE;
49
50
51/** Pointer to at-reset callback. */
52typedef struct VMATRESET *PVMATRESET;
53
54/**
55 * At reset callback.
56 */
57typedef struct VMATRESET
58{
59 /** Pointer to the next one in the list. */
60 PVMATRESET pNext;
61 /** Callback type. */
62 VMATRESETTYPE enmType;
63 /** User argument for the callback. */
64 void *pvUser;
65 /** Description. */
66 const char *pszDesc;
67 /** Type specific data. */
68 union
69 {
70 /** VMATRESETTYPE_DEV. */
71 struct
72 {
73 /** Callback. */
74 PFNVMATRESET pfnCallback;
75 /** Device instance. */
76 PPDMDEVINS pDevIns;
77 } Dev;
78
79 /** VMATRESETTYPE_INTERNAL. */
80 struct
81 {
82 /** Callback. */
83 PFNVMATRESETINT pfnCallback;
84 } Internal;
85
86 /** VMATRESETTYPE_EXTERNAL. */
87 struct
88 {
89 /** Callback. */
90 PFNVMATRESETEXT pfnCallback;
91 } External;
92 } u;
93} VMATRESET;
94
95
96/**
97 * VM state change callback.
98 */
99typedef struct VMATSTATE
100{
101 /** Pointer to the next one. */
102 struct VMATSTATE *pNext;
103 /** Pointer to the callback. */
104 PFNVMATSTATE pfnAtState;
105 /** The user argument. */
106 void *pvUser;
107} VMATSTATE;
108/** Pointer to a VM state change callback. */
109typedef VMATSTATE *PVMATSTATE;
110
111
112/**
113 * VM error callback.
114 */
115typedef struct VMATERROR
116{
117 /** Pointer to the next one. */
118 struct VMATERROR *pNext;
119 /** Pointer to the callback. */
120 PFNVMATERROR pfnAtError;
121 /** The user argument. */
122 void *pvUser;
123} VMATERROR;
124/** Pointer to a VM error callback. */
125typedef VMATERROR *PVMATERROR;
126
127
128/**
129 * Chunk of memory allocated off the hypervisor heap in which
130 * we copy the error details.
131 */
132typedef struct VMERROR
133{
134 /** The size of the chunk. */
135 uint32_t cbAllocated;
136 /** The current offset into the chunk.
137 * We start by putting the filename and function immediatly
138 * after the end of the buffer. */
139 uint32_t off;
140 /** Offset from the start of this structure to the file name. */
141 uint32_t offFile;
142 /** The line number. */
143 uint32_t iLine;
144 /** Offset from the start of this structure to the function name. */
145 uint32_t offFunction;
146 /** Offset from the start of this structure to the formatted message text. */
147 uint32_t offMessage;
148 /** The VBox status code. */
149 int32_t rc;
150} VMERROR, *PVMERROR;
151
152
153/**
154 * VM runtime error callback.
155 */
156typedef struct VMATRUNTIMEERROR
157{
158 /** Pointer to the next one. */
159 struct VMATRUNTIMEERROR *pNext;
160 /** Pointer to the callback. */
161 PFNVMATRUNTIMEERROR pfnAtRuntimeError;
162 /** The user argument. */
163 void *pvUser;
164} VMATRUNTIMEERROR;
165/** Pointer to a VM error callback. */
166typedef VMATRUNTIMEERROR *PVMATRUNTIMEERROR;
167
168
169/**
170 * Chunk of memory allocated off the hypervisor heap in which
171 * we copy the runtime error details.
172 */
173typedef struct VMRUNTIMEERROR
174{
175 /** The size of the chunk. */
176 uint32_t cbAllocated;
177 /** The current offset into the chunk.
178 * We start by putting the error ID immediatly
179 * after the end of the buffer. */
180 uint32_t off;
181 /** Offset from the start of this structure to the error ID. */
182 uint32_t offErrorID;
183 /** Offset from the start of this structure to the formatted message text. */
184 uint32_t offMessage;
185 /** Whether the error is fatal or not */
186 bool fFatal;
187} VMRUNTIMEERROR, *PVMRUNTIMEERROR;
188
189/** The halt method. */
190typedef enum
191{
192 /** The usual invalid value. */
193 VMHALTMETHOD_INVALID = 0,
194 /** Use the default method. */
195 VMHALTMETHOD_DEFAULT,
196 /** The old spin/yield/block method. */
197 VMHALTMETHOD_OLD,
198 /** The first go at a block/spin method. */
199 VMHALTMETHOD_1,
200 /** The end of valid methods. (not inclusive of course) */
201 VMHALTMETHOD_END,
202 /** The usual 32-bit max value. */
203 VMHALTMETHOD_32BIT_HACK = 0x7fffffff
204} VMHALTMETHOD;
205
206
207/**
208 * Converts a VMM pointer into a VM pointer.
209 * @returns Pointer to the VM structure the VMM is part of.
210 * @param pVMM Pointer to VMM instance data.
211 */
212#define VMINT2VM(pVMM) ( (PVM)((char*)pVMM - pVMM->offVM) )
213
214
215/**
216 * VM Internal Data (part of VM)
217 */
218typedef struct VMINT
219{
220 /** Offset to the VM structure.
221 * See VMINT2VM(). */
222 RTINT offVM;
223
224 /** List of registered reset callbacks. */
225 HCPTRTYPE(PVMATRESET) pAtReset;
226 /** List of registered reset callbacks. */
227 HCPTRTYPE(PVMATRESET *) ppAtResetNext;
228
229 /** List of registered state change callbacks. */
230 HCPTRTYPE(PVMATSTATE) pAtState;
231 /** List of registered state change callbacks. */
232 HCPTRTYPE(PVMATSTATE *) ppAtStateNext;
233
234 /** List of registered error callbacks. */
235 HCPTRTYPE(PVMATERROR) pAtError;
236 /** List of registered error callbacks. */
237 HCPTRTYPE(PVMATERROR *) ppAtErrorNext;
238
239 /** List of registered error callbacks. */
240 HCPTRTYPE(PVMATRUNTIMEERROR) pAtRuntimeError;
241 /** List of registered error callbacks. */
242 HCPTRTYPE(PVMATRUNTIMEERROR *) ppAtRuntimeErrorNext;
243
244 /** Head of the request queue. Atomic. */
245 volatile HCPTRTYPE(PVMREQ) pReqs;
246 /** The last index used during alloc/free. */
247 volatile uint32_t iReqFree;
248 /** Array of pointers to lists of free request packets. Atomic. */
249 volatile HCPTRTYPE(PVMREQ) apReqFree[9];
250 /** Number of free request packets. */
251 volatile uint32_t cReqFree;
252
253 /** Wait/Idle indicator. */
254 volatile uint32_t fWait;
255 /** Wait event semaphore. */
256 HCPTRTYPE(RTSEMEVENT) EventSemWait;
257
258 /** VM Error Message. */
259 R3PTRTYPE(PVMERROR) pErrorR3;
260
261 /** VM Runtime Error Message. */
262 R3PTRTYPE(PVMRUNTIMEERROR) pRuntimeErrorR3;
263
264 /** Pointer to the DBGC instance data. */
265 HCPTRTYPE(void *) pvDBGC;
266
267 /** If set the EMT does the final VM cleanup when it exits.
268 * If clear the VMR3Destroy() caller does so. */
269 bool fEMTDoesTheCleanup;
270
271 /** Set by VMR3SuspendNoSave; cleared by VMR3Resume; signals the VM is in an inconsistent state and saving is not allowed. */
272 bool fPreventSaveState;
273
274 /** vmR3EmulationThread longjmp buffer
275 * @todo r=bird: requires union with padding. See EMInternal.h. */
276 jmp_buf emtJumpEnv;
277
278 /** @name Generic Halt data
279 * @{
280 */
281 /** The current halt method.
282 * Can be selected by CFGM option 'VM/HaltMethod'. */
283 VMHALTMETHOD enmHaltMethod;
284 /** The index into g_aHaltMethods of the current halt method. */
285 uint32_t volatile iHaltMethod;
286 /** The average time (ns) between two halts in the last second. (updated once per second) */
287 uint32_t HaltInterval;
288 /** The average halt frequency for the last second. (updated once per second) */
289 uint32_t HaltFrequency;
290 /** The number of halts in the current period. */
291 uint32_t cHalts;
292 uint32_t padding; /**< alignment padding. */
293 /** When we started counting halts in cHalts (RTTimeNanoTS). */
294 uint64_t u64HaltsStartTS;
295 /** @} */
296
297 /** Union containing data and config for the different halt algorithms. */
298 union
299 {
300 /**
301 * Method 1 & 2 - Block whenever possible, and when lagging behind
302 * switch to spinning with regular blocking every 5-200ms (defaults)
303 * depending on the accumulated lag. The blocking interval is adjusted
304 * with the average oversleeping of the last 64 times.
305 *
306 * The difference between 1 and 2 is that we use native absolute
307 * time APIs for the blocking instead of the millisecond based IPRT
308 * interface.
309 */
310 struct
311 {
312 /** How many times we've blocked while cBlockedNS and cBlockedTooLongNS has been accumulating. */
313 uint32_t cBlocks;
314 /** Avg. time spend oversleeping when blocking. (Re-calculated every so often.) */
315 uint64_t cNSBlockedTooLongAvg;
316 /** Total time spend oversleeping when blocking. */
317 uint64_t cNSBlockedTooLong;
318 /** Total time spent blocking. */
319 uint64_t cNSBlocked;
320 /** The timestamp (RTTimeNanoTS) of the last block. */
321 uint64_t u64LastBlockTS;
322
323 /** When we started spinning relentlessly in order to catch up some of the oversleeping.
324 * This is 0 when we're not spinning. */
325 uint64_t u64StartSpinTS;
326
327 /** The max interval without blocking (when spinning). */
328 uint32_t u32MinBlockIntervalCfg;
329 /** The minimum interval between blocking (when spinning). */
330 uint32_t u32MaxBlockIntervalCfg;
331 /** The value to divide the current lag by to get the raw blocking interval (when spinning). */
332 uint32_t u32LagBlockIntervalDivisorCfg;
333 /** When to start spinning (lag / nano secs). */
334 uint32_t u32StartSpinningCfg;
335 /** When to stop spinning (lag / nano secs). */
336 uint32_t u32StopSpinningCfg;
337 } Method12;
338
339#if 0
340 /**
341 * Method 3 & 4 - Same as method 1 & 2 respectivly, except that we
342 * sprinkle it with yields.
343 */
344 struct
345 {
346 /** How many times we've blocked while cBlockedNS and cBlockedTooLongNS has been accumulating. */
347 uint32_t cBlocks;
348 /** Avg. time spend oversleeping when blocking. (Re-calculated every so often.) */
349 uint64_t cBlockedTooLongNSAvg;
350 /** Total time spend oversleeping when blocking. */
351 uint64_t cBlockedTooLongNS;
352 /** Total time spent blocking. */
353 uint64_t cBlockedNS;
354 /** The timestamp (RTTimeNanoTS) of the last block. */
355 uint64_t u64LastBlockTS;
356
357 /** How many times we've yielded while cBlockedNS and cBlockedTooLongNS has been accumulating. */
358 uint32_t cYields;
359 /** Avg. time spend oversleeping when yielding. */
360 uint32_t cYieldTooLongNSAvg;
361 /** Total time spend oversleeping when yielding. */
362 uint64_t cYieldTooLongNS;
363 /** Total time spent yielding. */
364 uint64_t cYieldedNS;
365 /** The timestamp (RTTimeNanoTS) of the last block. */
366 uint64_t u64LastYieldTS;
367
368 /** When we started spinning relentlessly in order to catch up some of the oversleeping. */
369 uint64_t u64StartSpinTS;
370 } Method34;
371#endif
372 } Halt;
373
374 /** @} */
375
376 /** Number of VMR3ReqAlloc returning a new packet. */
377 STAMCOUNTER StatReqAllocNew;
378 /** Number of VMR3ReqAlloc causing races. */
379 STAMCOUNTER StatReqAllocRaces;
380 /** Number of VMR3ReqAlloc returning a recycled packet. */
381 STAMCOUNTER StatReqAllocRecycled;
382 /** Number of VMR3ReqFree calls. */
383 STAMCOUNTER StatReqFree;
384 /** Number of times the request was actually freed. */
385 STAMCOUNTER StatReqFreeOverflow;
386
387 /** Profiling the halted state; yielding vs blocking. */
388 STAMPROFILE StatHaltYield;
389 STAMPROFILE StatHaltBlock;
390 STAMPROFILE StatHaltTimers;
391 STAMPROFILE StatHaltPoll;
392} VMINT, *PVMINT;
393
394
395/**
396 * Emulation thread arguments.
397 */
398typedef struct VMEMULATIONTHREADARGS
399{
400 /** Pointer to the VM structure. */
401 PVM pVM;
402} VMEMULATIONTHREADARGS;
403/** Pointer to the emulation thread arguments. */
404typedef VMEMULATIONTHREADARGS *PVMEMULATIONTHREADARGS;
405
406DECLCALLBACK(int) vmR3EmulationThread(RTTHREAD ThreadSelf, void *pvArg);
407int vmR3SetHaltMethod(PVM pVM, VMHALTMETHOD enmHaltMethod);
408DECLCALLBACK(int) vmR3Destroy(PVM pVM);
409DECLCALLBACK(void) vmR3SetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *args);
410void vmSetErrorCopy(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
411DECLCALLBACK(void) vmR3SetRuntimeErrorV(PVM pVM, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list *args);
412void vmSetRuntimeErrorCopy(PVM pVM, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list args);
413void vmR3DestroyFinalBit(PVM pVM);
414void vmR3SetState(PVM pVM, VMSTATE enmStateNew);
415
416
417/** @} */
418
419#endif
420
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