xref: /haiku/src/system/kernel/device_manager/IOSchedulerRoster.cpp (revision 8f88247e04c71e1fe8079fe4a029c0556e88e314)
1 /*
2  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2024, Haiku, Inc. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "IOSchedulerRoster.h"
9 
10 #include <util/AutoLock.h>
11 
12 
13 /*static*/ IOSchedulerRoster IOSchedulerRoster::sDefaultInstance;
14 
15 
IOSchedulerRoster()16 IOSchedulerRoster::IOSchedulerRoster()
17 	:
18 	fNextID(1),
19 	fNotificationService("I/O")
20 {
21 	mutex_init(&fLock, "IOSchedulerRoster");
22 	fNotificationService.Register();
23 }
24 
25 
~IOSchedulerRoster()26 IOSchedulerRoster::~IOSchedulerRoster()
27 {
28 	mutex_destroy(&fLock);
29 	fNotificationService.Unregister();
30 }
31 
32 
33 void
AddScheduler(IOScheduler * scheduler)34 IOSchedulerRoster::AddScheduler(IOScheduler* scheduler)
35 {
36 	AutoLocker<IOSchedulerRoster> locker(this);
37 	fSchedulers.Add(scheduler);
38 	locker.Unlock();
39 
40 	Notify(IO_SCHEDULER_ADDED, scheduler);
41 }
42 
43 
44 void
RemoveScheduler(IOScheduler * scheduler)45 IOSchedulerRoster::RemoveScheduler(IOScheduler* scheduler)
46 {
47 	AutoLocker<IOSchedulerRoster> locker(this);
48 	fSchedulers.Remove(scheduler);
49 	locker.Unlock();
50 
51 	Notify(IO_SCHEDULER_REMOVED, scheduler);
52 }
53 
54 
55 void
Notify(uint32 eventCode,const IOScheduler * scheduler,IORequest * request,IOOperation * operation)56 IOSchedulerRoster::Notify(uint32 eventCode, const IOScheduler* scheduler,
57 	IORequest* request, IOOperation* operation)
58 {
59 	AutoLocker<DefaultNotificationService> locker(fNotificationService);
60 
61 	if (!fNotificationService.HasListeners())
62 		return;
63 
64 	KMessage event;
65 	event.SetTo(fEventBuffer, sizeof(fEventBuffer), IO_SCHEDULER_MONITOR);
66 	event.AddInt32("event", eventCode);
67 	event.AddPointer("scheduler", scheduler);
68 	if (request != NULL) {
69 		event.AddPointer("request", request);
70 		if (operation != NULL)
71 			event.AddPointer("operation", operation);
72 	}
73 
74 	fNotificationService.NotifyLocked(event, eventCode);
75 }
76 
77 
78 int32
NextID()79 IOSchedulerRoster::NextID()
80 {
81 	AutoLocker<IOSchedulerRoster> locker(this);
82 	return fNextID++;
83 }
84 
85 
86 //	#pragma mark - debug methods and initialization
87 
88 
89 void
Dump() const90 IOSchedulerRoster::Dump() const
91 {
92 	kprintf("IOSchedulerRoster at %p\n", this);
93 	kprintf("  mutex:   %p\n", &fLock);
94 	kprintf("  next ID: %" B_PRId32 "\n", fNextID);
95 
96 	kprintf("  schedulers:");
97 	for (IOSchedulerList::ConstIterator it
98 				= fSchedulers.GetIterator();
99 			IOScheduler* scheduler = it.Next();) {
100 		kprintf(" %p", scheduler);
101 	}
102 	kprintf("\n");
103 }
104 
105 
106 static int
dump_io_scheduler_roster(int argc,char ** argv)107 dump_io_scheduler_roster(int argc, char** argv)
108 {
109 	IOSchedulerRoster* roster;
110 	if (argc == 1) {
111 		roster = IOSchedulerRoster::Default();
112 	} else if (argc == 2) {
113 		roster = (IOSchedulerRoster*)parse_expression(argv[1]);
114 		if (roster == NULL)
115 			return -1;
116 	} else {
117 		print_debugger_command_usage(argv[0]);
118 		return 0;
119 	}
120 
121 	roster->Dump();
122 	return 0;
123 }
124 
125 
126 static int
dump_io_scheduler(int argc,char ** argv)127 dump_io_scheduler(int argc, char** argv)
128 {
129 	if (argc != 2) {
130 		print_debugger_command_usage(argv[0]);
131 		return 0;
132 	}
133 
134 	IOScheduler* scheduler = (IOScheduler*)parse_expression(argv[1]);
135 	scheduler->Dump();
136 	return 0;
137 }
138 
139 
140 static int
dump_io_request_owner(int argc,char ** argv)141 dump_io_request_owner(int argc, char** argv)
142 {
143 	if (argc != 2) {
144 		print_debugger_command_usage(argv[0]);
145 		return 0;
146 	}
147 
148 	IORequestOwner* owner = (IORequestOwner*)parse_expression(argv[1]);
149 	owner->Dump();
150 	return 0;
151 }
152 
153 
154 static int
dump_io_request(int argc,char ** argv)155 dump_io_request(int argc, char** argv)
156 {
157 	if (argc != 2 || !strcmp(argv[1], "--help")) {
158 		kprintf("usage: %s <ptr-to-io-request>\n", argv[0]);
159 		return 0;
160 	}
161 
162 	IORequest* request = (IORequest*)parse_expression(argv[1]);
163 	request->Dump();
164 	return 0;
165 }
166 
167 
168 static int
dump_io_operation(int argc,char ** argv)169 dump_io_operation(int argc, char** argv)
170 {
171 	if (argc != 2 || !strcmp(argv[1], "--help")) {
172 		kprintf("usage: %s <ptr-to-io-operation>\n", argv[0]);
173 		return 0;
174 	}
175 
176 	IOOperation* operation = (IOOperation*)parse_expression(argv[1]);
177 	operation->Dump();
178 	return 0;
179 }
180 
181 
182 static int
dump_io_buffer(int argc,char ** argv)183 dump_io_buffer(int argc, char** argv)
184 {
185 	if (argc != 2 || !strcmp(argv[1], "--help")) {
186 		kprintf("usage: %s <ptr-to-io-buffer>\n", argv[0]);
187 		return 0;
188 	}
189 
190 	IOBuffer* buffer = (IOBuffer*)parse_expression(argv[1]);
191 	buffer->Dump();
192 	return 0;
193 }
194 
195 
196 static int
dump_dma_buffer(int argc,char ** argv)197 dump_dma_buffer(int argc, char** argv)
198 {
199 	if (argc != 2 || !strcmp(argv[1], "--help")) {
200 		kprintf("usage: %s <ptr-to-dma-buffer>\n", argv[0]);
201 		return 0;
202 	}
203 
204 	DMABuffer* buffer = (DMABuffer*)parse_expression(argv[1]);
205 	buffer->Dump();
206 	return 0;
207 }
208 
209 
210 /*static*/ void
Init()211 IOSchedulerRoster::Init()
212 {
213 	new(&sDefaultInstance) IOSchedulerRoster;
214 
215 	add_debugger_command_etc("io_scheduler_roster", &dump_io_scheduler_roster,
216 		"Dump an I/O scheduler roster",
217 		"<scheduler-roster>\n"
218 		"Dumps I/O scheduler roster at address <scheduler-roster>.\n"
219 		"If unspecified, dump the default roster.\n", 0);
220 	add_debugger_command_etc("io_scheduler", &dump_io_scheduler,
221 		"Dump an I/O scheduler",
222 		"<scheduler>\n"
223 		"Dumps I/O scheduler at address <scheduler>.\n", 0);
224 	add_debugger_command_etc("io_request_owner", &dump_io_request_owner,
225 		"Dump an I/O request owner",
226 		"<owner>\n"
227 		"Dumps I/O request owner at address <owner>.\n", 0);
228 	add_debugger_command("io_request", &dump_io_request, "dump an I/O request");
229 	add_debugger_command("io_operation", &dump_io_operation,
230 		"dump an I/O operation");
231 	add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer");
232 	add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer");
233 }
234