xref: /haiku/src/system/kernel/device_manager/IOCache.h (revision e91e4ee0a6787d04bfac0fef11e5e3cffe9b9f6b)
1*e91e4ee0SIngo Weinhold /*
2*e91e4ee0SIngo Weinhold  * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3*e91e4ee0SIngo Weinhold  * Distributed under the terms of the MIT License.
4*e91e4ee0SIngo Weinhold  */
5*e91e4ee0SIngo Weinhold #ifndef IO_CACHE_H
6*e91e4ee0SIngo Weinhold #define IO_CACHE_H
7*e91e4ee0SIngo Weinhold 
8*e91e4ee0SIngo Weinhold 
9*e91e4ee0SIngo Weinhold #include <lock.h>
10*e91e4ee0SIngo Weinhold #include <util/DoublyLinkedList.h>
11*e91e4ee0SIngo Weinhold 
12*e91e4ee0SIngo Weinhold #include "dma_resources.h"
13*e91e4ee0SIngo Weinhold #include "IOCallback.h"
14*e91e4ee0SIngo Weinhold #include "IORequest.h"
15*e91e4ee0SIngo Weinhold 
16*e91e4ee0SIngo Weinhold 
17*e91e4ee0SIngo Weinhold class IOCache {
18*e91e4ee0SIngo Weinhold public:
19*e91e4ee0SIngo Weinhold 								IOCache(DMAResource* resource,
20*e91e4ee0SIngo Weinhold 									size_t cacheLineSize);
21*e91e4ee0SIngo Weinhold 								~IOCache();
22*e91e4ee0SIngo Weinhold 
23*e91e4ee0SIngo Weinhold 			status_t			Init(const char* name);
24*e91e4ee0SIngo Weinhold 
25*e91e4ee0SIngo Weinhold 			void				SetCallback(IOCallback& callback);
26*e91e4ee0SIngo Weinhold 			void				SetCallback(io_callback callback, void* data);
27*e91e4ee0SIngo Weinhold 
28*e91e4ee0SIngo Weinhold 			void				SetDeviceCapacity(off_t deviceCapacity);
29*e91e4ee0SIngo Weinhold 
30*e91e4ee0SIngo Weinhold 			status_t			ScheduleRequest(IORequest* request);
31*e91e4ee0SIngo Weinhold 
32*e91e4ee0SIngo Weinhold 			void				OperationCompleted(IOOperation* operation,
33*e91e4ee0SIngo Weinhold 									status_t status, size_t transferredBytes);
34*e91e4ee0SIngo Weinhold 
35*e91e4ee0SIngo Weinhold private:
36*e91e4ee0SIngo Weinhold 			struct Line : DoublyLinkedListLinkImpl<Line> {
37*e91e4ee0SIngo Weinhold 				Line*	hashNext;
38*e91e4ee0SIngo Weinhold 				off_t	offset;
39*e91e4ee0SIngo Weinhold 				off_t	size;
40*e91e4ee0SIngo Weinhold 				uint8*	buffer;
41*e91e4ee0SIngo Weinhold 				addr_t	physicalBuffer;
42*e91e4ee0SIngo Weinhold 				area_id	area;
43*e91e4ee0SIngo Weinhold 				bool	inUse;
44*e91e4ee0SIngo Weinhold 			};
45*e91e4ee0SIngo Weinhold 
46*e91e4ee0SIngo Weinhold 			struct Operation;
47*e91e4ee0SIngo Weinhold 			struct LineHashDefinition;
48*e91e4ee0SIngo Weinhold 			struct LineTable;
49*e91e4ee0SIngo Weinhold 			typedef DoublyLinkedList<Line> LineList;
50*e91e4ee0SIngo Weinhold 
51*e91e4ee0SIngo Weinhold private:
52*e91e4ee0SIngo Weinhold 			status_t			_DoRequest(IORequest* request,
53*e91e4ee0SIngo Weinhold 									size_t& _bytesTransferred);
54*e91e4ee0SIngo Weinhold 			status_t			_TransferRequestLine(IORequest* request,
55*e91e4ee0SIngo Weinhold 									off_t lineOffset, off_t requestOffset,
56*e91e4ee0SIngo Weinhold 									size_t requestLength);
57*e91e4ee0SIngo Weinhold 			status_t			_TransferLine(Line* line, bool isWrite,
58*e91e4ee0SIngo Weinhold 									bool isVIP);
59*e91e4ee0SIngo Weinhold 			status_t			_DoOperation(Operation& operation);
60*e91e4ee0SIngo Weinhold 
61*e91e4ee0SIngo Weinhold 			Line*				_LookupLine(off_t lineOffset);
62*e91e4ee0SIngo Weinhold 			Line*				_PrepareLine(off_t lineOffset);
63*e91e4ee0SIngo Weinhold 			void				_DiscardLine(Line* line);
64*e91e4ee0SIngo Weinhold 			Line*				_AllocateLine();
65*e91e4ee0SIngo Weinhold 			void				_FreeLine(Line* line);
66*e91e4ee0SIngo Weinhold 
67*e91e4ee0SIngo Weinhold 	static	void				_LowMemoryHandlerEntry(void* data,
68*e91e4ee0SIngo Weinhold 									uint32 resources, int32 level);
69*e91e4ee0SIngo Weinhold 			void				_LowMemoryHandler(uint32 resources,
70*e91e4ee0SIngo Weinhold 									int32 level);
71*e91e4ee0SIngo Weinhold 	inline	bool				_MemoryIsLow() const;
72*e91e4ee0SIngo Weinhold 
73*e91e4ee0SIngo Weinhold private:
74*e91e4ee0SIngo Weinhold 			mutex				fLock;
75*e91e4ee0SIngo Weinhold 			mutex				fSerializationLock;
76*e91e4ee0SIngo Weinhold 			off_t				fDeviceCapacity;
77*e91e4ee0SIngo Weinhold 			size_t				fLineSize;
78*e91e4ee0SIngo Weinhold 			uint32				fLineSizeShift;
79*e91e4ee0SIngo Weinhold 			DMAResource*		fDMAResource;
80*e91e4ee0SIngo Weinhold 			io_callback			fIOCallback;
81*e91e4ee0SIngo Weinhold 			void*				fIOCallbackData;
82*e91e4ee0SIngo Weinhold 			LineTable*			fLineTable;
83*e91e4ee0SIngo Weinhold 			LineList			fUsedLines;		// LRU first
84*e91e4ee0SIngo Weinhold 			Line*				fUnusedLine;
85*e91e4ee0SIngo Weinhold 			size_t				fLineCount;
86*e91e4ee0SIngo Weinhold 			bool				fLowMemoryHandlerRegistered;
87*e91e4ee0SIngo Weinhold };
88*e91e4ee0SIngo Weinhold 
89*e91e4ee0SIngo Weinhold 
90*e91e4ee0SIngo Weinhold #endif	// IO_CACHE_H
91