/* * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2024, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #include "IOSchedulerRoster.h" #include /*static*/ IOSchedulerRoster IOSchedulerRoster::sDefaultInstance; IOSchedulerRoster::IOSchedulerRoster() : fNextID(1), fNotificationService("I/O") { mutex_init(&fLock, "IOSchedulerRoster"); fNotificationService.Register(); } IOSchedulerRoster::~IOSchedulerRoster() { mutex_destroy(&fLock); fNotificationService.Unregister(); } void IOSchedulerRoster::AddScheduler(IOScheduler* scheduler) { AutoLocker locker(this); fSchedulers.Add(scheduler); locker.Unlock(); Notify(IO_SCHEDULER_ADDED, scheduler); } void IOSchedulerRoster::RemoveScheduler(IOScheduler* scheduler) { AutoLocker locker(this); fSchedulers.Remove(scheduler); locker.Unlock(); Notify(IO_SCHEDULER_REMOVED, scheduler); } void IOSchedulerRoster::Notify(uint32 eventCode, const IOScheduler* scheduler, IORequest* request, IOOperation* operation) { AutoLocker locker(fNotificationService); if (!fNotificationService.HasListeners()) return; KMessage event; event.SetTo(fEventBuffer, sizeof(fEventBuffer), IO_SCHEDULER_MONITOR); event.AddInt32("event", eventCode); event.AddPointer("scheduler", scheduler); if (request != NULL) { event.AddPointer("request", request); if (operation != NULL) event.AddPointer("operation", operation); } fNotificationService.NotifyLocked(event, eventCode); } int32 IOSchedulerRoster::NextID() { AutoLocker locker(this); return fNextID++; } // #pragma mark - debug methods and initialization void IOSchedulerRoster::Dump() const { kprintf("IOSchedulerRoster at %p\n", this); kprintf(" mutex: %p\n", &fLock); kprintf(" next ID: %" B_PRId32 "\n", fNextID); kprintf(" schedulers:"); for (IOSchedulerList::ConstIterator it = fSchedulers.GetIterator(); IOScheduler* scheduler = it.Next();) { kprintf(" %p", scheduler); } kprintf("\n"); } static int dump_io_scheduler_roster(int argc, char** argv) { IOSchedulerRoster* roster; if (argc == 1) { roster = IOSchedulerRoster::Default(); } else if (argc == 2) { roster = (IOSchedulerRoster*)parse_expression(argv[1]); if (roster == NULL) return -1; } else { print_debugger_command_usage(argv[0]); return 0; } roster->Dump(); return 0; } static int dump_io_scheduler(int argc, char** argv) { if (argc != 2) { print_debugger_command_usage(argv[0]); return 0; } IOScheduler* scheduler = (IOScheduler*)parse_expression(argv[1]); scheduler->Dump(); return 0; } static int dump_io_request_owner(int argc, char** argv) { if (argc != 2) { print_debugger_command_usage(argv[0]); return 0; } IORequestOwner* owner = (IORequestOwner*)parse_expression(argv[1]); owner->Dump(); return 0; } static int dump_io_request(int argc, char** argv) { if (argc != 2 || !strcmp(argv[1], "--help")) { kprintf("usage: %s \n", argv[0]); return 0; } IORequest* request = (IORequest*)parse_expression(argv[1]); request->Dump(); return 0; } static int dump_io_operation(int argc, char** argv) { if (argc != 2 || !strcmp(argv[1], "--help")) { kprintf("usage: %s \n", argv[0]); return 0; } IOOperation* operation = (IOOperation*)parse_expression(argv[1]); operation->Dump(); return 0; } static int dump_io_buffer(int argc, char** argv) { if (argc != 2 || !strcmp(argv[1], "--help")) { kprintf("usage: %s \n", argv[0]); return 0; } IOBuffer* buffer = (IOBuffer*)parse_expression(argv[1]); buffer->Dump(); return 0; } static int dump_dma_buffer(int argc, char** argv) { if (argc != 2 || !strcmp(argv[1], "--help")) { kprintf("usage: %s \n", argv[0]); return 0; } DMABuffer* buffer = (DMABuffer*)parse_expression(argv[1]); buffer->Dump(); return 0; } /*static*/ void IOSchedulerRoster::Init() { new(&sDefaultInstance) IOSchedulerRoster; add_debugger_command_etc("io_scheduler_roster", &dump_io_scheduler_roster, "Dump an I/O scheduler roster", "\n" "Dumps I/O scheduler roster at address .\n" "If unspecified, dump the default roster.\n", 0); add_debugger_command_etc("io_scheduler", &dump_io_scheduler, "Dump an I/O scheduler", "\n" "Dumps I/O scheduler at address .\n", 0); add_debugger_command_etc("io_request_owner", &dump_io_request_owner, "Dump an I/O request owner", "\n" "Dumps I/O request owner at address .\n", 0); add_debugger_command("io_request", &dump_io_request, "dump an I/O request"); add_debugger_command("io_operation", &dump_io_operation, "dump an I/O operation"); add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer"); }