* Added tracing support to our scheduler to be able to do better diagnosis
with scheduling problems. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26929 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
#define NET_BUFFER_TRACING 0
|
#define NET_BUFFER_TRACING 0
|
||||||
#define NET_BUFFER_TRACING_STACK_TRACE 0 /* stack trace depth */
|
#define NET_BUFFER_TRACING_STACK_TRACE 0 /* stack trace depth */
|
||||||
#define RUNTIME_LOADER_TRACING 0
|
#define RUNTIME_LOADER_TRACING 0
|
||||||
|
#define SCHEDULER_TRACING 0
|
||||||
#define SIGNAL_TRACING 0
|
#define SIGNAL_TRACING 0
|
||||||
#define SYSCALL_TRACING 0
|
#define SYSCALL_TRACING 0
|
||||||
#define SYSCALL_TRACING_IGNORE_KTRACE_OUTPUT 1
|
#define SYSCALL_TRACING_IGNORE_KTRACE_OUTPUT 1
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <smp.h>
|
#include <smp.h>
|
||||||
#include <cpu.h>
|
#include <cpu.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <tracing.h>
|
||||||
#include <util/khash.h>
|
#include <util/khash.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -30,6 +31,98 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if SCHEDULER_TRACING
|
||||||
|
namespace SchedulerTracing {
|
||||||
|
|
||||||
|
class EnqueueThread : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
EnqueueThread(struct thread* thread, struct thread* previous,
|
||||||
|
struct thread* next)
|
||||||
|
:
|
||||||
|
fID(thread->id),
|
||||||
|
fPreviousID(-1),
|
||||||
|
fNextID(-1),
|
||||||
|
fPriority(thread->priority)
|
||||||
|
{
|
||||||
|
if (previous != NULL)
|
||||||
|
fPreviousID = previous->id;
|
||||||
|
if (next != NULL)
|
||||||
|
fNextID = next->id;
|
||||||
|
fName = alloc_tracing_buffer_strcpy(thread->name, B_OS_NAME_LENGTH,
|
||||||
|
false);
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(TraceOutput& out)
|
||||||
|
{
|
||||||
|
out.Print("scheduler enqueue %ld \"%s\", priority %d (previous %ld, "
|
||||||
|
"next %ld)", fID, fName, fPriority, fPreviousID, fNextID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fID;
|
||||||
|
thread_id fPreviousID;
|
||||||
|
thread_id fNextID;
|
||||||
|
char* fName;
|
||||||
|
uint8 fPriority;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RemoveThread : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
RemoveThread(struct thread* thread)
|
||||||
|
:
|
||||||
|
fID(thread->id),
|
||||||
|
fPriority(thread->priority)
|
||||||
|
{
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(TraceOutput& out)
|
||||||
|
{
|
||||||
|
out.Print("scheduler remove %ld, priority %d", fID, fPriority);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fID;
|
||||||
|
uint8 fPriority;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScheduleThread : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
ScheduleThread(struct thread* thread, struct thread* previous)
|
||||||
|
:
|
||||||
|
fID(thread->id),
|
||||||
|
fPreviousID(previous->id),
|
||||||
|
fCPU(previous->cpu->cpu_num),
|
||||||
|
fPriority(thread->priority)
|
||||||
|
{
|
||||||
|
fName = alloc_tracing_buffer_strcpy(thread->name, B_OS_NAME_LENGTH,
|
||||||
|
false);
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(TraceOutput& out)
|
||||||
|
{
|
||||||
|
out.Print("schedule %ld \"%s\", priority %d (from %ld, CPU %ld)", fID,
|
||||||
|
fName, fPriority, fPreviousID, fCPU);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fID;
|
||||||
|
thread_id fPreviousID;
|
||||||
|
int32 fCPU;
|
||||||
|
char* fName;
|
||||||
|
uint8 fPriority;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SchedulerTracing
|
||||||
|
|
||||||
|
# define T(x) new(std::nothrow) SchedulerTracing::x;
|
||||||
|
#else
|
||||||
|
# define T(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// The run queue. Holds the threads ready to run ordered by priority.
|
// The run queue. Holds the threads ready to run ordered by priority.
|
||||||
static struct thread *sRunQueue = NULL;
|
static struct thread *sRunQueue = NULL;
|
||||||
|
|
||||||
@@ -94,6 +187,8 @@ scheduler_enqueue_in_run_queue(struct thread *thread)
|
|||||||
prev = sRunQueue;
|
prev = sRunQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T(EnqueueThread(thread, prev, curr));
|
||||||
|
|
||||||
thread->queue_next = curr;
|
thread->queue_next = curr;
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->queue_next = thread;
|
prev->queue_next = thread;
|
||||||
@@ -112,6 +207,8 @@ scheduler_remove_from_run_queue(struct thread *thread)
|
|||||||
{
|
{
|
||||||
struct thread *item, *prev;
|
struct thread *item, *prev;
|
||||||
|
|
||||||
|
T(RemoveThread(thread));
|
||||||
|
|
||||||
// find thread in run queue
|
// find thread in run queue
|
||||||
for (item = sRunQueue, prev = NULL; item && item != thread;
|
for (item = sRunQueue, prev = NULL; item && item != thread;
|
||||||
item = item->queue_next) {
|
item = item->queue_next) {
|
||||||
@@ -246,6 +343,8 @@ scheduler_reschedule(void)
|
|||||||
else
|
else
|
||||||
sRunQueue = nextThread->queue_next;
|
sRunQueue = nextThread->queue_next;
|
||||||
|
|
||||||
|
T(ScheduleThread(nextThread, oldThread));
|
||||||
|
|
||||||
nextThread->state = B_THREAD_RUNNING;
|
nextThread->state = B_THREAD_RUNNING;
|
||||||
nextThread->next_state = B_THREAD_READY;
|
nextThread->next_state = B_THREAD_READY;
|
||||||
oldThread->was_yielded = false;
|
oldThread->was_yielded = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user