VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/utils/cpu/cpu-alloc-all-mem.cpp@ 93455

Last change on this file since 93455 was 93302, checked in by vboxsync, 3 years ago

ValKit: VC++ 19.2 update 11 build adjustments (uint64_t -> double conversions). bugref:8489

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: cpu-alloc-all-mem.cpp 93302 2022-01-18 11:25:24Z vboxsync $ */
2/** @file
3 * Allocate all memory we can get and then quit.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle Corporation
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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/test.h>
32
33#include <iprt/asm.h>
34#include <iprt/list.h>
35#include <iprt/mem.h>
36#include <iprt/param.h>
37#include <iprt/string.h>
38#include <iprt/time.h>
39
40
41/*********************************************************************************************************************************
42* Structures and Typedefs *
43*********************************************************************************************************************************/
44typedef struct TSTALLOC
45{
46 /** The page sequence number. */
47 size_t iPageSeq;
48 /** The allocation sequence number. */
49 size_t iAllocSeq;
50 /** The allocation size. */
51 size_t cb;
52 /** Pointer to the ourselves (paranoid). */
53 void *pv;
54 /** Linked list node. */
55 RTLISTNODE Node;
56
57} TSTALLOC;
58typedef TSTALLOC *PTSTALLOC;
59
60
61static bool checkList(PRTLISTNODE pHead)
62{
63 size_t iPageSeq = 0;
64 size_t iAllocSeq = 0;
65 PTSTALLOC pCur;
66 RTListForEach(pHead, pCur, TSTALLOC, Node)
67 {
68 RTTESTI_CHECK_RET(pCur->iAllocSeq == iAllocSeq, false);
69 RTTESTI_CHECK_RET(pCur->pv == pCur, false);
70
71 size_t const *pu = (size_t const *)pCur;
72 size_t const *puEnd = pu + pCur->cb / sizeof(size_t);
73 while (pu != puEnd)
74 {
75 RTTESTI_CHECK_RET(*pu == iPageSeq, false);
76 iPageSeq++;
77 pu += PAGE_SIZE / sizeof(size_t);
78 }
79 iAllocSeq++;
80 }
81 return true;
82}
83
84
85static void doTest(RTTEST hTest)
86{
87 RTTestSub(hTest, "Allocate all memory");
88
89 RTLISTANCHOR AllocHead;
90 PTSTALLOC pCur;
91 uint64_t cNsElapsed = 0;
92 size_t cbPrint = 0;
93 uint64_t uPrintTS = 0;
94 size_t cbTotal = 0;
95#if ARCH_BITS == 64
96 size_t const cbOneStart = 64 * _1M;
97 size_t const cbOneMin = 4 * _1M;
98#else
99 size_t const cbOneStart = 16 * _1M;
100 size_t const cbOneMin = 4 * _1M;
101#endif
102 size_t cbOne = cbOneStart;
103 size_t cAllocs = 0;
104 uint32_t iPageSeq = 0;
105 RTListInit(&AllocHead);
106
107 for (;;)
108 {
109 /*
110 * Allocate a chunk and make sure all the pages are there.
111 */
112 uint64_t const uStartTS = RTTimeNanoTS();
113 pCur = (PTSTALLOC)RTMemPageAlloc(cbOne);
114 if (pCur)
115 {
116 size_t *pu = (size_t *)pCur;
117 size_t *puEnd = pu + cbOne / sizeof(size_t);
118 while (pu != puEnd)
119 {
120 *pu = iPageSeq++;
121 pu += PAGE_SIZE / sizeof(size_t);
122 }
123 uint64_t const uEndTS = RTTimeNanoTS();
124 uint64_t const cNsThis = uEndTS - uStartTS;
125
126 /*
127 * Update the statistics.
128 */
129 cNsElapsed += cNsThis;
130 cbTotal += cbOne;
131 cAllocs++;
132
133 /*
134 * Link the allocation.
135 */
136 pCur->iAllocSeq = cAllocs - 1;
137 pCur->pv = pCur;
138 pCur->cb = cbOne;
139 RTListAppend(&AllocHead, &pCur->Node);
140
141 /*
142 * Print progress info?
143 */
144 if ( uEndTS - uPrintTS >= RT_NS_1SEC_64*10
145#if ARCH_BITS == 64
146 || cbTotal - cbPrint >= _4G
147#else
148 || cbTotal - cbPrint >= _2G
149#endif
150 )
151 {
152 cbPrint = cbTotal;
153 uPrintTS = uEndTS;
154
155 uint32_t cMBPerSec = (uint32_t)((long double)cbTotal / ((long double)cNsElapsed / RT_NS_1SEC) / _1M);
156 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "%'zu bytes in %'llu ns - %'u MB/s\n",
157 cbTotal, cNsElapsed, cMBPerSec);
158 RTTESTI_CHECK_RETV(checkList(&AllocHead));
159 }
160 }
161 else
162 {
163 /*
164 * Try again with a smaller request.
165 */
166 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Failed to allocate %'zu bytes (after %'zu bytes)\n", cbOne, cbTotal);
167 if (cbOne <= cbOneMin)
168 break;
169 cbOne = cbOneMin;
170 }
171 }
172
173 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Verifying...\n");
174 RTTESTI_CHECK_RETV(checkList(&AllocHead));
175 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "... detected no corruption.\n");
176
177 /*
178 * Free up some memory before displaying the results.
179 */
180 size_t i = 0;
181 PTSTALLOC pPrev;
182 RTListForEachReverseSafe(&AllocHead, pCur, pPrev, TSTALLOC, Node)
183 {
184 RTMemPageFree(pCur->pv, pCur->cb);
185 if (++i > 32)
186 break;
187 }
188
189 RTTestValue(hTest, "amount", cbTotal, RTTESTUNIT_BYTES);
190 RTTestValue(hTest, "time", cNsElapsed, RTTESTUNIT_NS);
191 uint32_t cMBPerSec = (uint32_t)((long double)cbTotal / ((long double)cNsElapsed / RT_NS_1SEC) / _1M);
192 RTTestValue(hTest, "speed", cMBPerSec, RTTESTUNIT_MEGABYTES_PER_SEC);
193 RTTestSubDone(hTest);
194}
195
196
197int main(int argc, char **argv)
198{
199 RTTEST hTest;
200 RTEXITCODE rcExit = RTTestInitAndCreate("memallocall", &hTest);
201 if (rcExit != RTEXITCODE_SUCCESS)
202 return rcExit;
203 RTTestBanner(hTest);
204
205 NOREF(argv);
206 if (argc == 1)
207 doTest(hTest);
208 else
209 RTTestFailed(hTest, "This test takes no arguments!");
210
211 return RTTestSummaryAndDestroy(hTest);
212}
213
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