VirtualBox

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

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

AsyncCompletion: Protect the dirty but not committed list by a spinlock

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