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