VirtualBox

source: vbox/trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h@ 36818

Last change on this file since 36818 was 36799, checked in by vboxsync, 14 years ago

AsyncCompletion: Add debugger command to inject delays. Disabled by default

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 KB
Line 
1/* $Id: PDMAsyncCompletionFileInternal.h 36799 2011-04-21 16:48:42Z vboxsync $ */
2/** @file
3 * PDM Async I/O - Transport data asynchronous in R3 using EMT.
4 */
5
6/*
7 * Copyright (C) 2006-2008 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
18#ifndef ___PDMAsyncCompletionFileInternal_h
19#define ___PDMAsyncCompletionFileInternal_h
20
21#include <VBox/vmm/cfgm.h>
22#include <VBox/vmm/stam.h>
23#include <VBox/vmm/tm.h>
24#include <iprt/types.h>
25#include <iprt/file.h>
26#include <iprt/thread.h>
27#include <iprt/semaphore.h>
28#include <iprt/critsect.h>
29#include <iprt/avl.h>
30#include <iprt/list.h>
31#include <iprt/spinlock.h>
32#include <iprt/memcache.h>
33
34#include "PDMAsyncCompletionInternal.h"
35
36/** @todo: Revise the caching of tasks. We have currently four caches:
37 * Per endpoint task cache
38 * Per class cache
39 * Per endpoint task segment cache
40 * Per class task segment cache
41 *
42 * We could use the RT heap for this probably or extend MMR3Heap (uses RTMemAlloc
43 * instead of managing larger blocks) to have this global for the whole VM.
44 */
45
46/** Enable for delay injection from the debugger. */
47#if 0
48# define PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
49#endif
50
51RT_C_DECLS_BEGIN
52
53/**
54 * A few forward declarations.
55 */
56typedef struct PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
57/** Pointer to a request segment. */
58typedef struct PDMACTASKFILE *PPDMACTASKFILE;
59/** Pointer to the endpoint class data. */
60typedef struct PDMASYNCCOMPLETIONTASKFILE *PPDMASYNCCOMPLETIONTASKFILE;
61/** Pointer to a cache LRU list. */
62typedef struct PDMACFILELRULIST *PPDMACFILELRULIST;
63/** Pointer to the global cache structure. */
64typedef struct PDMACFILECACHEGLOBAL *PPDMACFILECACHEGLOBAL;
65/** Pointer to a task segment. */
66typedef struct PDMACFILETASKSEG *PPDMACFILETASKSEG;
67
68/**
69 * Blocking event types.
70 */
71typedef enum PDMACEPFILEAIOMGRBLOCKINGEVENT
72{
73 /** Invalid tye */
74 PDMACEPFILEAIOMGRBLOCKINGEVENT_INVALID = 0,
75 /** An endpoint is added to the manager. */
76 PDMACEPFILEAIOMGRBLOCKINGEVENT_ADD_ENDPOINT,
77 /** An endpoint is removed from the manager. */
78 PDMACEPFILEAIOMGRBLOCKINGEVENT_REMOVE_ENDPOINT,
79 /** An endpoint is about to be closed. */
80 PDMACEPFILEAIOMGRBLOCKINGEVENT_CLOSE_ENDPOINT,
81 /** The manager is requested to terminate */
82 PDMACEPFILEAIOMGRBLOCKINGEVENT_SHUTDOWN,
83 /** The manager is requested to suspend */
84 PDMACEPFILEAIOMGRBLOCKINGEVENT_SUSPEND,
85 /** The manager is requested to resume */
86 PDMACEPFILEAIOMGRBLOCKINGEVENT_RESUME,
87 /** 32bit hack */
88 PDMACEPFILEAIOMGRBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
89} PDMACEPFILEAIOMGRBLOCKINGEVENT;
90
91/**
92 * I/O manager type.
93 */
94typedef enum PDMACEPFILEMGRTYPE
95{
96 /** Simple aka failsafe */
97 PDMACEPFILEMGRTYPE_SIMPLE = 0,
98 /** Async I/O with host cache enabled. */
99 PDMACEPFILEMGRTYPE_ASYNC,
100 /** 32bit hack */
101 PDMACEPFILEMGRTYPE_32BIT_HACK = 0x7fffffff
102} PDMACEPFILEMGRTYPE;
103/** Pointer to a I/O manager type */
104typedef PDMACEPFILEMGRTYPE *PPDMACEPFILEMGRTYPE;
105
106/**
107 * States of the I/O manager.
108 */
109typedef enum PDMACEPFILEMGRSTATE
110{
111 /** Invalid state. */
112 PDMACEPFILEMGRSTATE_INVALID = 0,
113 /** Normal running state accepting new requests
114 * and processing them.
115 */
116 PDMACEPFILEMGRSTATE_RUNNING,
117 /** Fault state - not accepting new tasks for endpoints but waiting for
118 * remaining ones to finish.
119 */
120 PDMACEPFILEMGRSTATE_FAULT,
121 /** Suspending state - not accepting new tasks for endpoints but waiting
122 * for remaining ones to finish.
123 */
124 PDMACEPFILEMGRSTATE_SUSPENDING,
125 /** Shutdown state - not accepting new tasks for endpoints but waiting
126 * for remaining ones to finish.
127 */
128 PDMACEPFILEMGRSTATE_SHUTDOWN,
129 /** The I/O manager waits for all active requests to complete and doesn't queue
130 * new ones because it needs to grow to handle more requests.
131 */
132 PDMACEPFILEMGRSTATE_GROWING,
133 /** 32bit hack */
134 PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff
135} PDMACEPFILEMGRSTATE;
136
137/**
138 * State of a async I/O manager.
139 */
140typedef struct PDMACEPFILEMGR
141{
142 /** Next Aio manager in the list. */
143 R3PTRTYPE(struct PDMACEPFILEMGR *) pNext;
144 /** Previous Aio manager in the list. */
145 R3PTRTYPE(struct PDMACEPFILEMGR *) pPrev;
146 /** Manager type */
147 PDMACEPFILEMGRTYPE enmMgrType;
148 /** Current state of the manager. */
149 PDMACEPFILEMGRSTATE enmState;
150 /** Event semaphore the manager sleeps on when waiting for new requests. */
151 RTSEMEVENT EventSem;
152 /** Flag whether the thread waits in the event semaphore. */
153 volatile bool fWaitingEventSem;
154 /** Thread data */
155 RTTHREAD Thread;
156 /** The async I/O context for this manager. */
157 RTFILEAIOCTX hAioCtx;
158 /** Flag whether the I/O manager was woken up. */
159 volatile bool fWokenUp;
160 /** List of endpoints assigned to this manager. */
161 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointsHead;
162 /** Number of endpoints assigned to the manager. */
163 unsigned cEndpoints;
164 /** Number of requests active currently. */
165 unsigned cRequestsActive;
166 /** Number of maximum requests active. */
167 uint32_t cRequestsActiveMax;
168 /** Pointer to an array of free async I/O request handles. */
169 RTFILEAIOREQ *pahReqsFree;
170 /** Index of the next free entry in the cache. */
171 uint32_t iFreeEntry;
172 /** Size of the array. */
173 unsigned cReqEntries;
174 /** Memory cache for file range locks. */
175 RTMEMCACHE hMemCacheRangeLocks;
176 /** Number of milliseconds to wait until the bandwidth is refreshed for at least
177 * one endpoint and it is possible to process more requests. */
178 RTMSINTERVAL msBwLimitExpired;
179 /** Critical section protecting the blocking event handling. */
180 RTCRITSECT CritSectBlockingEvent;
181 /** Event semaphore for blocking external events.
182 * The caller waits on it until the async I/O manager
183 * finished processing the event. */
184 RTSEMEVENT EventSemBlock;
185 /** Flag whether a blocking event is pending and needs
186 * processing by the I/O manager. */
187 volatile bool fBlockingEventPending;
188 /** Blocking event type */
189 volatile PDMACEPFILEAIOMGRBLOCKINGEVENT enmBlockingEvent;
190 /** Event type data */
191 union
192 {
193 /** Add endpoint event. */
194 struct
195 {
196 /** The endpoint to be added */
197 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
198 } AddEndpoint;
199 /** Remove endpoint event. */
200 struct
201 {
202 /** The endpoint to be removed */
203 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
204 } RemoveEndpoint;
205 /** Close endpoint event. */
206 struct
207 {
208 /** The endpoint to be closed */
209 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
210 } CloseEndpoint;
211 } BlockingEventData;
212} PDMACEPFILEMGR;
213/** Pointer to a async I/O manager state. */
214typedef PDMACEPFILEMGR *PPDMACEPFILEMGR;
215/** Pointer to a async I/O manager state pointer. */
216typedef PPDMACEPFILEMGR *PPPDMACEPFILEMGR;
217
218/**
219 * A file access range lock.
220 */
221typedef struct PDMACFILERANGELOCK
222{
223 /** AVL node in the locked range tree of the endpoint. */
224 AVLRFOFFNODECORE Core;
225 /** How many tasks have locked this range. */
226 uint32_t cRefs;
227 /** Flag whether this is a read or write lock. */
228 bool fReadLock;
229 /** List of tasks which are waiting that the range gets unlocked. */
230 PPDMACTASKFILE pWaitingTasksHead;
231 /** List of tasks which are waiting that the range gets unlocked. */
232 PPDMACTASKFILE pWaitingTasksTail;
233} PDMACFILERANGELOCK, *PPDMACFILERANGELOCK;
234
235/**
236 * Backend type for the endpoint.
237 */
238typedef enum PDMACFILEEPBACKEND
239{
240 /** Non buffered. */
241 PDMACFILEEPBACKEND_NON_BUFFERED = 0,
242 /** Buffered (i.e host cache enabled) */
243 PDMACFILEEPBACKEND_BUFFERED,
244 /** 32bit hack */
245 PDMACFILEEPBACKEND_32BIT_HACK = 0x7fffffff
246} PDMACFILEEPBACKEND;
247/** Pointer to a backend type. */
248typedef PDMACFILEEPBACKEND *PPDMACFILEEPBACKEND;
249
250/**
251 * Global data for the file endpoint class.
252 */
253typedef struct PDMASYNCCOMPLETIONEPCLASSFILE
254{
255 /** Common data. */
256 PDMASYNCCOMPLETIONEPCLASS Core;
257 /** Override I/O manager type - set to SIMPLE after failure. */
258 PDMACEPFILEMGRTYPE enmMgrTypeOverride;
259 /** Default backend type for the endpoint. */
260 PDMACFILEEPBACKEND enmEpBackendDefault;
261 RTCRITSECT CritSect;
262 /** Pointer to the head of the async I/O managers. */
263 R3PTRTYPE(PPDMACEPFILEMGR) pAioMgrHead;
264 /** Number of async I/O managers currently running. */
265 unsigned cAioMgrs;
266 /** Maximum number of segments to cache per endpoint */
267 unsigned cTasksCacheMax;
268 /** Maximum number of simultaneous outstandingrequests. */
269 uint32_t cReqsOutstandingMax;
270 /** Bitmask for checking the alignment of a buffer. */
271 RTR3UINTPTR uBitmaskAlignment;
272 /** Flag whether the out of resources warning was printed already. */
273 bool fOutOfResourcesWarningPrinted;
274} PDMASYNCCOMPLETIONEPCLASSFILE;
275/** Pointer to the endpoint class data. */
276typedef PDMASYNCCOMPLETIONEPCLASSFILE *PPDMASYNCCOMPLETIONEPCLASSFILE;
277
278typedef enum PDMACEPFILEBLOCKINGEVENT
279{
280 /** The invalid event type */
281 PDMACEPFILEBLOCKINGEVENT_INVALID = 0,
282 /** A task is about to be canceled */
283 PDMACEPFILEBLOCKINGEVENT_CANCEL,
284 /** Usual 32bit hack */
285 PDMACEPFILEBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
286} PDMACEPFILEBLOCKINGEVENT;
287
288/**
289 * States of the endpoint.
290 */
291typedef enum PDMASYNCCOMPLETIONENDPOINTFILESTATE
292{
293 /** Invalid state. */
294 PDMASYNCCOMPLETIONENDPOINTFILESTATE_INVALID = 0,
295 /** Normal running state accepting new requests
296 * and processing them.
297 */
298 PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE,
299 /** The endpoint is about to be closed - not accepting new tasks for endpoints but waiting for
300 * remaining ones to finish.
301 */
302 PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING,
303 /** Removing from current I/O manager state - not processing new tasks for endpoints but waiting
304 * for remaining ones to finish.
305 */
306 PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING,
307 /** The current endpoint will be migrated to another I/O manager. */
308 PDMASYNCCOMPLETIONENDPOINTFILESTATE_MIGRATING,
309 /** 32bit hack */
310 PDMASYNCCOMPLETIONENDPOINTFILESTATE_32BIT_HACK = 0x7fffffff
311} PDMASYNCCOMPLETIONENDPOINTFILESTATE;
312
313/**
314 * Data for the file endpoint.
315 */
316typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
317{
318 /** Common data. */
319 PDMASYNCCOMPLETIONENDPOINT Core;
320 /** Current state of the endpoint. */
321 PDMASYNCCOMPLETIONENDPOINTFILESTATE enmState;
322 /** The backend to use for this endpoint. */
323 PDMACFILEEPBACKEND enmBackendType;
324 /** async I/O manager this endpoint is assigned to. */
325 R3PTRTYPE(volatile PPDMACEPFILEMGR) pAioMgr;
326 /** Flags for opening the file. */
327 unsigned fFlags;
328 /** File handle. */
329 RTFILE File;
330 /**
331 * Real size of the file. Only updated if
332 * data is appended.
333 */
334 volatile uint64_t cbFile;
335 /** List of new tasks. */
336 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksNewHead;
337
338 /** Head of the small cache for allocated task segments for exclusive
339 * use by this endpoint. */
340 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeHead;
341 /** Tail of the small cache for allocated task segments for exclusive
342 * use by this endpoint. */
343 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeTail;
344 /** Number of elements in the cache. */
345 volatile uint32_t cTasksCached;
346
347 /** Flag whether a flush request is currently active */
348 PPDMACTASKFILE pFlushReq;
349
350#ifdef VBOX_WITH_STATISTICS
351 /** Time spend in a read. */
352 STAMPROFILEADV StatRead;
353 /** Time spend in a write. */
354 STAMPROFILEADV StatWrite;
355#endif
356
357 /** Event semaphore for blocking external events.
358 * The caller waits on it until the async I/O manager
359 * finished processing the event. */
360 RTSEMEVENT EventSemBlock;
361 /** Flag whether caching is enabled for this file. */
362 bool fCaching;
363 /** Flag whether the file was opened readonly. */
364 bool fReadonly;
365 /** Flag whether the host supports the async flush API. */
366 bool fAsyncFlushSupported;
367#ifdef VBOX_WITH_DEBUGGER
368 /** Status code to inject for the next complete read. */
369 volatile int rcReqRead;
370 /** Status code to inject for the next complete write. */
371 volatile int rcReqWrite;
372#endif
373#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
374 /** Request delay. */
375 volatile uint32_t msDelay;
376 /** The current task which gets delayed. */
377 PPDMASYNCCOMPLETIONTASKFILE pReqDelayed;
378 /** Timestamp when the delay expires. */
379 uint64_t tsDelayEnd;
380#endif
381 /** Flag whether a blocking event is pending and needs
382 * processing by the I/O manager. */
383 bool fBlockingEventPending;
384 /** Blocking event type */
385 PDMACEPFILEBLOCKINGEVENT enmBlockingEvent;
386
387 /** Additional data needed for the event types. */
388 union
389 {
390 /** Cancelation event. */
391 struct
392 {
393 /** The task to cancel. */
394 PPDMACTASKFILE pTask;
395 } Cancel;
396 } BlockingEventData;
397 /** Data for exclusive use by the assigned async I/O manager. */
398 struct
399 {
400 /** Pointer to the next endpoint assigned to the manager. */
401 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointNext;
402 /** Pointer to the previous endpoint assigned to the manager. */
403 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointPrev;
404 /** List of pending requests (not submitted due to usage restrictions
405 * or a pending flush request) */
406 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingHead;
407 /** Tail of pending requests. */
408 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingTail;
409 /** Tree of currently locked ranges.
410 * If a write task is enqueued the range gets locked and any other
411 * task writing to that range has to wait until the task completes.
412 */
413 PAVLRFOFFTREE pTreeRangesLocked;
414 /** Number of requests currently being processed for this endpoint
415 * (excluded flush requests). */
416 unsigned cRequestsActive;
417 /** Number of requests processed during the last second. */
418 unsigned cReqsPerSec;
419 /** Current number of processed requests for the current update period. */
420 unsigned cReqsProcessed;
421 /** Flag whether the endpoint is about to be moved to another manager. */
422 bool fMoving;
423 /** Destination I/O manager. */
424 PPDMACEPFILEMGR pAioMgrDst;
425 } AioMgr;
426} PDMASYNCCOMPLETIONENDPOINTFILE;
427/** Pointer to the endpoint class data. */
428typedef PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
429#ifdef VBOX_WITH_STATISTICS
430AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINTFILE, StatRead, sizeof(uint64_t));
431#endif
432
433/** Request completion function */
434typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc);
435/** Pointer to a request completion function. */
436typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
437
438/**
439 * Transfer type.
440 */
441typedef enum PDMACTASKFILETRANSFER
442{
443 /** Invalid. */
444 PDMACTASKFILETRANSFER_INVALID = 0,
445 /** Read transfer. */
446 PDMACTASKFILETRANSFER_READ,
447 /** Write transfer. */
448 PDMACTASKFILETRANSFER_WRITE,
449 /** Flush transfer. */
450 PDMACTASKFILETRANSFER_FLUSH
451} PDMACTASKFILETRANSFER;
452
453/**
454 * Data of a request.
455 */
456typedef struct PDMACTASKFILE
457{
458 /** Pointer to the range lock we are waiting for */
459 PPDMACFILERANGELOCK pRangeLock;
460 /** Next task in the list. (Depending on the state) */
461 struct PDMACTASKFILE *pNext;
462 /** Endpoint */
463 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
464 /** Transfer type. */
465 PDMACTASKFILETRANSFER enmTransferType;
466 /** Start offset */
467 RTFOFF Off;
468 /** Data segment. */
469 RTSGSEG DataSeg;
470 /** When non-zero the segment uses a bounce buffer because the provided buffer
471 * doesn't meet host requirements. */
472 size_t cbBounceBuffer;
473 /** Pointer to the used bounce buffer if any. */
474 void *pvBounceBuffer;
475 /** Start offset in the bounce buffer to copy from. */
476 uint32_t offBounceBuffer;
477 /** Flag whether this is a prefetch request. */
478 bool fPrefetch;
479 /** Already prepared native I/O request.
480 * Used if the request is prepared already but
481 * was not queued because the host has not enough
482 * resources. */
483 RTFILEAIOREQ hReq;
484 /** Completion function to call on completion. */
485 PFNPDMACTASKCOMPLETED pfnCompleted;
486 /** User data */
487 void *pvUser;
488} PDMACTASKFILE;
489
490/**
491 * Per task data.
492 */
493typedef struct PDMASYNCCOMPLETIONTASKFILE
494{
495 /** Common data. */
496 PDMASYNCCOMPLETIONTASK Core;
497 /** Number of bytes to transfer until this task completes. */
498 volatile int32_t cbTransferLeft;
499 /** Flag whether the task completed. */
500 volatile bool fCompleted;
501 /** Return code. */
502 volatile int rc;
503} PDMASYNCCOMPLETIONTASKFILE;
504
505int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser);
506int pdmacFileAioMgrNormal(RTTHREAD ThreadSelf, void *pvUser);
507
508int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr);
509void pdmacFileAioMgrNormalDestroy(PPDMACEPFILEMGR pAioMgr);
510
511int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr, PDMACEPFILEMGRTYPE enmMgrType);
512
513int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
514
515PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
516PPDMACTASKFILE pdmacFileTaskAlloc(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
517void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
518 PPDMACTASKFILE pTask);
519
520int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
521
522void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
523
524int pdmacFileCacheInit(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile, PCFGMNODE pCfgNode);
525void pdmacFileCacheDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
526int pdmacFileEpCacheInit(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
527void pdmacFileEpCacheDestroy(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
528
529int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
530 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
531 size_t cbRead);
532int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
533 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
534 size_t cbWrite);
535int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
536
537RT_C_DECLS_END
538
539#endif
540
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