VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstFileAio.cpp@ 28800

Last change on this file since 28800 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: tstFileAio.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * IPRT Testcase - File Async I/O.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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/file.h>
32#include <iprt/types.h>
33#include <iprt/err.h>
34#include <iprt/string.h>
35#include <iprt/stream.h>
36#include <iprt/mem.h>
37#include <iprt/initterm.h>
38
39/** @todo make configurable through cmd line. */
40#define TSTFILEAIO_MAX_REQS_IN_FLIGHT 64
41#define TSTFILEAIO_BUFFER_SIZE 64*_1K
42
43/* Global error counter. */
44int cErrors = 0;
45
46void tstFileAioTestReadWriteBasic(RTFILE File, bool fWrite, void *pvTestBuf, size_t cbTestBuf, size_t cbTestFile, uint32_t cMaxReqsInFlight)
47{
48 int rc = VINF_SUCCESS;
49 RTFILEAIOCTX hAioContext;
50 uint64_t NanoTS = RTTimeNanoTS();
51
52 RTPrintf("tstFileAio: Starting simple %s test...\n", fWrite ? "write" : "read");
53
54 rc = RTFileAioCtxCreate(&hAioContext, cMaxReqsInFlight);
55 if (RT_SUCCESS(rc))
56 {
57 RTFILEAIOREQ *paReqs = NULL;
58 void **papvBuf = NULL;
59 RTFOFF Offset = 0;
60 size_t cbLeft = cbTestFile;
61 int cRun = 0;
62
63 /* Allocate request array. */
64 paReqs = (PRTFILEAIOREQ)RTMemAllocZ(cMaxReqsInFlight * sizeof(RTFILEAIOREQ));
65 if (paReqs)
66 {
67 /* Allocate array holding pointer to data buffers. */
68 papvBuf = (void **)RTMemAllocZ(cMaxReqsInFlight * sizeof(void *));
69 if (papvBuf)
70 {
71 /* Allocate array holding completed requests. */
72 RTFILEAIOREQ *paReqsCompleted = NULL;
73 paReqsCompleted = (PRTFILEAIOREQ)RTMemAllocZ(cMaxReqsInFlight * sizeof(RTFILEAIOREQ));
74 if (paReqsCompleted)
75 {
76 /* Associate file with context.*/
77 rc = RTFileAioCtxAssociateWithFile(hAioContext, File);
78 if (RT_SUCCESS(rc))
79 {
80 /* Initialize buffers. */
81 for (unsigned i = 0; i < cMaxReqsInFlight; i++)
82 {
83 papvBuf[i] = RTMemPageAllocZ(cbTestBuf);
84
85 if (fWrite)
86 memcpy(papvBuf[i], pvTestBuf, cbTestBuf);
87 }
88
89 /* Initialize requests. */
90 for (unsigned i = 0; i < cMaxReqsInFlight; i++)
91 RTFileAioReqCreate(&paReqs[i]);
92
93 while (cbLeft)
94 {
95 int cReqs = 0;
96
97 for (unsigned i = 0; i < cMaxReqsInFlight; i++)
98 {
99 size_t cbTransfer = (cbLeft < cbTestBuf) ? cbLeft : cbTestBuf;
100
101 if (!cbTransfer)
102 break;
103
104 if (fWrite)
105 rc = RTFileAioReqPrepareWrite(paReqs[i], File, Offset, papvBuf[i],
106 cbTransfer, papvBuf[i]);
107 else
108 rc = RTFileAioReqPrepareRead(paReqs[i], File, Offset, papvBuf[i],
109 cbTransfer, papvBuf[i]);
110
111 cbLeft -= cbTransfer;
112 Offset += cbTransfer;
113 cReqs++;
114 }
115
116 rc = RTFileAioCtxSubmit(hAioContext, paReqs, cReqs);
117 if (RT_FAILURE(rc))
118 {
119 RTPrintf("tstFileAio: FATAL ERROR - Failed to submit tasks after %d runs. rc=%Rrc\n", cRun, rc);
120 cErrors++;
121 break;
122 }
123
124 /* Wait */
125 uint32_t cCompleted = 0;
126 rc = RTFileAioCtxWait(hAioContext, cReqs, RT_INDEFINITE_WAIT,
127 paReqsCompleted, cMaxReqsInFlight,
128 &cCompleted);
129 if (RT_FAILURE(rc))
130 {
131 RTPrintf("tstFileAio: FATAL ERROR - Waiting failed. rc=%Rrc\n", rc);
132 cErrors++;
133 break;
134 }
135
136 if (!fWrite)
137 {
138 for (uint32_t i = 0; i < cCompleted; i++)
139 {
140 /* Compare that we read the right stuff. */
141 void *pvBuf = RTFileAioReqGetUser(paReqsCompleted[i]);
142
143 size_t cbTransfered;
144 int rcReq = RTFileAioReqGetRC(paReqsCompleted[i], &cbTransfered);
145 if (RT_FAILURE(rcReq) || (cbTransfered != cbTestBuf))
146 {
147 RTPrintf("tstFileAio: FATAL ERROR - Request %d failed with rc=%Rrc cbTransfered=%d.\n",
148 i, rcReq, cbTransfered);
149 cErrors++;
150 rc = rcReq;
151 break;
152 }
153
154 if (memcmp(pvBuf, pvTestBuf, cbTestBuf) != 0)
155 {
156 RTPrintf("tstFileAio: FATAL ERROR - Unexpected content in memory.\n");
157 cErrors++;
158 break;
159 }
160 memset(pvBuf, 0, cbTestBuf);
161 }
162 }
163 cRun++;
164 if (RT_FAILURE(rc))
165 break;
166 }
167
168 /* Free buffers. */
169 for (unsigned i = 0; i < cMaxReqsInFlight; i++)
170 RTMemPageFree(papvBuf[i], cbTestBuf);
171
172 /* Free requests. */
173 for (unsigned i = 0; i < cMaxReqsInFlight; i++)
174 {
175 rc = RTFileAioReqDestroy(paReqs[i]);
176 if (RT_FAILURE(rc))
177 {
178 RTPrintf("tstFileAio: ERROR - Failed to destroy request %d. rc=%Rrc\n", i, rc);
179 cErrors++;
180 }
181 }
182
183 NanoTS = RTTimeNanoTS() - NanoTS;
184 unsigned SpeedKBs = (unsigned)(cbTestFile / (NanoTS / 1000000000.0) / 1024);
185
186 RTPrintf("tstFileAio: Completed simple %s test: %d.%03d MB/sec\n",
187 fWrite ? "write" : "read",
188 SpeedKBs / 1000,
189 SpeedKBs % 1000);
190 }
191 else
192 {
193 RTPrintf("tstFileAio: FATAL ERROR - Failed to asssociate file with async I/O context. rc=%Rrc\n", rc);
194 cErrors++;
195 }
196 }
197 else
198 {
199 RTPrintf("tstFileAio: FATAL ERROR - Failed to allocate memory for completed request array.\n");
200 cErrors++;
201 }
202 RTMemFree(papvBuf);
203 }
204 else
205 {
206 RTPrintf("tstFileAio: FATAL ERROR - Failed to allocate memory for buffer array.\n");
207 cErrors++;
208 }
209 RTMemFree(paReqs);
210 }
211 else
212 {
213 RTPrintf("tstFileAio: FATAL ERROR - Failed to allocate memory for request array.\n");
214 cErrors++;
215 }
216
217 rc = RTFileAioCtxDestroy(hAioContext);
218 if (RT_FAILURE(rc))
219 {
220 RTPrintf("tstFileAio: FATAL ERROR - Failed to destroy async I/O context. rc=%Rrc\n", rc);
221 cErrors++;
222 }
223 }
224 else
225 {
226 RTPrintf("tstFileAio: FATAL ERROR - Failed to create async I/O context. rc=%Rrc\n", rc);
227 cErrors++;
228 }
229}
230
231int main()
232{
233 RTPrintf("tstFileAio: TESTING\n");
234 RTR3Init();
235
236 /* Check if the API is available. */
237 RTFILEAIOLIMITS AioLimits;
238
239 memset(&AioLimits, 0, sizeof(AioLimits));
240 int rc = RTFileAioGetLimits(&AioLimits);
241 if (RT_FAILURE(rc))
242 {
243 if (rc == VERR_NOT_SUPPORTED)
244 RTPrintf("tstFileAio: FATAL ERROR - File AIO API not available\n");
245 else
246 RTPrintf("tstFileAio: FATAL ERROR - Unexpected error rc=%Rrc\n", rc);
247 return 1;
248 }
249
250 RTFILE File;
251 void *pvTestBuf = NULL;
252 rc = RTFileOpen(&File, "tstFileAio#1.tst", RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_ASYNC_IO);
253 if (RT_FAILURE(rc))
254 {
255 RTPrintf("tstFileAio: FATAL ERROR - Failed to open file #1. rc=%Rrc\n", rc);
256 return 1;
257 }
258
259 pvTestBuf = RTMemAllocZ(64 * _1K);
260 for (unsigned i = 0; i < 64*_1K; i++)
261 ((char *)pvTestBuf)[i] = i % 256;
262
263 uint32_t cReqsMax = AioLimits.cReqsOutstandingMax < TSTFILEAIO_MAX_REQS_IN_FLIGHT
264 ? AioLimits.cReqsOutstandingMax
265 : TSTFILEAIO_MAX_REQS_IN_FLIGHT;
266
267 /* Basic write test. */
268 RTPrintf("tstFileAio: Preparing test file, this can take some time and needs quite a bit of harddisk\n");
269 tstFileAioTestReadWriteBasic(File, true, pvTestBuf, 64*_1K, 100*_1M, cReqsMax);
270 /* Reopen the file. */
271 RTFileClose(File);
272 rc = RTFileOpen(&File, "tstFileAio#1.tst", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_ASYNC_IO);
273 if (RT_SUCCESS(rc))
274 {
275 tstFileAioTestReadWriteBasic(File, false, pvTestBuf, 64*_1K, 100*_1M, cReqsMax);
276 RTFileClose(File);
277 }
278 else
279 {
280 RTPrintf("tstFileAio: FATAL ERROR - Failed to open file #1. rc=%Rrc\n", rc);
281 cErrors++;
282 }
283
284 /* Cleanup */
285 RTMemFree(pvTestBuf);
286 RTFileDelete("tstFileAio#1.tst");
287 /*
288 * Summary
289 */
290 if (cErrors == 0)
291 RTPrintf("tstFileAio: SUCCESS\n");
292 else
293 RTPrintf("tstFileAio: FAILURE - %d errors\n", cErrors);
294 return !!cErrors;
295}
296
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