VirtualBox

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

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

AsyncCompletion: Increase the maximum number of requests the I/O manager can handle if required instead of using a static value

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