VirtualBox

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

最後變更 在這個檔案從35282是 35205,由 vboxsync 提交於 14 年 前

AsyncCompletion: Don't waste CPU cycles when all endpoints have reached the bandwidth limit and go to sleep

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette