[haiku-commits] r34703 - in haiku/trunk: headers/private/system src/system/kernel/debug

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 19 Dec 2009 15:33:29 +0100 (CET)

Author: bonefish
Date: 2009-12-19 15:33:29 +0100 (Sat, 19 Dec 2009)
New Revision: 34703
Changeset: http://dev.haiku-os.org/changeset/34703/haiku

Modified:
   haiku/trunk/headers/private/system/system_profiler_defs.h
   haiku/trunk/src/system/kernel/debug/system_profiler.cpp
Log:
Added support for I/O scheduling events to the system profiler interface.


Modified: haiku/trunk/headers/private/system/system_profiler_defs.h
===================================================================
--- haiku/trunk/headers/private/system/system_profiler_defs.h   2009-12-19 
14:32:14 UTC (rev 34702)
+++ haiku/trunk/headers/private/system/system_profiler_defs.h   2009-12-19 
14:33:29 UTC (rev 34703)
@@ -26,11 +26,12 @@
 
 // event flags
 enum {
-       B_SYSTEM_PROFILER_TEAM_EVENTS           = 0x01,
-       B_SYSTEM_PROFILER_THREAD_EVENTS         = 0x02,
-       B_SYSTEM_PROFILER_IMAGE_EVENTS          = 0x04,
-       B_SYSTEM_PROFILER_SAMPLING_EVENTS       = 0x08,
-       B_SYSTEM_PROFILER_SCHEDULING_EVENTS     = 0x10
+       B_SYSTEM_PROFILER_TEAM_EVENTS                   = 0x01,
+       B_SYSTEM_PROFILER_THREAD_EVENTS                 = 0x02,
+       B_SYSTEM_PROFILER_IMAGE_EVENTS                  = 0x04,
+       B_SYSTEM_PROFILER_SAMPLING_EVENTS               = 0x08,
+       B_SYSTEM_PROFILER_SCHEDULING_EVENTS             = 0x10,
+       B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS  = 0x20
 };
 
 
@@ -62,7 +63,15 @@
        B_SYSTEM_PROFILER_THREAD_SCHEDULED,
        B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE,
        B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE,
-       B_SYSTEM_PROFILER_WAIT_OBJECT_INFO
+       B_SYSTEM_PROFILER_WAIT_OBJECT_INFO,
+
+       // I/O scheduling
+       B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED,
+       B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED,
+       B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED,
+       B_SYSTEM_PROFILER_IO_REQUEST_FINISHED,
+       B_SYSTEM_PROFILER_IO_OPERATION_STARTED,
+       B_SYSTEM_PROFILER_IO_OPERATION_FINISHED
 };
 
 
@@ -166,5 +175,59 @@
        char            name[1];
 };
 
+// B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED
+struct system_profiler_io_scheduler_added {
+       int32           scheduler;
+       char            name[1];
+};
 
+// B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED
+struct system_profiler_io_scheduler_removed {
+       int32           scheduler;
+};
+
+// B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED
+struct system_profiler_io_request_scheduled {
+       nanotime_t      time;
+       int32           scheduler;
+       team_id         team;
+       thread_id       thread;
+       void*           request;
+       off_t           offset;
+       size_t          length;
+       bool            write;
+       uint8           priority;
+};
+
+// B_SYSTEM_PROFILER_IO_REQUEST_FINISHED
+struct system_profiler_io_request_finished {
+       nanotime_t      time;
+       int32           scheduler;
+       void*           request;
+       status_t        status;
+       size_t          transferred;
+};
+
+// B_SYSTEM_PROFILER_IO_OPERATION_STARTED
+struct system_profiler_io_operation_started {
+       nanotime_t      time;
+       int32           scheduler;
+       void*           request;
+       void*           operation;
+       off_t           offset;
+       size_t          length;
+       bool            write;
+};
+
+// B_SYSTEM_PROFILER_IO_OPERATION_FINISHED
+struct system_profiler_io_operation_finished {
+       nanotime_t      time;
+       int32           scheduler;
+       void*           request;
+       void*           operation;
+       status_t        status;
+       size_t          transferred;
+};
+
+
 #endif /* _SYSTEM_SYSTEM_PROFILER_DEFS_H */

Modified: haiku/trunk/src/system/kernel/debug/system_profiler.cpp
===================================================================
--- haiku/trunk/src/system/kernel/debug/system_profiler.cpp     2009-12-19 
14:32:14 UTC (rev 34702)
+++ haiku/trunk/src/system/kernel/debug/system_profiler.cpp     2009-12-19 
14:33:29 UTC (rev 34703)
@@ -27,11 +27,14 @@
 
 #include <arch/debug.h>
 
+#include "IOScheduler.h"
 
+
 // This is the kernel-side implementation of the system profiling support.
 // A userland team can register as system profiler, providing an area as buffer
-// for events. Those events are team, thread, and image changes (added/removed)
-// and periodic sampling of the return address stack for each CPU.
+// for events. Those events are team, thread, and image changes 
(added/removed),
+// periodic sampling of the return address stack for each CPU, as well as
+// scheduling and I/O scheduling events.
 
 
 class SystemProfiler;
@@ -89,6 +92,17 @@
                        bool                            _ImageAdded(struct 
image* image);
                        bool                            _ImageRemoved(struct 
image* image);
 
+                       bool                            
_IOSchedulerAdded(IOScheduler* scheduler);
+                       bool                            
_IOSchedulerRemoved(IOScheduler* scheduler);
+                       bool                            
_IORequestScheduled(IOScheduler* scheduler,
+                                                                       
IORequest* request);
+                       bool                            
_IORequestFinished(IOScheduler* scheduler,
+                                                                       
IORequest* request);
+                       bool                            
_IOOperationStarted(IOScheduler* scheduler,
+                                                                       
IORequest* request, IOOperation* operation);
+                       bool                            
_IOOperationFinished(IOScheduler* scheduler,
+                                                                       
IORequest* request, IOOperation* operation);
+
                        void                            
_WaitObjectCreated(addr_t object, uint32 type);
                        void                            _WaitObjectUsed(addr_t 
object, uint32 type);
 
@@ -182,6 +196,8 @@
                        bool                            
fThreadNotificationsEnabled;
                        bool                            
fImageNotificationsRequested;
                        bool                            
fImageNotificationsEnabled;
+                       bool                            
fIONotificationsRequested;
+                       bool                            fIONotificationsEnabled;
                        bool                            
fSchedulerNotificationsRequested;
                        bool                            
fWaitObjectNotificationsRequested;
                        ConditionVariable       fProfilerWaitCondition;
@@ -247,6 +263,8 @@
        fThreadNotificationsEnabled(false),
        fImageNotificationsRequested(false),
        fImageNotificationsEnabled(false),
+       fIONotificationsRequested(false),
+       fIONotificationsEnabled(false),
        fSchedulerNotificationsRequested(false),
        fWaitObjectNotificationsRequested(false),
        fProfilerWaiting(false),
@@ -323,6 +341,12 @@
                notificationManager.RemoveListener("teams", NULL, *this);
        }
 
+       // I/O
+       if (fIONotificationsRequested) {
+               fIONotificationsRequested = false;
+               notificationManager.RemoveListener("I/O", NULL, *this);
+       }
+
        // delete wait object related allocations
        fWaitObjectTable.Clear();
        delete[] fWaitObjectBuffer;
@@ -407,6 +431,19 @@
                fImageNotificationsRequested = true;
        }
 
+       // I/O events
+       if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
+               error = notificationManager.AddListener("I/O",
+                       IO_SCHEDULER_ADDED | IO_SCHEDULER_REMOVED
+                               | IO_SCHEDULER_REQUEST_SCHEDULED | 
IO_SCHEDULER_REQUEST_FINISHED
+                               | IO_SCHEDULER_OPERATION_STARTED
+                               | IO_SCHEDULER_OPERATION_FINISHED,
+                       *this);
+               if (error != B_OK)
+                       return error;
+               fIONotificationsRequested = true;
+       }
+
        // We need to fill the buffer with the initial state of teams, threads,
        // and images.
 
@@ -463,6 +500,20 @@
 
        threadsLocker.Unlock();
 
+       // I/O scheduling
+       if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
+               IOSchedulerRoster* roster = IOSchedulerRoster::Default();
+               AutoLocker<IOSchedulerRoster> rosterLocker(roster);
+
+               for (IOSchedulerList::ConstIterator it
+                               = roster->SchedulerList().GetIterator();
+                       IOScheduler* scheduler = it.Next();) {
+                       _IOSchedulerAdded(scheduler);
+               }
+
+               fIONotificationsEnabled = true;
+       }
+
        // activate the profiling timers on all CPUs
        if ((fFlags & B_SYSTEM_PROFILER_SAMPLING_EVENTS) != 0)
                call_all_cpus(_InitTimers, this);
@@ -606,6 +657,44 @@
                                _ImageRemoved(image);
                                break;
                }
+       } else if (strcmp(service.Name(), "I/O") == 0) {
+               if (!fIONotificationsEnabled)
+                       return;
+
+               IOScheduler* scheduler = 
(IOScheduler*)event->GetPointer("scheduler",
+                       NULL);
+               if (scheduler == NULL)
+                       return;
+
+               IORequest* request = (IORequest*)event->GetPointer("request", 
NULL);
+               IOOperation* operation = 
(IOOperation*)event->GetPointer("operation",
+                       NULL);
+
+               switch (eventCode) {
+                       case IO_SCHEDULER_ADDED:
+                               _IOSchedulerAdded(scheduler);
+                               break;
+
+                       case IO_SCHEDULER_REMOVED:
+                               _IOSchedulerRemoved(scheduler);
+                               break;
+
+                       case IO_SCHEDULER_REQUEST_SCHEDULED:
+                               _IORequestScheduled(scheduler, request);
+                               break;
+
+                       case IO_SCHEDULER_REQUEST_FINISHED:
+                               _IORequestFinished(scheduler, request);
+                               break;
+
+                       case IO_SCHEDULER_OPERATION_STARTED:
+                               _IOOperationStarted(scheduler, request, 
operation);
+                               break;
+
+                       case IO_SCHEDULER_OPERATION_FINISHED:
+                               _IOOperationFinished(scheduler, request, 
operation);
+                               break;
+               }
        }
 
        _MaybeNotifyProfilerThread();
@@ -734,11 +823,11 @@
 bool
 SystemProfiler::_TeamAdded(struct team* team)
 {
-       InterruptsSpinLocker locker(fLock);
-
        size_t nameLen = strlen(team->name);
        size_t argsLen = strlen(team->args);
 
+       InterruptsSpinLocker locker(fLock);
+
        system_profiler_team_added* event = (system_profiler_team_added*)
                _AllocateBuffer(
                        sizeof(system_profiler_team_added) + nameLen + 1 + 
argsLen,
@@ -779,10 +868,10 @@
 bool
 SystemProfiler::_TeamExec(struct team* team)
 {
+       size_t argsLen = strlen(team->args);
+
        InterruptsSpinLocker locker(fLock);
 
-       size_t argsLen = strlen(team->args);
-
        system_profiler_team_exec* event = (system_profiler_team_exec*)
                _AllocateBuffer(sizeof(system_profiler_team_exec) + argsLen,
                        B_SYSTEM_PROFILER_TEAM_EXEC, 0, 0);
@@ -882,6 +971,156 @@
 }
 
 
+bool
+SystemProfiler::_IOSchedulerAdded(IOScheduler* scheduler)
+{
+       size_t nameLen = strlen(scheduler->Name());
+
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_scheduler_added* event
+               = (system_profiler_io_scheduler_added*)_AllocateBuffer(
+                       sizeof(system_profiler_io_scheduler_added) + nameLen,
+                       B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       event->scheduler = scheduler->ID();
+       strcpy(event->name, scheduler->Name());
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
+bool
+SystemProfiler::_IOSchedulerRemoved(IOScheduler* scheduler)
+{
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_scheduler_removed* event
+               = (system_profiler_io_scheduler_removed*)_AllocateBuffer(
+                       sizeof(system_profiler_io_scheduler_removed),
+                       B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       event->scheduler = scheduler->ID();
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
+bool
+SystemProfiler::_IORequestScheduled(IOScheduler* scheduler, IORequest* request)
+{
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_request_scheduled* event
+               = (system_profiler_io_request_scheduled*)_AllocateBuffer(
+                       sizeof(system_profiler_io_request_scheduled),
+                       B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       IORequestOwner* owner = request->Owner();
+
+       event->time = system_time_nsecs();
+       event->scheduler = scheduler->ID();
+       event->team = owner->team;
+       event->thread = owner->thread;
+       event->request = request;
+       event->offset = request->Offset();
+       event->length = request->Length();
+       event->write = request->IsWrite();
+       event->priority = owner->priority;
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
+bool
+SystemProfiler::_IORequestFinished(IOScheduler* scheduler, IORequest* request)
+{
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_request_finished* event
+               = (system_profiler_io_request_finished*)_AllocateBuffer(
+                       sizeof(system_profiler_io_request_finished),
+                       B_SYSTEM_PROFILER_IO_REQUEST_FINISHED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       event->time = system_time_nsecs();
+       event->scheduler = scheduler->ID();
+       event->request = request;
+       event->status = request->Status();
+       event->transferred = request->TransferredBytes();
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
+bool
+SystemProfiler::_IOOperationStarted(IOScheduler* scheduler, IORequest* request,
+       IOOperation* operation)
+{
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_operation_started* event
+               = (system_profiler_io_operation_started*)_AllocateBuffer(
+                       sizeof(system_profiler_io_operation_started),
+                       B_SYSTEM_PROFILER_IO_OPERATION_STARTED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       event->time = system_time_nsecs();
+       event->scheduler = scheduler->ID();
+       event->request = request;
+       event->operation = operation;
+       event->offset = request->Offset();
+       event->length = request->Length();
+       event->write = request->IsWrite();
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
+bool
+SystemProfiler::_IOOperationFinished(IOScheduler* scheduler, IORequest* 
request,
+       IOOperation* operation)
+{
+       InterruptsSpinLocker locker(fLock);
+
+       system_profiler_io_operation_finished* event
+               = (system_profiler_io_operation_finished*)_AllocateBuffer(
+                       sizeof(system_profiler_io_operation_finished),
+                       B_SYSTEM_PROFILER_IO_OPERATION_FINISHED, 0, 0);
+       if (event == NULL)
+               return false;
+
+       event->time = system_time_nsecs();
+       event->scheduler = scheduler->ID();
+       event->request = request;
+       event->operation = operation;
+       event->status = request->Status();
+       event->transferred = request->TransferredBytes();
+
+       fHeader->size = fBufferSize;
+
+       return true;
+}
+
+
 void
 SystemProfiler::_WaitObjectCreated(addr_t object, uint32 type)
 {
@@ -1188,6 +1427,7 @@
        sRecordedParameters->buffer_area = area;
        sRecordedParameters->flags = B_SYSTEM_PROFILER_TEAM_EVENTS
                | B_SYSTEM_PROFILER_THREAD_EVENTS | 
B_SYSTEM_PROFILER_IMAGE_EVENTS
+               | B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS
                | B_SYSTEM_PROFILER_SAMPLING_EVENTS;
        sRecordedParameters->locking_lookup_size = 4096;
        sRecordedParameters->interval = interval;


Other related posts:

  • » [haiku-commits] r34703 - in haiku/trunk: headers/private/system src/system/kernel/debug - ingo_weinhold