1
/* $Id: PDMAsyncCompletionFileInternal.h $ */
3
* PDM Async I/O - Transport data asynchronous in R3 using EMT.
7
* Copyright (C) 2006-2008 Oracle Corporation
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.
18
#ifndef ___PDMAsyncCompletionFileInternal_h
19
#define ___PDMAsyncCompletionFileInternal_h
21
#include <VBox/cfgm.h>
22
#include <VBox/stam.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>
30
#include <iprt/list.h>
31
#include <iprt/spinlock.h>
32
#include <iprt/memcache.h>
34
#include "PDMAsyncCompletionInternal.h"
36
/** @todo: Revise the caching of tasks. We have currently four caches:
37
* Per endpoint task cache
39
* Per endpoint task segment cache
40
* Per class task segment cache
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.
49
* A few forward declerations.
51
typedef struct PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
52
/** Pointer to a request segment. */
53
typedef struct PDMACTASKFILE *PPDMACTASKFILE;
54
/** Pointer to the endpoint class data. */
55
typedef struct PDMASYNCCOMPLETIONTASKFILE *PPDMASYNCCOMPLETIONTASKFILE;
56
/** Pointer to a cache LRU list. */
57
typedef struct PDMACFILELRULIST *PPDMACFILELRULIST;
58
/** Pointer to the global cache structure. */
59
typedef struct PDMACFILECACHEGLOBAL *PPDMACFILECACHEGLOBAL;
60
/** Pointer to a task segment. */
61
typedef struct PDMACFILETASKSEG *PPDMACFILETASKSEG;
64
* Blocking event types.
66
typedef enum PDMACEPFILEAIOMGRBLOCKINGEVENT
69
PDMACEPFILEAIOMGRBLOCKINGEVENT_INVALID = 0,
70
/** An endpoint is added to the manager. */
71
PDMACEPFILEAIOMGRBLOCKINGEVENT_ADD_ENDPOINT,
72
/** An endpoint is removed from the manager. */
73
PDMACEPFILEAIOMGRBLOCKINGEVENT_REMOVE_ENDPOINT,
74
/** An endpoint is about to be closed. */
75
PDMACEPFILEAIOMGRBLOCKINGEVENT_CLOSE_ENDPOINT,
76
/** The manager is requested to terminate */
77
PDMACEPFILEAIOMGRBLOCKINGEVENT_SHUTDOWN,
78
/** The manager is requested to suspend */
79
PDMACEPFILEAIOMGRBLOCKINGEVENT_SUSPEND,
80
/** The manager is requested to resume */
81
PDMACEPFILEAIOMGRBLOCKINGEVENT_RESUME,
83
PDMACEPFILEAIOMGRBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
84
} PDMACEPFILEAIOMGRBLOCKINGEVENT;
89
typedef enum PDMACEPFILEMGRTYPE
91
/** Simple aka failsafe */
92
PDMACEPFILEMGRTYPE_SIMPLE = 0,
93
/** Async I/O with host cache enabled. */
94
PDMACEPFILEMGRTYPE_ASYNC,
96
PDMACEPFILEMGRTYPE_32BIT_HACK = 0x7fffffff
98
/** Pointer to a I/O manager type */
99
typedef PDMACEPFILEMGRTYPE *PPDMACEPFILEMGRTYPE;
102
* States of the I/O manager.
104
typedef enum PDMACEPFILEMGRSTATE
106
/** Invalid state. */
107
PDMACEPFILEMGRSTATE_INVALID = 0,
108
/** Normal running state accepting new requests
109
* and processing them.
111
PDMACEPFILEMGRSTATE_RUNNING,
112
/** Fault state - not accepting new tasks for endpoints but waiting for
113
* remaining ones to finish.
115
PDMACEPFILEMGRSTATE_FAULT,
116
/** Suspending state - not accepting new tasks for endpoints but waiting
117
* for remaining ones to finish.
119
PDMACEPFILEMGRSTATE_SUSPENDING,
120
/** Shutdown state - not accepting new tasks for endpoints but waiting
121
* for remaining ones to finish.
123
PDMACEPFILEMGRSTATE_SHUTDOWN,
124
/** The I/O manager waits for all active requests to complete and doesn't queue
125
* new ones because it needs to grow to handle more requests.
127
PDMACEPFILEMGRSTATE_GROWING,
129
PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff
130
} PDMACEPFILEMGRSTATE;
133
* State of a async I/O manager.
135
typedef struct PDMACEPFILEMGR
137
/** Next Aio manager in the list. */
138
R3PTRTYPE(struct PDMACEPFILEMGR *) pNext;
139
/** Previous Aio manager in the list. */
140
R3PTRTYPE(struct PDMACEPFILEMGR *) pPrev;
142
PDMACEPFILEMGRTYPE enmMgrType;
143
/** Current state of the manager. */
144
PDMACEPFILEMGRSTATE enmState;
145
/** Event semaphore the manager sleeps on when waiting for new requests. */
147
/** Flag whether the thread waits in the event semaphore. */
148
volatile bool fWaitingEventSem;
151
/** The async I/O context for this manager. */
152
RTFILEAIOCTX hAioCtx;
153
/** Flag whether the I/O manager was woken up. */
154
volatile bool fWokenUp;
155
/** List of endpoints assigned to this manager. */
156
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointsHead;
157
/** Number of endpoints assigned to the manager. */
159
/** Number of requests active currently. */
160
unsigned cRequestsActive;
161
/** Number of maximum requests active. */
162
uint32_t cRequestsActiveMax;
163
/** Pointer to an array of free async I/O request handles. */
164
RTFILEAIOREQ *pahReqsFree;
165
/** Index of the next free entry in the cache. */
167
/** Size of the array. */
168
unsigned cReqEntries;
169
/** Flag whether at least one endpoint reached its bandwidth limit. */
170
bool fBwLimitReached;
171
/** Memory cache for file range locks. */
172
RTMEMCACHE hMemCacheRangeLocks;
173
/** Critical section protecting the blocking event handling. */
174
RTCRITSECT CritSectBlockingEvent;
175
/** Event sempahore for blocking external events.
176
* The caller waits on it until the async I/O manager
177
* finished processing the event. */
178
RTSEMEVENT EventSemBlock;
179
/** Flag whether a blocking event is pending and needs
180
* processing by the I/O manager. */
181
volatile bool fBlockingEventPending;
182
/** Blocking event type */
183
volatile PDMACEPFILEAIOMGRBLOCKINGEVENT enmBlockingEvent;
184
/** Event type data */
187
/** Add endpoint event. */
190
/** The endpoint to be added */
191
volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
193
/** Remove endpoint event. */
196
/** The endpoint to be removed */
197
volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
199
/** Close endpoint event. */
202
/** The endpoint to be closed */
203
volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
207
/** Pointer to a async I/O manager state. */
208
typedef PDMACEPFILEMGR *PPDMACEPFILEMGR;
209
/** Pointer to a async I/O manager state pointer. */
210
typedef PPDMACEPFILEMGR *PPPDMACEPFILEMGR;
213
* Bandwidth control manager instance data
215
typedef struct PDMACFILEBWMGR
217
/** Maximum number of bytes the VM is allowed to transfer (Max is 4GB/s) */
218
uint32_t cbVMTransferPerSecMax;
219
/** Number of bytes we start with */
220
uint32_t cbVMTransferPerSecStart;
221
/** Step after each update */
222
uint32_t cbVMTransferPerSecStep;
223
/** Number of bytes we are allowed to transfer till the next update.
224
* Resetted by the refresh timer. */
225
volatile uint32_t cbVMTransferAllowed;
226
/** Timestamp of the last update */
227
volatile uint64_t tsUpdatedLast;
228
/** Reference counter - How many endpoints are associated with this manager. */
231
/** Pointer to a bandwidth control manager */
232
typedef PDMACFILEBWMGR *PPDMACFILEBWMGR;
233
/** Pointer to a bandwidth control manager pointer */
234
typedef PPDMACFILEBWMGR *PPPDMACFILEBWMGR;
237
* A file access range lock.
239
typedef struct PDMACFILERANGELOCK
241
/** AVL node in the locked range tree of the endpoint. */
242
AVLRFOFFNODECORE Core;
243
/** How many tasks have locked this range. */
245
/** Flag whether this is a read or write lock. */
247
/** List of tasks which are waiting that the range gets unlocked. */
248
PPDMACTASKFILE pWaitingTasksHead;
249
/** List of tasks which are waiting that the range gets unlocked. */
250
PPDMACTASKFILE pWaitingTasksTail;
251
} PDMACFILERANGELOCK, *PPDMACFILERANGELOCK;
254
* Data for one request segment waiting for cache entry.
256
typedef struct PDMACFILETASKSEG
258
/** Next task segment in the list. */
259
struct PDMACFILETASKSEG *pNext;
260
/** Task this segment is for. */
261
PPDMASYNCCOMPLETIONTASKFILE pTask;
262
/** Offset into the cache entry buffer to start reading from. */
264
/** Number of bytes to transfer. */
266
/** Pointer to the buffer. */
268
/** Flag whether this entry writes data to the cache. */
275
typedef struct PDMACFILECACHEENTRY
277
/** The AVL entry data. */
278
AVLRFOFFNODECORE Core;
279
/** Pointer to the previous element. Used in one of the LRU lists.*/
280
struct PDMACFILECACHEENTRY *pPrev;
281
/** Pointer to the next element. Used in one of the LRU lists.*/
282
struct PDMACFILECACHEENTRY *pNext;
283
/** Pointer to the list the entry is in. */
284
PPDMACFILELRULIST pList;
285
/** Pointer to the global cache structure. */
286
PPDMACFILECACHEGLOBAL pCache;
287
/** Endpoint the entry belongs to. */
288
PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
289
/** Flags for this entry. Combinations of PDMACFILECACHE_* #defines */
290
volatile uint32_t fFlags;
291
/** Reference counter. Prevents eviction of the entry if > 0. */
292
volatile uint32_t cRefs;
293
/** Size of the entry. */
295
/** Pointer to the memory containing the data. */
297
/** Head of list of tasks waiting for this one to finish. */
298
PPDMACFILETASKSEG pWaitingHead;
299
/** Tail of list of tasks waiting for this one to finish. */
300
PPDMACFILETASKSEG pWaitingTail;
301
/** Node for dirty but not yet committed entries list per endpoint. */
302
RTLISTNODE NodeNotCommitted;
303
} PDMACFILECACHEENTRY, *PPDMACFILECACHEENTRY;
304
/** I/O is still in progress for this entry. This entry is not evictable. */
305
#define PDMACFILECACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
306
/** Entry is locked and thus not evictable. */
307
#define PDMACFILECACHE_ENTRY_LOCKED RT_BIT(1)
308
/** Entry is dirty */
309
#define PDMACFILECACHE_ENTRY_IS_DIRTY RT_BIT(2)
310
/** Entry is not evictable. */
311
#define PDMACFILECACHE_NOT_EVICTABLE (PDMACFILECACHE_ENTRY_LOCKED | PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)
316
typedef struct PDMACFILELRULIST
318
/** Head of the list. */
319
PPDMACFILECACHEENTRY pHead;
320
/** Tail of the list. */
321
PPDMACFILECACHEENTRY pTail;
322
/** Number of bytes cached in the list. */
329
typedef struct PDMACFILECACHEGLOBAL
331
/** Maximum size of the cache in bytes. */
333
/** Current size of the cache in bytes. */
335
/** Critical section protecting the cache. */
337
/** Maximum number of bytes cached. */
338
uint32_t cbRecentlyUsedInMax;
339
/** Maximum number of bytes in the paged out list .*/
340
uint32_t cbRecentlyUsedOutMax;
341
/** Recently used cache entries list */
342
PDMACFILELRULIST LruRecentlyUsedIn;
343
/** Scorecard cache entry list. */
344
PDMACFILELRULIST LruRecentlyUsedOut;
345
/** List of frequently used cache entries */
346
PDMACFILELRULIST LruFrequentlyUsed;
347
/** Commit timeout in milli seconds */
348
uint32_t u32CommitTimeoutMs;
349
/** Number of dirty bytes needed to start a commit of the data to the disk. */
350
uint32_t cbCommitDirtyThreshold;
351
/** Current number of dirty bytes in the cache. */
352
volatile uint32_t cbDirty;
353
/** Flag whether a commit is currently in progress. */
354
volatile bool fCommitInProgress;
355
/** Commit interval timer */
356
PTMTIMERR3 pTimerCommit;
357
/** Number of endpoints using the cache. */
359
/** List of all endpoints using this cache. */
360
RTLISTNODE ListEndpoints;
361
#ifdef VBOX_WITH_STATISTICS
363
uint32_t u32Alignment;
366
/** Partial hit counter. */
367
STAMCOUNTER cPartialHits;
370
/** Bytes read from cache. */
371
STAMCOUNTER StatRead;
372
/** Bytes written to the cache. */
373
STAMCOUNTER StatWritten;
374
/** Time spend to get an entry in the AVL tree. */
375
STAMPROFILEADV StatTreeGet;
376
/** Time spend to insert an entry in the AVL tree. */
377
STAMPROFILEADV StatTreeInsert;
378
/** Time spend to remove an entry in the AVL tree. */
379
STAMPROFILEADV StatTreeRemove;
380
/** Number of times a buffer could be reused. */
381
STAMCOUNTER StatBuffersReused;
383
} PDMACFILECACHEGLOBAL;
384
#ifdef VBOX_WITH_STATISTICS
385
AssertCompileMemberAlignment(PDMACFILECACHEGLOBAL, cHits, sizeof(uint64_t));
389
* Per endpoint cache data.
391
typedef struct PDMACFILEENDPOINTCACHE
393
/** AVL tree managing cache entries. */
395
/** R/W semaphore protecting cached entries for this endpoint. */
396
RTSEMRW SemRWEntries;
397
/** Pointer to the gobal cache data */
398
PPDMACFILECACHEGLOBAL pCache;
399
/** Lock protecting the dirty entries list. */
401
/** List of dirty but not committed entries for this endpoint. */
402
RTLISTNODE ListDirtyNotCommitted;
403
/** Node of the cache endpoint list. */
404
RTLISTNODE NodeCacheEndpoint;
405
#ifdef VBOX_WITH_STATISTICS
406
/** Number of times a write was deferred because the cache entry was still in progress */
407
STAMCOUNTER StatWriteDeferred;
409
} PDMACFILEENDPOINTCACHE, *PPDMACFILEENDPOINTCACHE;
410
#ifdef VBOX_WITH_STATISTICS
411
AssertCompileMemberAlignment(PDMACFILEENDPOINTCACHE, StatWriteDeferred, sizeof(uint64_t));
415
* Backend type for the endpoint.
417
typedef enum PDMACFILEEPBACKEND
420
PDMACFILEEPBACKEND_NON_BUFFERED = 0,
421
/** Buffered (i.e host cache enabled) */
422
PDMACFILEEPBACKEND_BUFFERED,
424
PDMACFILEEPBACKEND_32BIT_HACK = 0x7fffffff
425
} PDMACFILEEPBACKEND;
426
/** Pointer to a backend type. */
427
typedef PDMACFILEEPBACKEND *PPDMACFILEEPBACKEND;
430
* Global data for the file endpoint class.
432
typedef struct PDMASYNCCOMPLETIONEPCLASSFILE
435
PDMASYNCCOMPLETIONEPCLASS Core;
436
/** Override I/O manager type - set to SIMPLE after failure. */
437
PDMACEPFILEMGRTYPE enmMgrTypeOverride;
438
/** Default backend type for the endpoint. */
439
PDMACFILEEPBACKEND enmEpBackendDefault;
440
/** Flag whether the file data cache is enabled. */
442
/** Critical section protecting the list of async I/O managers. */
444
/** Pointer to the head of the async I/O managers. */
445
R3PTRTYPE(PPDMACEPFILEMGR) pAioMgrHead;
446
/** Number of async I/O managers currently running. */
448
/** Maximum number of segments to cache per endpoint */
449
unsigned cTasksCacheMax;
450
/** Maximum number of simultaneous outstandingrequests. */
451
uint32_t cReqsOutstandingMax;
452
/** Bitmask for checking the alignment of a buffer. */
453
RTR3UINTPTR uBitmaskAlignment;
454
#ifdef VBOX_WITH_STATISTICS
455
uint32_t u32Alignment;
457
/** Global cache data. */
458
PDMACFILECACHEGLOBAL Cache;
459
/** Flag whether the out of resources warning was printed already. */
460
bool fOutOfResourcesWarningPrinted;
461
/** The global bandwidth control manager */
462
PPDMACFILEBWMGR pBwMgr;
463
} PDMASYNCCOMPLETIONEPCLASSFILE;
464
/** Pointer to the endpoint class data. */
465
typedef PDMASYNCCOMPLETIONEPCLASSFILE *PPDMASYNCCOMPLETIONEPCLASSFILE;
466
#ifdef VBOX_WITH_STATISTICS
467
AssertCompileMemberAlignment(PDMASYNCCOMPLETIONEPCLASSFILE, Cache, sizeof(uint64_t));
470
typedef enum PDMACEPFILEBLOCKINGEVENT
472
/** The invalid event type */
473
PDMACEPFILEBLOCKINGEVENT_INVALID = 0,
474
/** A task is about to be canceled */
475
PDMACEPFILEBLOCKINGEVENT_CANCEL,
476
/** Usual 32bit hack */
477
PDMACEPFILEBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
478
} PDMACEPFILEBLOCKINGEVENT;
481
* States of the endpoint.
483
typedef enum PDMASYNCCOMPLETIONENDPOINTFILESTATE
485
/** Invalid state. */
486
PDMASYNCCOMPLETIONENDPOINTFILESTATE_INVALID = 0,
487
/** Normal running state accepting new requests
488
* and processing them.
490
PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE,
491
/** The endpoint is about to be closed - not accepting new tasks for endpoints but waiting for
492
* remaining ones to finish.
494
PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING,
495
/** Removing from current I/O manager state - not processing new tasks for endpoints but waiting
496
* for remaining ones to finish.
498
PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING,
499
/** The current endpoint will be migrated to another I/O manager. */
500
PDMASYNCCOMPLETIONENDPOINTFILESTATE_MIGRATING,
502
PDMASYNCCOMPLETIONENDPOINTFILESTATE_32BIT_HACK = 0x7fffffff
503
} PDMASYNCCOMPLETIONENDPOINTFILESTATE;
506
* Data for the file endpoint.
508
typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
511
PDMASYNCCOMPLETIONENDPOINT Core;
512
/** Current state of the endpoint. */
513
PDMASYNCCOMPLETIONENDPOINTFILESTATE enmState;
514
/** The backend to use for this endpoint. */
515
PDMACFILEEPBACKEND enmBackendType;
516
/** async I/O manager this endpoint is assigned to. */
517
R3PTRTYPE(volatile PPDMACEPFILEMGR) pAioMgr;
518
/** Flags for opening the file. */
522
/** Size of the endpoint.
523
* Updated while data is appended even if it is
524
* only in the cache yet and not written to the file.
526
volatile uint64_t cbEndpoint;
528
* Real size of the file. Only updated if
531
volatile uint64_t cbFile;
532
/** List of new tasks. */
533
R3PTRTYPE(volatile PPDMACTASKFILE) pTasksNewHead;
535
/** Head of the small cache for allocated task segments for exclusive
536
* use by this endpoint. */
537
R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeHead;
538
/** Tail of the small cache for allocated task segments for exclusive
539
* use by this endpoint. */
540
R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeTail;
541
/** Number of elements in the cache. */
542
volatile uint32_t cTasksCached;
544
#ifdef VBOX_WITH_STATISTICS
545
uint32_t u32Alignment;
547
/** Cache of endpoint data. */
548
PDMACFILEENDPOINTCACHE DataCache;
549
/** Pointer to the associated bandwidth control manager */
550
PPDMACFILEBWMGR pBwMgr;
552
/** Flag whether a flush request is currently active */
553
PPDMACTASKFILE pFlushReq;
555
#ifdef VBOX_WITH_STATISTICS
556
/** Time spend in a read. */
557
STAMPROFILEADV StatRead;
558
/** Time spend in a write. */
559
STAMPROFILEADV StatWrite;
562
/** Event sempahore for blocking external events.
563
* The caller waits on it until the async I/O manager
564
* finished processing the event. */
565
RTSEMEVENT EventSemBlock;
566
/** Flag whether caching is enabled for this file. */
568
/** Flag whether the file was opened readonly. */
570
/** Flag whether the host supports the async flush API. */
571
bool fAsyncFlushSupported;
572
/** Flag whether a blocking event is pending and needs
573
* processing by the I/O manager. */
574
bool fBlockingEventPending;
575
/** Blocking event type */
576
PDMACEPFILEBLOCKINGEVENT enmBlockingEvent;
578
/** Additional data needed for the event types. */
581
/** Cancelation event. */
584
/** The task to cancel. */
585
PPDMACTASKFILE pTask;
588
/** Data for exclusive use by the assigned async I/O manager. */
591
/** Pointer to the next endpoint assigned to the manager. */
592
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointNext;
593
/** Pointer to the previous endpoint assigned to the manager. */
594
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointPrev;
595
/** List of pending requests (not submitted due to usage restrictions
596
* or a pending flush request) */
597
R3PTRTYPE(PPDMACTASKFILE) pReqsPendingHead;
598
/** Tail of pending requests. */
599
R3PTRTYPE(PPDMACTASKFILE) pReqsPendingTail;
600
/** Tree of currently locked ranges.
601
* If a write task is enqueued the range gets locked and any other
602
* task writing to that range has to wait until the task completes.
604
PAVLRFOFFTREE pTreeRangesLocked;
605
/** Number of requests currently being processed for this endpoint
606
* (excluded flush requests). */
607
unsigned cRequestsActive;
608
/** Number of requests processed during the last second. */
609
unsigned cReqsPerSec;
610
/** Current number of processed requests for the current update period. */
611
unsigned cReqsProcessed;
612
/** Flag whether the endpoint is about to be moved to another manager. */
614
/** Destination I/O manager. */
615
PPDMACEPFILEMGR pAioMgrDst;
617
} PDMASYNCCOMPLETIONENDPOINTFILE;
618
/** Pointer to the endpoint class data. */
619
typedef PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
620
#ifdef VBOX_WITH_STATISTICS
621
AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINTFILE, StatRead, sizeof(uint64_t));
622
AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINTFILE, DataCache, sizeof(uint64_t));
625
/** Request completion function */
626
typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc);
627
/** Pointer to a request completion function. */
628
typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
633
typedef enum PDMACTASKFILETRANSFER
636
PDMACTASKFILETRANSFER_INVALID = 0,
637
/** Read transfer. */
638
PDMACTASKFILETRANSFER_READ,
639
/** Write transfer. */
640
PDMACTASKFILETRANSFER_WRITE,
641
/** Flush transfer. */
642
PDMACTASKFILETRANSFER_FLUSH
643
} PDMACTASKFILETRANSFER;
648
typedef struct PDMACTASKFILE
650
/** Pointer to the range lock we are waiting for */
651
PPDMACFILERANGELOCK pRangeLock;
652
/** Next task in the list. (Depending on the state) */
653
struct PDMACTASKFILE *pNext;
655
PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
656
/** Transfer type. */
657
PDMACTASKFILETRANSFER enmTransferType;
662
/** When non-zero the segment uses a bounce buffer because the provided buffer
663
* doesn't meet host requirements. */
664
size_t cbBounceBuffer;
665
/** Pointer to the used bounce buffer if any. */
666
void *pvBounceBuffer;
667
/** Start offset in the bounce buffer to copy from. */
668
uint32_t offBounceBuffer;
669
/** Flag whether this is a prefetch request. */
671
/** Already prepared native I/O request.
672
* Used if the request is prepared already but
673
* was not queued because the host has not enough
676
/** Completion function to call on completion. */
677
PFNPDMACTASKCOMPLETED pfnCompleted;
685
typedef struct PDMASYNCCOMPLETIONTASKFILE
688
PDMASYNCCOMPLETIONTASK Core;
689
/** Number of bytes to transfer until this task completes. */
690
volatile int32_t cbTransferLeft;
691
/** Flag whether the task completed. */
692
volatile bool fCompleted;
695
} PDMASYNCCOMPLETIONTASKFILE;
697
int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser);
698
int pdmacFileAioMgrNormal(RTTHREAD ThreadSelf, void *pvUser);
700
int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr);
701
void pdmacFileAioMgrNormalDestroy(PPDMACEPFILEMGR pAioMgr);
703
int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr, PDMACEPFILEMGRTYPE enmMgrType);
705
int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
707
PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
708
PPDMACTASKFILE pdmacFileTaskAlloc(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
709
void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
710
PPDMACTASKFILE pTask);
712
int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
714
void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
716
bool pdmacFileBwMgrIsTransferAllowed(PPDMACFILEBWMGR pBwMgr, uint32_t cbTransfer);
718
int pdmacFileCacheInit(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile, PCFGMNODE pCfgNode);
719
void pdmacFileCacheDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
720
int pdmacFileEpCacheInit(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
721
void pdmacFileEpCacheDestroy(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
723
int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
724
RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
726
int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
727
RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
729
int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);