10715529bSIngo Weinhold /* 20715529bSIngo Weinhold * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 30715529bSIngo Weinhold * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. 40715529bSIngo Weinhold * Distributed under the terms of the MIT License. 50715529bSIngo Weinhold */ 60715529bSIngo Weinhold #ifndef IO_SCHEDULER_SIMPLE_H 70715529bSIngo Weinhold #define IO_SCHEDULER_SIMPLE_H 80715529bSIngo Weinhold 90715529bSIngo Weinhold 100715529bSIngo Weinhold #include <KernelExport.h> 110715529bSIngo Weinhold 120715529bSIngo Weinhold #include <condition_variable.h> 130715529bSIngo Weinhold #include <lock.h> 140715529bSIngo Weinhold #include <util/OpenHashTable.h> 150715529bSIngo Weinhold 160715529bSIngo Weinhold #include "dma_resources.h" 170715529bSIngo Weinhold #include "IOScheduler.h" 180715529bSIngo Weinhold 190715529bSIngo Weinhold 200715529bSIngo Weinhold class IOSchedulerSimple : public IOScheduler { 210715529bSIngo Weinhold public: 220715529bSIngo Weinhold IOSchedulerSimple(DMAResource* resource); 230715529bSIngo Weinhold virtual ~IOSchedulerSimple(); 240715529bSIngo Weinhold 250715529bSIngo Weinhold virtual status_t Init(const char* name); 260715529bSIngo Weinhold 270715529bSIngo Weinhold virtual status_t ScheduleRequest(IORequest* request); 280715529bSIngo Weinhold 290715529bSIngo Weinhold virtual void AbortRequest(IORequest* request, 300715529bSIngo Weinhold status_t status = B_CANCELED); 310715529bSIngo Weinhold virtual void OperationCompleted(IOOperation* operation, 32*435c43f5SIngo Weinhold status_t status, 33*435c43f5SIngo Weinhold generic_size_t transferredBytes); 340715529bSIngo Weinhold // called by the driver when the operation 350715529bSIngo Weinhold // has been completed successfully or failed 360715529bSIngo Weinhold // for some reason 370715529bSIngo Weinhold 380715529bSIngo Weinhold virtual void Dump() const; 390715529bSIngo Weinhold 400715529bSIngo Weinhold private: 410715529bSIngo Weinhold typedef DoublyLinkedList<IORequestOwner> RequestOwnerList; 420715529bSIngo Weinhold 430715529bSIngo Weinhold struct RequestOwnerHashDefinition; 440715529bSIngo Weinhold struct RequestOwnerHashTable; 450715529bSIngo Weinhold 460715529bSIngo Weinhold void _Finisher(); 470715529bSIngo Weinhold bool _FinisherWorkPending(); 480715529bSIngo Weinhold off_t _ComputeRequestOwnerBandwidth( 490715529bSIngo Weinhold int32 priority) const; 500715529bSIngo Weinhold bool _NextActiveRequestOwner(IORequestOwner*& owner, 510715529bSIngo Weinhold off_t& quantum); 520715529bSIngo Weinhold bool _PrepareRequestOperations(IORequest* request, 530715529bSIngo Weinhold IOOperationList& operations, 540715529bSIngo Weinhold int32& operationsPrepared); 550715529bSIngo Weinhold bool _PrepareRequestOperations(IORequest* request, 560715529bSIngo Weinhold IOOperationList& operations, 570715529bSIngo Weinhold int32& operationsPrepared, off_t quantum, 580715529bSIngo Weinhold off_t& usedBandwidth); 590715529bSIngo Weinhold void _SortOperations(IOOperationList& operations, 600715529bSIngo Weinhold off_t& lastOffset); 610715529bSIngo Weinhold status_t _Scheduler(); 620715529bSIngo Weinhold static status_t _SchedulerThread(void* self); 630715529bSIngo Weinhold status_t _RequestNotifier(); 640715529bSIngo Weinhold static status_t _RequestNotifierThread(void* self); 650715529bSIngo Weinhold 660715529bSIngo Weinhold void _AddRequestOwner(IORequestOwner* owner); 670715529bSIngo Weinhold IORequestOwner* _GetRequestOwner(team_id team, thread_id thread, 680715529bSIngo Weinhold bool allocate); 690715529bSIngo Weinhold 700715529bSIngo Weinhold private: 710715529bSIngo Weinhold spinlock fFinisherLock; 720715529bSIngo Weinhold mutex fLock; 730715529bSIngo Weinhold thread_id fSchedulerThread; 740715529bSIngo Weinhold thread_id fRequestNotifierThread; 750715529bSIngo Weinhold IORequestList fUnscheduledRequests; 760715529bSIngo Weinhold IORequestList fFinishedRequests; 770715529bSIngo Weinhold ConditionVariable fNewRequestCondition; 780715529bSIngo Weinhold ConditionVariable fFinishedOperationCondition; 790715529bSIngo Weinhold ConditionVariable fFinishedRequestCondition; 800715529bSIngo Weinhold IOOperation** fOperationArray; 810715529bSIngo Weinhold IOOperationList fUnusedOperations; 820715529bSIngo Weinhold IOOperationList fCompletedOperations; 830715529bSIngo Weinhold IORequestOwner* fAllocatedRequestOwners; 840715529bSIngo Weinhold int32 fAllocatedRequestOwnerCount; 850715529bSIngo Weinhold RequestOwnerList fActiveRequestOwners; 860715529bSIngo Weinhold RequestOwnerList fUnusedRequestOwners; 870715529bSIngo Weinhold RequestOwnerHashTable* fRequestOwners; 88*435c43f5SIngo Weinhold generic_size_t fBlockSize; 890715529bSIngo Weinhold int32 fPendingOperations; 900715529bSIngo Weinhold off_t fIterationBandwidth; 910715529bSIngo Weinhold off_t fMinOwnerBandwidth; 920715529bSIngo Weinhold off_t fMaxOwnerBandwidth; 930715529bSIngo Weinhold volatile bool fTerminating; 940715529bSIngo Weinhold }; 950715529bSIngo Weinhold 960715529bSIngo Weinhold 970715529bSIngo Weinhold #endif // IO_SCHEDULER_SIMPLE_H 98