VBoxServiceBalloon.cpp revision 65d6ef67b3cf4d2f4c84af4d50439eb738d2ea31
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/* $Id$ */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @file
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * VBoxService - Memory Ballooning.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
b3eb676cebf5407921b8f535095ca7655edb9db3vboxsync/*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Copyright (C) 2006-2010 Sun Microsystems, Inc.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * available from http://www.virtualbox.org. This file is free software;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * you can redistribute it and/or modify it under the terms of the GNU
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * General Public License (GPL) as published by the Free Software
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * additional information or have any questions.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
2d97f8baccdd684bc0a8a15eb86bbe9ff2b85374vboxsync/*******************************************************************************
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync* Header Files *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync*******************************************************************************/
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/assert.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/mem.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/stream.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/string.h>
032703cba22135d6032705fc2d67dd1294a6491avboxsync#include <iprt/semaphore.h>
032703cba22135d6032705fc2d67dd1294a6491avboxsync#include <iprt/system.h>
032703cba22135d6032705fc2d67dd1294a6491avboxsync#include <iprt/thread.h>
032703cba22135d6032705fc2d67dd1294a6491avboxsync#include <iprt/time.h>
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync#include <VBox/VBoxGuestLib.h>
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync#include "VBoxServiceInternal.h"
032703cba22135d6032705fc2d67dd1294a6491avboxsync#include "VBoxServiceUtils.h"
032703cba22135d6032705fc2d67dd1294a6491avboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync/*******************************************************************************
032703cba22135d6032705fc2d67dd1294a6491avboxsync* Global Variables *
032703cba22135d6032705fc2d67dd1294a6491avboxsync*******************************************************************************/
032703cba22135d6032705fc2d67dd1294a6491avboxsync/** The balloon size. */
032703cba22135d6032705fc2d67dd1294a6491avboxsyncstatic uint32_t g_cMemBalloonChunks = 0;
032703cba22135d6032705fc2d67dd1294a6491avboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync/** The semaphore we're blocking on. */
032703cba22135d6032705fc2d67dd1294a6491avboxsyncstatic RTSEMEVENTMULTI g_MemBalloonEvent = NIL_RTSEMEVENTMULTI;
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync/** The array holding the R3 pointers of the balloon */
032703cba22135d6032705fc2d67dd1294a6491avboxsyncstatic void **g_pavBalloon = NULL;
032703cba22135d6032705fc2d67dd1294a6491avboxsync
4edc278439db2c83a5a59a104ec85e379d4c07dfvboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync/**
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync * Adapt the R0 memory balloon by granting/reclaiming 1MB chunks to/from R0.
032703cba22135d6032705fc2d67dd1294a6491avboxsync *
032703cba22135d6032705fc2d67dd1294a6491avboxsync * returns IPRT status code.
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync * @param cNewChunks The new number of 1MB chunks in the balloon.
032703cba22135d6032705fc2d67dd1294a6491avboxsync */
032703cba22135d6032705fc2d67dd1294a6491avboxsyncstatic int VBoxServiceBalloonSetUser(uint32_t cNewChunks)
032703cba22135d6032705fc2d67dd1294a6491avboxsync{
032703cba22135d6032705fc2d67dd1294a6491avboxsync if (cNewChunks == g_cMemBalloonChunks)
032703cba22135d6032705fc2d67dd1294a6491avboxsync return VINF_SUCCESS;
032703cba22135d6032705fc2d67dd1294a6491avboxsync
032703cba22135d6032705fc2d67dd1294a6491avboxsync int rc = VINF_SUCCESS;
032703cba22135d6032705fc2d67dd1294a6491avboxsync if (cNewChunks > g_cMemBalloonChunks)
032703cba22135d6032705fc2d67dd1294a6491avboxsync {
032703cba22135d6032705fc2d67dd1294a6491avboxsync /* inflate */
032703cba22135d6032705fc2d67dd1294a6491avboxsync uint32_t i;
032703cba22135d6032705fc2d67dd1294a6491avboxsync g_pavBalloon = (void**)RTMemRealloc(g_pavBalloon, cNewChunks * sizeof(void*));
032703cba22135d6032705fc2d67dd1294a6491avboxsync for (i = g_cMemBalloonChunks; i < cNewChunks; i++)
032703cba22135d6032705fc2d67dd1294a6491avboxsync {
032703cba22135d6032705fc2d67dd1294a6491avboxsync/** @todo r=bird: this isn't safe on linux. See suplibOsPageAlloc in
032703cba22135d6032705fc2d67dd1294a6491avboxsync * SUPLib-linux.cpp. We should probably just fail outright here if
032703cba22135d6032705fc2d67dd1294a6491avboxsync * linux, just in case... */
032703cba22135d6032705fc2d67dd1294a6491avboxsync void *pv = RTMemPageAlloc(VMMDEV_MEMORY_BALLOON_CHUNK_SIZE);
032703cba22135d6032705fc2d67dd1294a6491avboxsync rc = VbglR3MemBalloonChange(pv, /* inflate=*/ true);
032703cba22135d6032705fc2d67dd1294a6491avboxsync if (RT_SUCCESS(rc))
032703cba22135d6032705fc2d67dd1294a6491avboxsync {
032703cba22135d6032705fc2d67dd1294a6491avboxsync g_pavBalloon[i] = pv;
032703cba22135d6032705fc2d67dd1294a6491avboxsync /* protect against access by dangling pointers (may fail) */
032703cba22135d6032705fc2d67dd1294a6491avboxsync RTMemProtect(pv, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_cMemBalloonChunks++;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTMemPageFree(pv);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync break;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync }
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync }
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync }
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync else
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* deflate */
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync uint32_t i;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync for (i = g_cMemBalloonChunks; i-- > cNewChunks;)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync void *pv = g_pavBalloon[i];
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync rc = VbglR3MemBalloonChange(pv, /* inflate=*/ false);
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync if (RT_SUCCESS(rc))
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync {
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync /* unprotect */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTMemProtect(pv, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync RTMemPageFree(g_pavBalloon[i]);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_pavBalloon[i] = NULL;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_cMemBalloonChunks--;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync }
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync else
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync break;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync }
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync return VINF_SUCCESS;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsyncstatic DECLCALLBACK(int) VBoxServiceBalloonPreInit(void)
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync{
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync return VINF_SUCCESS;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @copydoc VBOXSERVICE::pfnOption */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic DECLCALLBACK(int) VBoxServiceBalloonOption(const char **ppszShort, int argc, char **argv, int *pi)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NOREF(ppszShort);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NOREF(argc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NOREF(argv);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NOREF(pi);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return VINF_SUCCESS;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @copydoc VBOXSERVICE::pfnInit */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic DECLCALLBACK(int) VBoxServiceBalloonInit(void)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonInit\n");
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync int rc = RTSemEventMultiCreate(&g_MemBalloonEvent);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync AssertRCReturn(rc, rc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_cMemBalloonChunks = 0;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uint32_t cNewChunks = 0;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync bool fHandleInR3;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* Check balloon size */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync rc = VbglR3MemBalloonRefresh(&cNewChunks, &fHandleInR3);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (RT_SUCCESS(rc))
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxMemBalloonInit: new balloon size %d MB (%s memory)\n",
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync cNewChunks, fHandleInR3 ? "R3" : "R0");
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (fHandleInR3)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync rc = VBoxServiceBalloonSetUser(cNewChunks);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_cMemBalloonChunks = cNewChunks;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxMemBalloonInit: VbglR3MemBalloonRefresh failed with %Rrc\n", rc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* We shouldn't fail here if ballooning isn't available. This can have several reasons,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * for instance, host too old (which is not that fatal). */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return VINF_SUCCESS;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/**
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Query the size of the memory balloon, given as a count of chunks.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * @returns The number of chunks (VMMDEV_MEMORY_BALLOON_CHUNK_SIZE).
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncuint32_t VBoxServiceBalloonQueryChunks(void)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return g_cMemBalloonChunks;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @copydoc VBOXSERVICE::pfnWorker */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncDECLCALLBACK(int) VBoxServiceBalloonWorker(bool volatile *pfShutdown)
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync{
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync /* Start monitoring of the stat event change event. */
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync int rc = VbglR3CtlFilterMask(VMMDEV_EVENT_BALLOON_CHANGE_REQUEST, 0);
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync if (RT_FAILURE(rc))
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %Rrc\n", rc);
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync return rc;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Tell the control thread that it can continue
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * spawning services.
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync */
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync RTThreadUserSignal(RTThreadSelf());
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync /*
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync * Now enter the loop retrieving runtime data continuously.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync for (;;)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uint32_t fEvents = 0;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* Check if an update interval change is pending. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync rc = VbglR3WaitEvent(VMMDEV_EVENT_BALLOON_CHANGE_REQUEST, 0 /* no wait */, &fEvents);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if ( RT_SUCCESS(rc)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync && (fEvents & VMMDEV_EVENT_BALLOON_CHANGE_REQUEST))
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync {
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync uint32_t cNewChunks;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync bool fHandleInR3;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync rc = VbglR3MemBalloonRefresh(&cNewChunks, &fHandleInR3);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (RT_SUCCESS(rc))
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: new balloon size %d MB (%s memory)\n",
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync cNewChunks, fHandleInR3 ? "R3" : "R0");
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync if (fHandleInR3)
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync rc = VBoxServiceBalloonSetUser(cNewChunks);
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_cMemBalloonChunks = cNewChunks;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3MemBalloonRefresh failed with %Rrc\n", rc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Block for a while.
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync *
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync * The event semaphore takes care of ignoring interruptions and it
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync * allows us to implement service wakeup later.
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (*pfShutdown)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync break;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync int rc2 = RTSemEventMultiWait(g_MemBalloonEvent, 5000);
315f68b04971772d94ba6c4408eaa19559a77cedvboxsync if (*pfShutdown)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync break;
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2))
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync {
b6cedcca2caa8d1bb6310dfc0d51981c51b97014vboxsync VBoxServiceError("RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync rc = rc2;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync break;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* Cancel monitoring of the memory balloon change event. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_BALLOON_CHANGE_REQUEST);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (RT_FAILURE(rc))
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: VbglR3CtlFilterMask failed with %Rrc\n", rc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTSemEventMultiDestroy(g_MemBalloonEvent);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_MemBalloonEvent = NIL_RTSEMEVENTMULTI;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonWorker: finished mem balloon change request thread\n");
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return 0;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @copydoc VBOXSERVICE::pfnTerm */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic DECLCALLBACK(void) VBoxServiceBalloonTerm(void)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceVerbose(3, "VBoxServiceBalloonTerm\n");
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @copydoc VBOXSERVICE::pfnStop */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic DECLCALLBACK(void) VBoxServiceBalloonStop(void)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTSemEventMultiSignal(g_MemBalloonEvent);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/**
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * The 'memballoon' service description.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncVBOXSERVICE g_MemBalloon =
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* pszName. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync "memballoon",
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* pszDescription. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync "Memory Ballooning",
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* pszUsage. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NULL,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* pszOptions. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync NULL,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* methods */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonPreInit,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonOption,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonInit,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonWorker,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonStop,
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync VBoxServiceBalloonTerm
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync};
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync