xref: /haiku/src/system/kernel/device_manager/IOSchedulerSimple.h (revision 435c43f5912b109e7d5cf682865d2061e62fad8c)
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