VirtualBox

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

Last change on this file since 5232 was 5167, checked in by vboxsync, 17 years ago

New halt method.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.1 KB
Line 
1/* $Id: VMInternal.h 5167 2007-10-05 13:33:36Z 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 first go at a more global approach. */
201 VMHALTMETHOD_GLOBAL_1,
202 /** The end of valid methods. (not inclusive of course) */
203 VMHALTMETHOD_END,
204 /** The usual 32-bit max value. */
205 VMHALTMETHOD_32BIT_HACK = 0x7fffffff
206} VMHALTMETHOD;
207
208
209/**
210 * Converts a VMM pointer into a VM pointer.
211 * @returns Pointer to the VM structure the VMM is part of.
212 * @param pVMM Pointer to VMM instance data.
213 */
214#define VMINT2VM(pVMM) ( (PVM)((char*)pVMM - pVMM->offVM) )
215
216
217/**
218 * VM Internal Data (part of VM)
219 */
220typedef struct VMINT
221{
222 /** Offset to the VM structure.
223 * See VMINT2VM(). */
224 RTINT offVM;
225
226 /** List of registered reset callbacks. */
227 R3PTRTYPE(PVMATRESET) pAtReset;
228 /** List of registered reset callbacks. */
229 R3PTRTYPE(PVMATRESET *) ppAtResetNext;
230
231 /** List of registered state change callbacks. */
232 R3PTRTYPE(PVMATSTATE) pAtState;
233 /** List of registered state change callbacks. */
234 R3PTRTYPE(PVMATSTATE *) ppAtStateNext;
235
236 /** List of registered error callbacks. */
237 R3PTRTYPE(PVMATERROR) pAtError;
238 /** List of registered error callbacks. */
239 R3PTRTYPE(PVMATERROR *) ppAtErrorNext;
240
241 /** List of registered error callbacks. */
242 R3PTRTYPE(PVMATRUNTIMEERROR) pAtRuntimeError;
243 /** List of registered error callbacks. */
244 R3PTRTYPE(PVMATRUNTIMEERROR *) ppAtRuntimeErrorNext;
245
246 /** Head of the request queue. Atomic. */
247 volatile R3PTRTYPE(PVMREQ) pReqs;
248 /** The last index used during alloc/free. */
249 volatile uint32_t iReqFree;
250 /** Array of pointers to lists of free request packets. Atomic. */
251 volatile R3PTRTYPE(PVMREQ) apReqFree[9];
252 /** Number of free request packets. */
253 volatile uint32_t cReqFree;
254
255 /** Wait/Idle indicator. */
256 volatile uint32_t fWait;
257 /** Wait event semaphore. */
258 R3PTRTYPE(RTSEMEVENT) EventSemWait;
259
260 /** VM Error Message. */
261 R3PTRTYPE(PVMERROR) pErrorR3;
262
263 /** VM Runtime Error Message. */
264 R3PTRTYPE(PVMRUNTIMEERROR) pRuntimeErrorR3;
265
266 /** Pointer to the DBGC instance data. */
267 R3PTRTYPE(void *) pvDBGC;
268
269 /** If set the EMT does the final VM cleanup when it exits.
270 * If clear the VMR3Destroy() caller does so. */
271 bool fEMTDoesTheCleanup;
272
273 /** Set by VMR3SuspendNoSave; cleared by VMR3Resume; signals the VM is in an inconsistent state and saving is not allowed. */
274 bool fPreventSaveState;
275
276 /** vmR3EmulationThread longjmp buffer
277 * @todo r=bird: requires union with padding. See EMInternal.h. */
278 jmp_buf emtJumpEnv;
279
280 /** @name Generic Halt data
281 * @{
282 */
283 /** The current halt method.
284 * Can be selected by CFGM option 'VM/HaltMethod'. */
285 VMHALTMETHOD enmHaltMethod;
286 /** The index into g_aHaltMethods of the current halt method. */
287 uint32_t volatile iHaltMethod;
288 /** The average time (ns) between two halts in the last second. (updated once per second) */
289 uint32_t HaltInterval;
290 /** The average halt frequency for the last second. (updated once per second) */
291 uint32_t HaltFrequency;
292 /** The number of halts in the current period. */
293 uint32_t cHalts;
294 uint32_t padding; /**< alignment padding. */
295 /** When we started counting halts in cHalts (RTTimeNanoTS). */
296 uint64_t u64HaltsStartTS;
297 /** @} */
298
299 /** Union containing data and config for the different halt algorithms. */
300 union
301 {
302 /**
303 * Method 1 & 2 - Block whenever possible, and when lagging behind
304 * switch to spinning with regular blocking every 5-200ms (defaults)
305 * depending on the accumulated lag. The blocking interval is adjusted
306 * with the average oversleeping of the last 64 times.
307 *
308 * The difference between 1 and 2 is that we use native absolute
309 * time APIs for the blocking instead of the millisecond based IPRT
310 * interface.
311 */
312 struct
313 {
314 /** How many times we've blocked while cBlockedNS and cBlockedTooLongNS has been accumulating. */
315 uint32_t cBlocks;
316 /** Avg. time spend oversleeping when blocking. (Re-calculated every so often.) */
317 uint64_t cNSBlockedTooLongAvg;
318 /** Total time spend oversleeping when blocking. */
319 uint64_t cNSBlockedTooLong;
320 /** Total time spent blocking. */
321 uint64_t cNSBlocked;
322 /** The timestamp (RTTimeNanoTS) of the last block. */
323 uint64_t u64LastBlockTS;
324
325 /** When we started spinning relentlessly in order to catch up some of the oversleeping.
326 * This is 0 when we're not spinning. */
327 uint64_t u64StartSpinTS;
328
329 /** The max interval without blocking (when spinning). */
330 uint32_t u32MinBlockIntervalCfg;
331 /** The minimum interval between blocking (when spinning). */
332 uint32_t u32MaxBlockIntervalCfg;
333 /** The value to divide the current lag by to get the raw blocking interval (when spinning). */
334 uint32_t u32LagBlockIntervalDivisorCfg;
335 /** When to start spinning (lag / nano secs). */
336 uint32_t u32StartSpinningCfg;
337 /** When to stop spinning (lag / nano secs). */
338 uint32_t u32StopSpinningCfg;
339 } Method12;
340
341#if 0
342 /**
343 * Method 3 & 4 - Same as method 1 & 2 respectivly, except that we
344 * sprinkle it with yields.
345 */
346 struct
347 {
348 /** How many times we've blocked while cBlockedNS and cBlockedTooLongNS has been accumulating. */
349 uint32_t cBlocks;
350 /** Avg. time spend oversleeping when blocking. (Re-calculated every so often.) */
351 uint64_t cBlockedTooLongNSAvg;
352 /** Total time spend oversleeping when blocking. */
353 uint64_t cBlockedTooLongNS;
354 /** Total time spent blocking. */
355 uint64_t cBlockedNS;
356 /** The timestamp (RTTimeNanoTS) of the last block. */
357 uint64_t u64LastBlockTS;
358
359 /** How many times we've yielded while cBlockedNS and cBlockedTooLongNS has been accumulating. */
360 uint32_t cYields;
361 /** Avg. time spend oversleeping when yielding. */
362 uint32_t cYieldTooLongNSAvg;
363 /** Total time spend oversleeping when yielding. */
364 uint64_t cYieldTooLongNS;
365 /** Total time spent yielding. */
366 uint64_t cYieldedNS;
367 /** The timestamp (RTTimeNanoTS) of the last block. */
368 uint64_t u64LastYieldTS;
369
370 /** When we started spinning relentlessly in order to catch up some of the oversleeping. */
371 uint64_t u64StartSpinTS;
372 } Method34;
373#endif
374 } Halt;
375
376 /** @} */
377
378 /** Number of VMR3ReqAlloc returning a new packet. */
379 STAMCOUNTER StatReqAllocNew;
380 /** Number of VMR3ReqAlloc causing races. */
381 STAMCOUNTER StatReqAllocRaces;
382 /** Number of VMR3ReqAlloc returning a recycled packet. */
383 STAMCOUNTER StatReqAllocRecycled;
384 /** Number of VMR3ReqFree calls. */
385 STAMCOUNTER StatReqFree;
386 /** Number of times the request was actually freed. */
387 STAMCOUNTER StatReqFreeOverflow;
388
389 /** Profiling the halted state; yielding vs blocking. */
390 STAMPROFILE StatHaltYield;
391 STAMPROFILE StatHaltBlock;
392 STAMPROFILE StatHaltTimers;
393 STAMPROFILE StatHaltPoll;
394} VMINT, *PVMINT;
395
396
397/**
398 * Emulation thread arguments.
399 */
400typedef struct VMEMULATIONTHREADARGS
401{
402 /** Pointer to the VM structure. */
403 PVM pVM;
404} VMEMULATIONTHREADARGS;
405/** Pointer to the emulation thread arguments. */
406typedef VMEMULATIONTHREADARGS *PVMEMULATIONTHREADARGS;
407
408DECLCALLBACK(int) vmR3EmulationThread(RTTHREAD ThreadSelf, void *pvArg);
409int vmR3SetHaltMethod(PVM pVM, VMHALTMETHOD enmHaltMethod);
410DECLCALLBACK(int) vmR3Destroy(PVM pVM);
411DECLCALLBACK(void) vmR3SetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list *args);
412void vmSetErrorCopy(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
413DECLCALLBACK(void) vmR3SetRuntimeErrorV(PVM pVM, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list *args);
414void vmSetRuntimeErrorCopy(PVM pVM, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list args);
415void vmR3DestroyFinalBit(PVM pVM);
416void vmR3SetState(PVM pVM, VMSTATE enmStateNew);
417
418
419/** @} */
420
421#endif
422
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