VirtualBox

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

Last change on this file since 12983 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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