1/*
2 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2004-2008, Axel D��rfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef IO_SCHEDULER_SIMPLE_H
7#define IO_SCHEDULER_SIMPLE_H
8
9
10#include <KernelExport.h>
11
12#include <condition_variable.h>
13#include <lock.h>
14#include <util/OpenHashTable.h>
15
16#include "dma_resources.h"
17#include "IOScheduler.h"
18
19
20class IOSchedulerSimple : public IOScheduler {
21public:
22								IOSchedulerSimple(DMAResource* resource);
23	virtual						~IOSchedulerSimple();
24
25	virtual	status_t			Init(const char* name);
26
27	virtual	status_t			ScheduleRequest(IORequest* request);
28
29	virtual	void				AbortRequest(IORequest* request,
30									status_t status = B_CANCELED);
31	virtual	void				OperationCompleted(IOOperation* operation,
32									status_t status,
33									generic_size_t transferredBytes);
34									// called by the driver when the operation
35									// has been completed successfully or failed
36									// for some reason
37
38	virtual	void				Dump() const;
39
40private:
41			typedef DoublyLinkedList<IORequestOwner> RequestOwnerList;
42
43			struct RequestOwnerHashDefinition;
44			struct RequestOwnerHashTable;
45
46			void				_Finisher();
47			bool				_FinisherWorkPending();
48			off_t				_ComputeRequestOwnerBandwidth(
49									int32 priority) const;
50			bool				_NextActiveRequestOwner(IORequestOwner*& owner,
51									off_t& quantum);
52			bool				_PrepareRequestOperations(IORequest* request,
53									IOOperationList& operations,
54									int32& operationsPrepared);
55			bool				_PrepareRequestOperations(IORequest* request,
56									IOOperationList& operations,
57									int32& operationsPrepared, off_t quantum,
58									off_t& usedBandwidth);
59			void				_SortOperations(IOOperationList& operations,
60									off_t& lastOffset);
61			status_t			_Scheduler();
62	static	status_t			_SchedulerThread(void* self);
63			status_t			_RequestNotifier();
64	static	status_t			_RequestNotifierThread(void* self);
65
66			void				_AddRequestOwner(IORequestOwner* owner);
67			IORequestOwner*		_GetRequestOwner(team_id team, thread_id thread,
68									bool allocate);
69
70private:
71			spinlock			fFinisherLock;
72			mutex				fLock;
73			thread_id			fSchedulerThread;
74			thread_id			fRequestNotifierThread;
75			IORequestList		fUnscheduledRequests;
76			IORequestList		fFinishedRequests;
77			ConditionVariable	fNewRequestCondition;
78			ConditionVariable	fFinishedOperationCondition;
79			ConditionVariable	fFinishedRequestCondition;
80			IOOperation**		fOperationArray;
81			IOOperationList		fUnusedOperations;
82			IOOperationList		fCompletedOperations;
83			IORequestOwner*		fAllocatedRequestOwners;
84			int32				fAllocatedRequestOwnerCount;
85			RequestOwnerList	fActiveRequestOwners;
86			RequestOwnerList	fUnusedRequestOwners;
87			RequestOwnerHashTable* fRequestOwners;
88			generic_size_t		fBlockSize;
89			int32				fPendingOperations;
90			off_t				fIterationBandwidth;
91			off_t				fMinOwnerBandwidth;
92			off_t				fMaxOwnerBandwidth;
93	volatile bool				fTerminating;
94};
95
96
97#endif	// IO_SCHEDULER_SIMPLE_H
98