VirtualBox

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

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

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.8 KB
Line 
1/* $Id: PDMAsyncCompletionFileInternal.h 33540 2010-10-28 09:27:05Z 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/cfgm.h>
22#include <VBox/stam.h>
23#include <VBox/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
46RT_C_DECLS_BEGIN
47
48/**
49 * A few forward declarations.
50 */
51typedef struct PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
52/** Pointer to a request segment. */
53typedef struct PDMACTASKFILE *PPDMACTASKFILE;
54/** Pointer to the endpoint class data. */
55typedef struct PDMASYNCCOMPLETIONTASKFILE *PPDMASYNCCOMPLETIONTASKFILE;
56/** Pointer to a cache LRU list. */
57typedef struct PDMACFILELRULIST *PPDMACFILELRULIST;
58/** Pointer to the global cache structure. */
59typedef struct PDMACFILECACHEGLOBAL *PPDMACFILECACHEGLOBAL;
60/** Pointer to a task segment. */
61typedef struct PDMACFILETASKSEG *PPDMACFILETASKSEG;
62
63/**
64 * Blocking event types.
65 */
66typedef enum PDMACEPFILEAIOMGRBLOCKINGEVENT
67{
68 /** Invalid tye */
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,
82 /** 32bit hack */
83 PDMACEPFILEAIOMGRBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
84} PDMACEPFILEAIOMGRBLOCKINGEVENT;
85
86/**
87 * I/O manager type.
88 */
89typedef enum PDMACEPFILEMGRTYPE
90{
91 /** Simple aka failsafe */
92 PDMACEPFILEMGRTYPE_SIMPLE = 0,
93 /** Async I/O with host cache enabled. */
94 PDMACEPFILEMGRTYPE_ASYNC,
95 /** 32bit hack */
96 PDMACEPFILEMGRTYPE_32BIT_HACK = 0x7fffffff
97} PDMACEPFILEMGRTYPE;
98/** Pointer to a I/O manager type */
99typedef PDMACEPFILEMGRTYPE *PPDMACEPFILEMGRTYPE;
100
101/**
102 * States of the I/O manager.
103 */
104typedef enum PDMACEPFILEMGRSTATE
105{
106 /** Invalid state. */
107 PDMACEPFILEMGRSTATE_INVALID = 0,
108 /** Normal running state accepting new requests
109 * and processing them.
110 */
111 PDMACEPFILEMGRSTATE_RUNNING,
112 /** Fault state - not accepting new tasks for endpoints but waiting for
113 * remaining ones to finish.
114 */
115 PDMACEPFILEMGRSTATE_FAULT,
116 /** Suspending state - not accepting new tasks for endpoints but waiting
117 * for remaining ones to finish.
118 */
119 PDMACEPFILEMGRSTATE_SUSPENDING,
120 /** Shutdown state - not accepting new tasks for endpoints but waiting
121 * for remaining ones to finish.
122 */
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.
126 */
127 PDMACEPFILEMGRSTATE_GROWING,
128 /** 32bit hack */
129 PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff
130} PDMACEPFILEMGRSTATE;
131
132/**
133 * State of a async I/O manager.
134 */
135typedef struct PDMACEPFILEMGR
136{
137 /** Next Aio manager in the list. */
138 R3PTRTYPE(struct PDMACEPFILEMGR *) pNext;
139 /** Previous Aio manager in the list. */
140 R3PTRTYPE(struct PDMACEPFILEMGR *) pPrev;
141 /** Manager type */
142 PDMACEPFILEMGRTYPE enmMgrType;
143 /** Current state of the manager. */
144 PDMACEPFILEMGRSTATE enmState;
145 /** Event semaphore the manager sleeps on when waiting for new requests. */
146 RTSEMEVENT EventSem;
147 /** Flag whether the thread waits in the event semaphore. */
148 volatile bool fWaitingEventSem;
149 /** Thread data */
150 RTTHREAD Thread;
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. */
158 unsigned cEndpoints;
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. */
166 uint32_t iFreeEntry;
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 semaphore 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 */
185 union
186 {
187 /** Add endpoint event. */
188 struct
189 {
190 /** The endpoint to be added */
191 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
192 } AddEndpoint;
193 /** Remove endpoint event. */
194 struct
195 {
196 /** The endpoint to be removed */
197 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
198 } RemoveEndpoint;
199 /** Close endpoint event. */
200 struct
201 {
202 /** The endpoint to be closed */
203 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
204 } CloseEndpoint;
205 } BlockingEventData;
206} PDMACEPFILEMGR;
207/** Pointer to a async I/O manager state. */
208typedef PDMACEPFILEMGR *PPDMACEPFILEMGR;
209/** Pointer to a async I/O manager state pointer. */
210typedef PPDMACEPFILEMGR *PPPDMACEPFILEMGR;
211
212/**
213 * A file access range lock.
214 */
215typedef struct PDMACFILERANGELOCK
216{
217 /** AVL node in the locked range tree of the endpoint. */
218 AVLRFOFFNODECORE Core;
219 /** How many tasks have locked this range. */
220 uint32_t cRefs;
221 /** Flag whether this is a read or write lock. */
222 bool fReadLock;
223 /** List of tasks which are waiting that the range gets unlocked. */
224 PPDMACTASKFILE pWaitingTasksHead;
225 /** List of tasks which are waiting that the range gets unlocked. */
226 PPDMACTASKFILE pWaitingTasksTail;
227} PDMACFILERANGELOCK, *PPDMACFILERANGELOCK;
228
229/**
230 * Data for one request segment waiting for cache entry.
231 */
232typedef struct PDMACFILETASKSEG
233{
234 /** Next task segment in the list. */
235 struct PDMACFILETASKSEG *pNext;
236 /** Task this segment is for. */
237 PPDMASYNCCOMPLETIONTASKFILE pTask;
238 /** Offset into the cache entry buffer to start reading from. */
239 uint32_t uBufOffset;
240 /** Number of bytes to transfer. */
241 size_t cbTransfer;
242 /** Pointer to the buffer. */
243 void *pvBuf;
244 /** Flag whether this entry writes data to the cache. */
245 bool fWrite;
246} PDMACFILETASKSEG;
247
248/**
249 * A cache entry
250 */
251typedef struct PDMACFILECACHEENTRY
252{
253 /** The AVL entry data. */
254 AVLRFOFFNODECORE Core;
255 /** Pointer to the previous element. Used in one of the LRU lists.*/
256 struct PDMACFILECACHEENTRY *pPrev;
257 /** Pointer to the next element. Used in one of the LRU lists.*/
258 struct PDMACFILECACHEENTRY *pNext;
259 /** Pointer to the list the entry is in. */
260 PPDMACFILELRULIST pList;
261 /** Pointer to the global cache structure. */
262 PPDMACFILECACHEGLOBAL pCache;
263 /** Endpoint the entry belongs to. */
264 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
265 /** Flags for this entry. Combinations of PDMACFILECACHE_* #defines */
266 volatile uint32_t fFlags;
267 /** Reference counter. Prevents eviction of the entry if > 0. */
268 volatile uint32_t cRefs;
269 /** Size of the entry. */
270 size_t cbData;
271 /** Pointer to the memory containing the data. */
272 uint8_t *pbData;
273 /** Head of list of tasks waiting for this one to finish. */
274 PPDMACFILETASKSEG pWaitingHead;
275 /** Tail of list of tasks waiting for this one to finish. */
276 PPDMACFILETASKSEG pWaitingTail;
277 /** Node for dirty but not yet committed entries list per endpoint. */
278 RTLISTNODE NodeNotCommitted;
279} PDMACFILECACHEENTRY, *PPDMACFILECACHEENTRY;
280/** I/O is still in progress for this entry. This entry is not evictable. */
281#define PDMACFILECACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
282/** Entry is locked and thus not evictable. */
283#define PDMACFILECACHE_ENTRY_LOCKED RT_BIT(1)
284/** Entry is dirty */
285#define PDMACFILECACHE_ENTRY_IS_DIRTY RT_BIT(2)
286/** Entry is not evictable. */
287#define PDMACFILECACHE_NOT_EVICTABLE (PDMACFILECACHE_ENTRY_LOCKED | PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)
288
289/**
290 * LRU list data
291 */
292typedef struct PDMACFILELRULIST
293{
294 /** Head of the list. */
295 PPDMACFILECACHEENTRY pHead;
296 /** Tail of the list. */
297 PPDMACFILECACHEENTRY pTail;
298 /** Number of bytes cached in the list. */
299 uint32_t cbCached;
300} PDMACFILELRULIST;
301
302/**
303 * Global cache data.
304 */
305typedef struct PDMACFILECACHEGLOBAL
306{
307 /** Maximum size of the cache in bytes. */
308 uint32_t cbMax;
309 /** Current size of the cache in bytes. */
310 uint32_t cbCached;
311 /** Critical section protecting the cache. */
312 RTCRITSECT CritSect;
313 /** Maximum number of bytes cached. */
314 uint32_t cbRecentlyUsedInMax;
315 /** Maximum number of bytes in the paged out list .*/
316 uint32_t cbRecentlyUsedOutMax;
317 /** Recently used cache entries list */
318 PDMACFILELRULIST LruRecentlyUsedIn;
319 /** Scorecard cache entry list. */
320 PDMACFILELRULIST LruRecentlyUsedOut;
321 /** List of frequently used cache entries */
322 PDMACFILELRULIST LruFrequentlyUsed;
323 /** Commit timeout in milli seconds */
324 uint32_t u32CommitTimeoutMs;
325 /** Number of dirty bytes needed to start a commit of the data to the disk. */
326 uint32_t cbCommitDirtyThreshold;
327 /** Current number of dirty bytes in the cache. */
328 volatile uint32_t cbDirty;
329 /** Flag whether a commit is currently in progress. */
330 volatile bool fCommitInProgress;
331 /** Commit interval timer */
332 PTMTIMERR3 pTimerCommit;
333 /** Number of endpoints using the cache. */
334 uint32_t cRefs;
335 /** List of all endpoints using this cache. */
336 RTLISTNODE ListEndpoints;
337#ifdef VBOX_WITH_STATISTICS
338 /** Alignment */
339 uint32_t u32Alignment;
340 /** Hit counter. */
341 STAMCOUNTER cHits;
342 /** Partial hit counter. */
343 STAMCOUNTER cPartialHits;
344 /** Miss counter. */
345 STAMCOUNTER cMisses;
346 /** Bytes read from cache. */
347 STAMCOUNTER StatRead;
348 /** Bytes written to the cache. */
349 STAMCOUNTER StatWritten;
350 /** Time spend to get an entry in the AVL tree. */
351 STAMPROFILEADV StatTreeGet;
352 /** Time spend to insert an entry in the AVL tree. */
353 STAMPROFILEADV StatTreeInsert;
354 /** Time spend to remove an entry in the AVL tree. */
355 STAMPROFILEADV StatTreeRemove;
356 /** Number of times a buffer could be reused. */
357 STAMCOUNTER StatBuffersReused;
358#endif
359} PDMACFILECACHEGLOBAL;
360#ifdef VBOX_WITH_STATISTICS
361AssertCompileMemberAlignment(PDMACFILECACHEGLOBAL, cHits, sizeof(uint64_t));
362#endif
363
364/**
365 * Per endpoint cache data.
366 */
367typedef struct PDMACFILEENDPOINTCACHE
368{
369 /** AVL tree managing cache entries. */
370 PAVLRFOFFTREE pTree;
371 /** R/W semaphore protecting cached entries for this endpoint. */
372 RTSEMRW SemRWEntries;
373 /** Pointer to the gobal cache data */
374 PPDMACFILECACHEGLOBAL pCache;
375 /** Lock protecting the dirty entries list. */
376 RTSPINLOCK LockList;
377 /** List of dirty but not committed entries for this endpoint. */
378 RTLISTNODE ListDirtyNotCommitted;
379 /** Node of the cache endpoint list. */
380 RTLISTNODE NodeCacheEndpoint;
381#ifdef VBOX_WITH_STATISTICS
382 /** Number of times a write was deferred because the cache entry was still in progress */
383 STAMCOUNTER StatWriteDeferred;
384#endif
385} PDMACFILEENDPOINTCACHE, *PPDMACFILEENDPOINTCACHE;
386#ifdef VBOX_WITH_STATISTICS
387AssertCompileMemberAlignment(PDMACFILEENDPOINTCACHE, StatWriteDeferred, sizeof(uint64_t));
388#endif
389
390/**
391 * Backend type for the endpoint.
392 */
393typedef enum PDMACFILEEPBACKEND
394{
395 /** Non buffered. */
396 PDMACFILEEPBACKEND_NON_BUFFERED = 0,
397 /** Buffered (i.e host cache enabled) */
398 PDMACFILEEPBACKEND_BUFFERED,
399 /** 32bit hack */
400 PDMACFILEEPBACKEND_32BIT_HACK = 0x7fffffff
401} PDMACFILEEPBACKEND;
402/** Pointer to a backend type. */
403typedef PDMACFILEEPBACKEND *PPDMACFILEEPBACKEND;
404
405/**
406 * Global data for the file endpoint class.
407 */
408typedef struct PDMASYNCCOMPLETIONEPCLASSFILE
409{
410 /** Common data. */
411 PDMASYNCCOMPLETIONEPCLASS Core;
412 /** Override I/O manager type - set to SIMPLE after failure. */
413 PDMACEPFILEMGRTYPE enmMgrTypeOverride;
414 /** Default backend type for the endpoint. */
415 PDMACFILEEPBACKEND enmEpBackendDefault;
416 /** Flag whether the file data cache is enabled. */
417 bool fCacheEnabled;
418 /** Critical section protecting the list of async I/O managers. */
419 RTCRITSECT CritSect;
420 /** Pointer to the head of the async I/O managers. */
421 R3PTRTYPE(PPDMACEPFILEMGR) pAioMgrHead;
422 /** Number of async I/O managers currently running. */
423 unsigned cAioMgrs;
424 /** Maximum number of segments to cache per endpoint */
425 unsigned cTasksCacheMax;
426 /** Maximum number of simultaneous outstandingrequests. */
427 uint32_t cReqsOutstandingMax;
428 /** Bitmask for checking the alignment of a buffer. */
429 RTR3UINTPTR uBitmaskAlignment;
430#ifdef VBOX_WITH_STATISTICS
431 uint32_t u32Alignment[2];
432#endif
433 /** Global cache data. */
434 PDMACFILECACHEGLOBAL Cache;
435 /** Flag whether the out of resources warning was printed already. */
436 bool fOutOfResourcesWarningPrinted;
437} PDMASYNCCOMPLETIONEPCLASSFILE;
438/** Pointer to the endpoint class data. */
439typedef PDMASYNCCOMPLETIONEPCLASSFILE *PPDMASYNCCOMPLETIONEPCLASSFILE;
440#ifdef VBOX_WITH_STATISTICS
441AssertCompileMemberAlignment(PDMASYNCCOMPLETIONEPCLASSFILE, Cache, sizeof(uint64_t));
442#endif
443
444typedef enum PDMACEPFILEBLOCKINGEVENT
445{
446 /** The invalid event type */
447 PDMACEPFILEBLOCKINGEVENT_INVALID = 0,
448 /** A task is about to be canceled */
449 PDMACEPFILEBLOCKINGEVENT_CANCEL,
450 /** Usual 32bit hack */
451 PDMACEPFILEBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
452} PDMACEPFILEBLOCKINGEVENT;
453
454/**
455 * States of the endpoint.
456 */
457typedef enum PDMASYNCCOMPLETIONENDPOINTFILESTATE
458{
459 /** Invalid state. */
460 PDMASYNCCOMPLETIONENDPOINTFILESTATE_INVALID = 0,
461 /** Normal running state accepting new requests
462 * and processing them.
463 */
464 PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE,
465 /** The endpoint is about to be closed - not accepting new tasks for endpoints but waiting for
466 * remaining ones to finish.
467 */
468 PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING,
469 /** Removing from current I/O manager state - not processing new tasks for endpoints but waiting
470 * for remaining ones to finish.
471 */
472 PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING,
473 /** The current endpoint will be migrated to another I/O manager. */
474 PDMASYNCCOMPLETIONENDPOINTFILESTATE_MIGRATING,
475 /** 32bit hack */
476 PDMASYNCCOMPLETIONENDPOINTFILESTATE_32BIT_HACK = 0x7fffffff
477} PDMASYNCCOMPLETIONENDPOINTFILESTATE;
478
479/**
480 * Data for the file endpoint.
481 */
482typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
483{
484 /** Common data. */
485 PDMASYNCCOMPLETIONENDPOINT Core;
486 /** Current state of the endpoint. */
487 PDMASYNCCOMPLETIONENDPOINTFILESTATE enmState;
488 /** The backend to use for this endpoint. */
489 PDMACFILEEPBACKEND enmBackendType;
490 /** async I/O manager this endpoint is assigned to. */
491 R3PTRTYPE(volatile PPDMACEPFILEMGR) pAioMgr;
492 /** Flags for opening the file. */
493 unsigned fFlags;
494 /** File handle. */
495 RTFILE File;
496 /** Size of the endpoint.
497 * Updated while data is appended even if it is
498 * only in the cache yet and not written to the file.
499 */
500 volatile uint64_t cbEndpoint;
501 /**
502 * Real size of the file. Only updated if
503 * data is appended.
504 */
505 volatile uint64_t cbFile;
506 /** List of new tasks. */
507 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksNewHead;
508
509 /** Head of the small cache for allocated task segments for exclusive
510 * use by this endpoint. */
511 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeHead;
512 /** Tail of the small cache for allocated task segments for exclusive
513 * use by this endpoint. */
514 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeTail;
515 /** Number of elements in the cache. */
516 volatile uint32_t cTasksCached;
517 /** Cache of endpoint data. */
518 PDMACFILEENDPOINTCACHE DataCache;
519
520 /** Flag whether a flush request is currently active */
521 PPDMACTASKFILE pFlushReq;
522
523#ifdef VBOX_WITH_STATISTICS
524 uint32_t u32Alignment;
525#endif
526
527#ifdef VBOX_WITH_STATISTICS
528 /** Time spend in a read. */
529 STAMPROFILEADV StatRead;
530 /** Time spend in a write. */
531 STAMPROFILEADV StatWrite;
532#endif
533
534 /** Event semaphore for blocking external events.
535 * The caller waits on it until the async I/O manager
536 * finished processing the event. */
537 RTSEMEVENT EventSemBlock;
538 /** Flag whether caching is enabled for this file. */
539 bool fCaching;
540 /** Flag whether the file was opened readonly. */
541 bool fReadonly;
542 /** Flag whether the host supports the async flush API. */
543 bool fAsyncFlushSupported;
544 /** Flag whether a blocking event is pending and needs
545 * processing by the I/O manager. */
546 bool fBlockingEventPending;
547 /** Blocking event type */
548 PDMACEPFILEBLOCKINGEVENT enmBlockingEvent;
549
550 /** Additional data needed for the event types. */
551 union
552 {
553 /** Cancelation event. */
554 struct
555 {
556 /** The task to cancel. */
557 PPDMACTASKFILE pTask;
558 } Cancel;
559 } BlockingEventData;
560 /** Data for exclusive use by the assigned async I/O manager. */
561 struct
562 {
563 /** Pointer to the next endpoint assigned to the manager. */
564 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointNext;
565 /** Pointer to the previous endpoint assigned to the manager. */
566 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointPrev;
567 /** List of pending requests (not submitted due to usage restrictions
568 * or a pending flush request) */
569 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingHead;
570 /** Tail of pending requests. */
571 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingTail;
572 /** Tree of currently locked ranges.
573 * If a write task is enqueued the range gets locked and any other
574 * task writing to that range has to wait until the task completes.
575 */
576 PAVLRFOFFTREE pTreeRangesLocked;
577 /** Number of requests currently being processed for this endpoint
578 * (excluded flush requests). */
579 unsigned cRequestsActive;
580 /** Number of requests processed during the last second. */
581 unsigned cReqsPerSec;
582 /** Current number of processed requests for the current update period. */
583 unsigned cReqsProcessed;
584 /** Flag whether the endpoint is about to be moved to another manager. */
585 bool fMoving;
586 /** Destination I/O manager. */
587 PPDMACEPFILEMGR pAioMgrDst;
588 } AioMgr;
589} PDMASYNCCOMPLETIONENDPOINTFILE;
590/** Pointer to the endpoint class data. */
591typedef PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
592#ifdef VBOX_WITH_STATISTICS
593AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINTFILE, StatRead, sizeof(uint64_t));
594AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINTFILE, DataCache, sizeof(uint64_t));
595#endif
596
597/** Request completion function */
598typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc);
599/** Pointer to a request completion function. */
600typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
601
602/**
603 * Transfer type.
604 */
605typedef enum PDMACTASKFILETRANSFER
606{
607 /** Invalid. */
608 PDMACTASKFILETRANSFER_INVALID = 0,
609 /** Read transfer. */
610 PDMACTASKFILETRANSFER_READ,
611 /** Write transfer. */
612 PDMACTASKFILETRANSFER_WRITE,
613 /** Flush transfer. */
614 PDMACTASKFILETRANSFER_FLUSH
615} PDMACTASKFILETRANSFER;
616
617/**
618 * Data of a request.
619 */
620typedef struct PDMACTASKFILE
621{
622 /** Pointer to the range lock we are waiting for */
623 PPDMACFILERANGELOCK pRangeLock;
624 /** Next task in the list. (Depending on the state) */
625 struct PDMACTASKFILE *pNext;
626 /** Endpoint */
627 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
628 /** Transfer type. */
629 PDMACTASKFILETRANSFER enmTransferType;
630 /** Start offset */
631 RTFOFF Off;
632 /** Data segment. */
633 RTSGSEG DataSeg;
634 /** When non-zero the segment uses a bounce buffer because the provided buffer
635 * doesn't meet host requirements. */
636 size_t cbBounceBuffer;
637 /** Pointer to the used bounce buffer if any. */
638 void *pvBounceBuffer;
639 /** Start offset in the bounce buffer to copy from. */
640 uint32_t offBounceBuffer;
641 /** Flag whether this is a prefetch request. */
642 bool fPrefetch;
643 /** Already prepared native I/O request.
644 * Used if the request is prepared already but
645 * was not queued because the host has not enough
646 * resources. */
647 RTFILEAIOREQ hReq;
648 /** Completion function to call on completion. */
649 PFNPDMACTASKCOMPLETED pfnCompleted;
650 /** User data */
651 void *pvUser;
652} PDMACTASKFILE;
653
654/**
655 * Per task data.
656 */
657typedef struct PDMASYNCCOMPLETIONTASKFILE
658{
659 /** Common data. */
660 PDMASYNCCOMPLETIONTASK Core;
661 /** Number of bytes to transfer until this task completes. */
662 volatile int32_t cbTransferLeft;
663 /** Flag whether the task completed. */
664 volatile bool fCompleted;
665 /** Return code. */
666 volatile int rc;
667} PDMASYNCCOMPLETIONTASKFILE;
668
669int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser);
670int pdmacFileAioMgrNormal(RTTHREAD ThreadSelf, void *pvUser);
671
672int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr);
673void pdmacFileAioMgrNormalDestroy(PPDMACEPFILEMGR pAioMgr);
674
675int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr, PDMACEPFILEMGRTYPE enmMgrType);
676
677int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
678
679PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
680PPDMACTASKFILE pdmacFileTaskAlloc(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
681void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
682 PPDMACTASKFILE pTask);
683
684int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
685
686void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
687
688int pdmacFileCacheInit(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile, PCFGMNODE pCfgNode);
689void pdmacFileCacheDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
690int pdmacFileEpCacheInit(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
691void pdmacFileEpCacheDestroy(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
692
693int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
694 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
695 size_t cbRead);
696int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
697 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
698 size_t cbWrite);
699int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
700
701RT_C_DECLS_END
702
703#endif
704
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