/* $Id: bs3-locking-1.c $ */ /** @file * BS3Kit - bs3-locking-1, 16-bit C code. */ /* * Copyright (C) 2007-2023 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included * in the VirtualBox distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. * * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 */ /********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #include #include #include /********************************************************************************************************************************* * Global Variables * *********************************************************************************************************************************/ static struct { const char * BS3_FAR pszName; uint32_t cInnerLoops; uint32_t uCtrlLo; uint32_t uCtrlHi; } g_aLockingTests[] = { #if 1 # if 1 /* no contention benchmark */ { "None 0us/inf/0k", _32K, 0, 0, }, { "RW None Exl 0us/inf/0k", _32K, 0, 0 | VMMDEV_TESTING_LOCKED_HI_TYPE_RW, }, # endif { "RW None Shr 0us/inf/0k", _32K, 0, 0 | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_EMT_SHARED, }, # if 1 { "Contention 500us/250us/64k", 2000 + 16384, 500 | (UINT32_C(250) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 64 | VMMDEV_TESTING_LOCKED_HI_ENABLED, }, { "Contention 100us/50us/8k", 10000 + 4096, 100 | (UINT32_C(50) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 8 | VMMDEV_TESTING_LOCKED_HI_ENABLED, }, { "Contention 10us/1us/0k", 16384 + 4096, 10 | (UINT32_C(1) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 0 | VMMDEV_TESTING_LOCKED_HI_ENABLED, }, { "Contention 500us/250us/64k poke", 2000 + 16384, 500 | (UINT32_C(250) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 64 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_POKE, }, { "Contention 100us/50us/1k poke", 10000 + 4096, 100 | (UINT32_C(50) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 1 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_POKE, }, { "Contention 500us/250us/64k poke void", 2000 + 16384, 500 | (UINT32_C(250) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 64 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_POKE | VMMDEV_TESTING_LOCKED_HI_BUSY_SUCCESS }, { "Contention 50us/25us/8k poke void", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 1 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_POKE | VMMDEV_TESTING_LOCKED_HI_BUSY_SUCCESS }, # endif # if 1 { "RW Contention Exl/Exl 50us/25us/16k", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW }, # endif { "RW Contention Shr/Exl 50us/25us/16k", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_THREAD_SHARED }, # if 1 { "RW Contention Exl/Exl 50us/25us/16k poke", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_POKE }, # endif { "RW Contention Shr/Exl 50us/25us/16k poke", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_THREAD_SHARED | VMMDEV_TESTING_LOCKED_HI_POKE | VMMDEV_TESTING_LOCKED_HI_BUSY_SUCCESS }, # if 1 { "RW Contention Exl/Exl 50us/25us/16k poke void", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_POKE }, # endif { "RW Contention Shr/Exl 50us/25us/16k poke void", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_THREAD_SHARED | VMMDEV_TESTING_LOCKED_HI_POKE | VMMDEV_TESTING_LOCKED_HI_BUSY_SUCCESS }, #endif { "RW Contention Exl/Shr 50us/25us/16k", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_EMT_SHARED }, { "RW Contention Exl/Shr poke 250us/25us/16k", 10000 + 4096, 250 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_EMT_SHARED | VMMDEV_TESTING_LOCKED_HI_POKE }, { "RW Contention Exl/Shr poke void 250us/25us/16k", 10000 + 4096, 250 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_EMT_SHARED | VMMDEV_TESTING_LOCKED_HI_POKE | VMMDEV_TESTING_LOCKED_HI_BUSY_SUCCESS }, { "RW None Shr/Shr 50us/25us/16k", 20000 + 4096, 50 | (UINT32_C(25) << VMMDEV_TESTING_LOCKED_LO_WAIT_SHIFT), 16 | VMMDEV_TESTING_LOCKED_HI_ENABLED | VMMDEV_TESTING_LOCKED_HI_TYPE_RW | VMMDEV_TESTING_LOCKED_HI_THREAD_SHARED | VMMDEV_TESTING_LOCKED_HI_EMT_SHARED }, }; BS3_DECL(void) Main_rm() { uint64_t const cNsPerTest = RT_NS_15SEC; unsigned i; Bs3InitAll_rm(); Bs3TestInit("bs3-locking-1"); /* * Since this is a host-side test and we don't have raw-mode any more, we * just stay in raw-mode when doing the test. */ for (i = 0; i < RT_ELEMENTS(g_aLockingTests); i++) { uint64_t const nsStart = Bs3TestNow(); uint64_t cNsElapsed = 0; uint32_t cTotal = 0; uint32_t j; Bs3TestSub(g_aLockingTests[i].pszName); ASMOutU32(VMMDEV_TESTING_IOPORT_LOCKED_LO, g_aLockingTests[i].uCtrlLo); ASMOutU32(VMMDEV_TESTING_IOPORT_LOCKED_HI, g_aLockingTests[i].uCtrlHi); for (j = 0; j < _2M && cTotal < _1G; j++) { /* The inner loop should avoid calling Bs3TestNow too often, while not overshooting the . */ unsigned iInner = (unsigned)g_aLockingTests[i].cInnerLoops; cTotal += iInner; while (iInner-- > 0) ASMInU32(VMMDEV_TESTING_IOPORT_LOCKED_LO); cNsElapsed = Bs3TestNow() - nsStart; if (cNsElapsed >= cNsPerTest) break; } /* Disable locking. */ ASMOutU32(VMMDEV_TESTING_IOPORT_LOCKED_HI, 0); Bs3TestValue("Loops", cTotal, VMMDEV_TESTING_UNIT_OCCURRENCES); Bs3TestValue("Elapsed", cNsElapsed, VMMDEV_TESTING_UNIT_NS); Bs3TestValue("PerLoop", cNsElapsed / cTotal, VMMDEV_TESTING_UNIT_NS_PER_OCCURRENCE); } Bs3TestTerm(); }