VirtualBox

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

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

RTMemPageFree + all users: Added size parameter to RTMemPageFree so we can avoid tracking structures when using mmap/munmap.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.2 KB
Line 
1/* $Id: PDMAsyncCompletionFileInternal.h 28317 2010-04-14 18:06:05Z 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 /** 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 /** Next free position for a free request handle. */
166 unsigned iFreeEntryNext;
167 /** Position of the next free task handle */
168 unsigned iFreeReqNext;
169 /** Size of the array. */
170 unsigned cReqEntries;
171 /** Flag whether at least one endpoint reached its bandwidth limit. */
172 bool fBwLimitReached;
173 /** Memory cache for file range locks. */
174 RTMEMCACHE hMemCacheRangeLocks;
175 /** Critical section protecting the blocking event handling. */
176 RTCRITSECT CritSectBlockingEvent;
177 /** Event sempahore for blocking external events.
178 * The caller waits on it until the async I/O manager
179 * finished processing the event. */
180 RTSEMEVENT EventSemBlock;
181 /** Flag whether a blocking event is pending and needs
182 * processing by the I/O manager. */
183 volatile bool fBlockingEventPending;
184 /** Blocking event type */
185 volatile PDMACEPFILEAIOMGRBLOCKINGEVENT enmBlockingEvent;
186 /** Event type data */
187 union
188 {
189 /** Add endpoint event. */
190 struct
191 {
192 /** The endpoint to be added */
193 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
194 } AddEndpoint;
195 /** Remove endpoint event. */
196 struct
197 {
198 /** The endpoint to be removed */
199 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
200 } RemoveEndpoint;
201 /** Close endpoint event. */
202 struct
203 {
204 /** The endpoint to be closed */
205 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
206 } CloseEndpoint;
207 } BlockingEventData;
208} PDMACEPFILEMGR;
209/** Pointer to a async I/O manager state. */
210typedef PDMACEPFILEMGR *PPDMACEPFILEMGR;
211/** Pointer to a async I/O manager state pointer. */
212typedef PPDMACEPFILEMGR *PPPDMACEPFILEMGR;
213
214/**
215 * Bandwidth control manager instance data
216 */
217typedef struct PDMACFILEBWMGR
218{
219 /** Maximum number of bytes the VM is allowed to transfer (Max is 4GB/s) */
220 uint32_t cbVMTransferPerSecMax;
221 /** Number of bytes we start with */
222 uint32_t cbVMTransferPerSecStart;
223 /** Step after each update */
224 uint32_t cbVMTransferPerSecStep;
225 /** Number of bytes we are allowed to transfer till the next update.
226 * Resetted by the refresh timer. */
227 volatile uint32_t cbVMTransferAllowed;
228 /** Timestamp of the last update */
229 volatile uint64_t tsUpdatedLast;
230 /** Reference counter - How many endpoints are associated with this manager. */
231 uint32_t cRefs;
232} PDMACFILEBWMGR;
233/** Pointer to a bandwidth control manager */
234typedef PDMACFILEBWMGR *PPDMACFILEBWMGR;
235/** Pointer to a bandwidth control manager pointer */
236typedef PPDMACFILEBWMGR *PPPDMACFILEBWMGR;
237
238/**
239 * A file access range lock.
240 */
241typedef struct PDMACFILERANGELOCK
242{
243 /** AVL node in the locked range tree of the endpoint. */
244 AVLRFOFFNODECORE Core;
245 /** How many tasks have locked this range. */
246 uint32_t cRefs;
247 /** Flag whether this is a read or write lock. */
248 bool fReadLock;
249 /** List of tasks which are waiting that the range gets unlocked. */
250 PPDMACTASKFILE pWaitingTasksHead;
251 /** List of tasks which are waiting that the range gets unlocked. */
252 PPDMACTASKFILE pWaitingTasksTail;
253} PDMACFILERANGELOCK, *PPDMACFILERANGELOCK;
254
255/**
256 * Data for one request segment waiting for cache entry.
257 */
258typedef struct PDMACFILETASKSEG
259{
260 /** Next task segment in the list. */
261 struct PDMACFILETASKSEG *pNext;
262 /** Task this segment is for. */
263 PPDMASYNCCOMPLETIONTASKFILE pTask;
264 /** Offset into the cache entry buffer to start reading from. */
265 uint32_t uBufOffset;
266 /** Number of bytes to transfer. */
267 size_t cbTransfer;
268 /** Pointer to the buffer. */
269 void *pvBuf;
270 /** Flag whether this entry writes data to the cache. */
271 bool fWrite;
272} PDMACFILETASKSEG;
273
274/**
275 * A cache entry
276 */
277typedef struct PDMACFILECACHEENTRY
278{
279 /** The AVL entry data. */
280 AVLRFOFFNODECORE Core;
281 /** Pointer to the previous element. Used in one of the LRU lists.*/
282 struct PDMACFILECACHEENTRY *pPrev;
283 /** Pointer to the next element. Used in one of the LRU lists.*/
284 struct PDMACFILECACHEENTRY *pNext;
285 /** Pointer to the list the entry is in. */
286 PPDMACFILELRULIST pList;
287 /** Pointer to the global cache structure. */
288 PPDMACFILECACHEGLOBAL pCache;
289 /** Endpoint the entry belongs to. */
290 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
291 /** Flags for this entry. Combinations of PDMACFILECACHE_* #defines */
292 volatile uint32_t fFlags;
293 /** Reference counter. Prevents eviction of the entry if > 0. */
294 volatile uint32_t cRefs;
295 /** Size of the entry. */
296 size_t cbData;
297 /** Pointer to the memory containing the data. */
298 uint8_t *pbData;
299 /** Head of list of tasks waiting for this one to finish. */
300 PPDMACFILETASKSEG pWaitingHead;
301 /** Tail of list of tasks waiting for this one to finish. */
302 PPDMACFILETASKSEG pWaitingTail;
303 /** Node for dirty but not yet committed entries list per endpoint. */
304 RTLISTNODE NodeNotCommitted;
305} PDMACFILECACHEENTRY, *PPDMACFILECACHEENTRY;
306/** I/O is still in progress for this entry. This entry is not evictable. */
307#define PDMACFILECACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
308/** Entry is locked and thus not evictable. */
309#define PDMACFILECACHE_ENTRY_LOCKED RT_BIT(1)
310/** Entry is dirty */
311#define PDMACFILECACHE_ENTRY_IS_DIRTY RT_BIT(2)
312/** Entry is not evictable. */
313#define PDMACFILECACHE_NOT_EVICTABLE (PDMACFILECACHE_ENTRY_LOCKED | PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)
314
315/**
316 * LRU list data
317 */
318typedef struct PDMACFILELRULIST
319{
320 /** Head of the list. */
321 PPDMACFILECACHEENTRY pHead;
322 /** Tail of the list. */
323 PPDMACFILECACHEENTRY pTail;
324 /** Number of bytes cached in the list. */
325 uint32_t cbCached;
326} PDMACFILELRULIST;
327
328/**
329 * Global cache data.
330 */
331typedef struct PDMACFILECACHEGLOBAL
332{
333 /** Maximum size of the cache in bytes. */
334 uint32_t cbMax;
335 /** Current size of the cache in bytes. */
336 uint32_t cbCached;
337 /** Critical section protecting the cache. */
338 RTCRITSECT CritSect;
339 /** Maximum number of bytes cached. */
340 uint32_t cbRecentlyUsedInMax;
341 /** Maximum number of bytes in the paged out list .*/
342 uint32_t cbRecentlyUsedOutMax;
343 /** Recently used cache entries list */
344 PDMACFILELRULIST LruRecentlyUsedIn;
345 /** Scorecard cache entry list. */
346 PDMACFILELRULIST LruRecentlyUsedOut;
347 /** List of frequently used cache entries */
348 PDMACFILELRULIST LruFrequentlyUsed;
349 /** Commit timeout in milli seconds */
350 uint32_t u32CommitTimeoutMs;
351 /** Number of dirty bytes needed to start a commit of the data to the disk. */
352 uint32_t cbCommitDirtyThreshold;
353 /** Current number of dirty bytes in the cache. */
354 volatile uint32_t cbDirty;
355 /** Flag whether a commit is currently in progress. */
356 volatile bool fCommitInProgress;
357 /** Commit interval timer */
358 PTMTIMERR3 pTimerCommit;
359 /** Number of endpoints using the cache. */
360 uint32_t cRefs;
361 /** List of all endpoints using this cache. */
362 RTLISTNODE ListEndpoints;
363#ifdef VBOX_WITH_STATISTICS
364 /** Hit counter. */
365 STAMCOUNTER cHits;
366 /** Partial hit counter. */
367 STAMCOUNTER cPartialHits;
368 /** Miss counter. */
369 STAMCOUNTER cMisses;
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;
382#endif
383} PDMACFILECACHEGLOBAL;
384
385/**
386 * Per endpoint cache data.
387 */
388typedef struct PDMACFILEENDPOINTCACHE
389{
390 /** AVL tree managing cache entries. */
391 PAVLRFOFFTREE pTree;
392 /** R/W semaphore protecting cached entries for this endpoint. */
393 RTSEMRW SemRWEntries;
394 /** Pointer to the gobal cache data */
395 PPDMACFILECACHEGLOBAL pCache;
396 /** Number of writes outstanding. */
397 volatile uint32_t cWritesOutstanding;
398 /** Handle of the flush request if one is active */
399 volatile PPDMASYNCCOMPLETIONTASKFILE pTaskFlush;
400 /** Lock protecting the dirty entries list. */
401 RTSPINLOCK LockList;
402 /** List of dirty but not committed entries for this endpoint. */
403 RTLISTNODE ListDirtyNotCommitted;
404 /** Node of the cache endpoint list. */
405 RTLISTNODE NodeCacheEndpoint;
406#ifdef VBOX_WITH_STATISTICS
407 /** Alignment */
408 bool afAlignment[3];
409 /** Number of times a write was deferred because the cache entry was still in progress */
410 STAMCOUNTER StatWriteDeferred;
411#endif
412} PDMACFILEENDPOINTCACHE, *PPDMACFILEENDPOINTCACHE;
413
414/**
415 * Backend type for the endpoint.
416 */
417typedef enum PDMACFILEEPBACKEND
418{
419 /** Non buffered. */
420 PDMACFILEEPBACKEND_NON_BUFFERED = 0,
421 /** Buffered (i.e host cache enabled) */
422 PDMACFILEEPBACKEND_BUFFERED,
423 /** 32bit hack */
424 PDMACFILEEPBACKEND_32BIT_HACK = 0x7fffffff
425} PDMACFILEEPBACKEND;
426/** Pointer to a backend type. */
427typedef PDMACFILEEPBACKEND *PPDMACFILEEPBACKEND;
428
429/**
430 * Global data for the file endpoint class.
431 */
432typedef struct PDMASYNCCOMPLETIONEPCLASSFILE
433{
434 /** Common data. */
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. */
441 bool fCacheEnabled;
442 /** Critical section protecting the list of async I/O managers. */
443 RTCRITSECT CritSect;
444 /** Pointer to the head of the async I/O managers. */
445 R3PTRTYPE(PPDMACEPFILEMGR) pAioMgrHead;
446 /** Number of async I/O managers currently running. */
447 unsigned cAioMgrs;
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 /** Global cache data. */
455 PDMACFILECACHEGLOBAL Cache;
456 /** Flag whether the out of resources warning was printed already. */
457 bool fOutOfResourcesWarningPrinted;
458 /** The global bandwidth control manager */
459 PPDMACFILEBWMGR pBwMgr;
460} PDMASYNCCOMPLETIONEPCLASSFILE;
461/** Pointer to the endpoint class data. */
462typedef PDMASYNCCOMPLETIONEPCLASSFILE *PPDMASYNCCOMPLETIONEPCLASSFILE;
463
464typedef enum PDMACEPFILEBLOCKINGEVENT
465{
466 /** The invalid event type */
467 PDMACEPFILEBLOCKINGEVENT_INVALID = 0,
468 /** A task is about to be canceled */
469 PDMACEPFILEBLOCKINGEVENT_CANCEL,
470 /** Usual 32bit hack */
471 PDMACEPFILEBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
472} PDMACEPFILEBLOCKINGEVENT;
473
474/**
475 * States of the endpoint.
476 */
477typedef enum PDMASYNCCOMPLETIONENDPOINTFILESTATE
478{
479 /** Invalid state. */
480 PDMASYNCCOMPLETIONENDPOINTFILESTATE_INVALID = 0,
481 /** Normal running state accepting new requests
482 * and processing them.
483 */
484 PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE,
485 /** The endpoint is about to be closed - not accepting new tasks for endpoints but waiting for
486 * remaining ones to finish.
487 */
488 PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING,
489 /** Removing from current I/O manager state - not processing new tasks for endpoints but waiting
490 * for remaining ones to finish.
491 */
492 PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING,
493 /** The current endpoint will be migrated to another I/O manager. */
494 PDMASYNCCOMPLETIONENDPOINTFILESTATE_MIGRATING,
495 /** 32bit hack */
496 PDMASYNCCOMPLETIONENDPOINTFILESTATE_32BIT_HACK = 0x7fffffff
497} PDMASYNCCOMPLETIONENDPOINTFILESTATE;
498
499/**
500 * Data for the file endpoint.
501 */
502typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
503{
504 /** Common data. */
505 PDMASYNCCOMPLETIONENDPOINT Core;
506 /** Current state of the endpoint. */
507 PDMASYNCCOMPLETIONENDPOINTFILESTATE enmState;
508 /** The backend to use for this endpoint. */
509 PDMACFILEEPBACKEND enmBackendType;
510 /** async I/O manager this endpoint is assigned to. */
511 R3PTRTYPE(volatile PPDMACEPFILEMGR) pAioMgr;
512 /** Flags for opening the file. */
513 unsigned fFlags;
514 /** File handle. */
515 RTFILE File;
516 /** Size of the endpoint.
517 * Updated while data is appended even if it is
518 * only in the cache yet and not written to the file.
519 */
520 volatile uint64_t cbEndpoint;
521 /**
522 * Real size of the file. Only updated if
523 * data is appended.
524 */
525 volatile uint64_t cbFile;
526 /** List of new tasks. */
527 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksNewHead;
528
529 /** Head of the small cache for allocated task segments for exclusive
530 * use by this endpoint. */
531 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeHead;
532 /** Tail of the small cache for allocated task segments for exclusive
533 * use by this endpoint. */
534 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeTail;
535 /** Number of elements in the cache. */
536 volatile uint32_t cTasksCached;
537
538 /** Cache of endpoint data. */
539 PDMACFILEENDPOINTCACHE DataCache;
540 /** Pointer to the associated bandwidth control manager */
541 PPDMACFILEBWMGR pBwMgr;
542
543 /** Flag whether a flush request is currently active */
544 PPDMACTASKFILE pFlushReq;
545
546#ifdef VBOX_WITH_STATISTICS
547 /** Time spend in a read. */
548 STAMPROFILEADV StatRead;
549 /** Time spend in a write. */
550 STAMPROFILEADV StatWrite;
551#endif
552
553 /** Event sempahore for blocking external events.
554 * The caller waits on it until the async I/O manager
555 * finished processing the event. */
556 RTSEMEVENT EventSemBlock;
557 /** Flag whether caching is enabled for this file. */
558 bool fCaching;
559 /** Flag whether the file was opened readonly. */
560 bool fReadonly;
561 /** Flag whether a blocking event is pending and needs
562 * processing by the I/O manager. */
563 bool fBlockingEventPending;
564 /** Blocking event type */
565 PDMACEPFILEBLOCKINGEVENT enmBlockingEvent;
566
567 /** Additional data needed for the event types. */
568 union
569 {
570 /** Cancelation event. */
571 struct
572 {
573 /** The task to cancel. */
574 PPDMACTASKFILE pTask;
575 } Cancel;
576 } BlockingEventData;
577 /** Data for exclusive use by the assigned async I/O manager. */
578 struct
579 {
580 /** Pointer to the next endpoint assigned to the manager. */
581 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointNext;
582 /** Pointer to the previous endpoint assigned to the manager. */
583 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointPrev;
584 /** List of pending requests (not submitted due to usage restrictions
585 * or a pending flush request) */
586 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingHead;
587 /** Tail of pending requests. */
588 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingTail;
589 /** Tree of currently locked ranges.
590 * If a write task is enqueued the range gets locked and any other
591 * task writing to that range has to wait until the task completes.
592 */
593 PAVLRFOFFTREE pTreeRangesLocked;
594 /** Number of requests currently being processed for this endpoint
595 * (excluded flush requests). */
596 unsigned cRequestsActive;
597 /** Number of requests processed during the last second. */
598 unsigned cReqsPerSec;
599 /** Current number of processed requests for the current update period. */
600 unsigned cReqsProcessed;
601 /** Flag whether the endpoint is about to be moved to another manager. */
602 bool fMoving;
603 /** Destination I/O manager. */
604 PPDMACEPFILEMGR pAioMgrDst;
605 } AioMgr;
606} PDMASYNCCOMPLETIONENDPOINTFILE;
607/** Pointer to the endpoint class data. */
608typedef PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
609
610/** Request completion function */
611typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc);
612/** Pointer to a request completion function. */
613typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
614
615/**
616 * Transfer type.
617 */
618typedef enum PDMACTASKFILETRANSFER
619{
620 /** Invalid. */
621 PDMACTASKFILETRANSFER_INVALID = 0,
622 /** Read transfer. */
623 PDMACTASKFILETRANSFER_READ,
624 /** Write transfer. */
625 PDMACTASKFILETRANSFER_WRITE,
626 /** Flush transfer. */
627 PDMACTASKFILETRANSFER_FLUSH
628} PDMACTASKFILETRANSFER;
629
630/**
631 * Data of a request.
632 */
633typedef struct PDMACTASKFILE
634{
635 /** Pointer to the range lock we are waiting for */
636 PPDMACFILERANGELOCK pRangeLock;
637 /** Next task in the list. (Depending on the state) */
638 struct PDMACTASKFILE *pNext;
639 /** Endpoint */
640 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
641 /** Transfer type. */
642 PDMACTASKFILETRANSFER enmTransferType;
643 /** Start offset */
644 RTFOFF Off;
645 /** Data segment. */
646 RTSGSEG DataSeg;
647 /** When non-zero the segment uses a bounce buffer because the provided buffer
648 * doesn't meet host requirements. */
649 size_t cbBounceBuffer;
650 /** Pointer to the used bounce buffer if any. */
651 void *pvBounceBuffer;
652 /** Start offset in the bounce buffer to copy from. */
653 uint32_t offBounceBuffer;
654 /** Flag whether this is a prefetch request. */
655 bool fPrefetch;
656 /** Completion function to call on completion. */
657 PFNPDMACTASKCOMPLETED pfnCompleted;
658 /** User data */
659 void *pvUser;
660} PDMACTASKFILE;
661
662/**
663 * Per task data.
664 */
665typedef struct PDMASYNCCOMPLETIONTASKFILE
666{
667 /** Common data. */
668 PDMASYNCCOMPLETIONTASK Core;
669 /** Number of bytes to transfer until this task completes. */
670 volatile int32_t cbTransferLeft;
671 /** Flag whether the task completed. */
672 volatile bool fCompleted;
673 /** Return code. */
674 volatile int rc;
675} PDMASYNCCOMPLETIONTASKFILE;
676
677int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser);
678int pdmacFileAioMgrNormal(RTTHREAD ThreadSelf, void *pvUser);
679
680int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr);
681void pdmacFileAioMgrNormalDestroy(PPDMACEPFILEMGR pAioMgr);
682
683int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr, PDMACEPFILEMGRTYPE enmMgrType);
684
685int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
686
687PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
688PPDMACTASKFILE pdmacFileTaskAlloc(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
689void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
690 PPDMACTASKFILE pTask);
691
692int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
693
694void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
695
696bool pdmacFileBwMgrIsTransferAllowed(PPDMACFILEBWMGR pBwMgr, uint32_t cbTransfer);
697
698int pdmacFileCacheInit(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile, PCFGMNODE pCfgNode);
699void pdmacFileCacheDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
700int pdmacFileEpCacheInit(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
701void pdmacFileEpCacheDestroy(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
702
703int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
704 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
705 size_t cbRead);
706int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
707 RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
708 size_t cbWrite);
709int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask);
710
711RT_C_DECLS_END
712
713#endif
714
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