haiku/headers/private/kernel/scheduling_analysis.h
Ingo Weinhold 020ac56840 * Fixed bug in the "scheduler" command: The check when a thread was
unscheduled was incorrect.
* Introduced _kern_analyze_scheduling() syscall. It requires scheduler
  kernel tracing to be enabled. It uses the tracing entries for a given
  period of time to do a similar analysis the "scheduler" debugger
  command does (i.e. number of runs, run time, latencies, preemption
  times) for each thread. Additionally the analysis includes for each
  thread how long the thread waited on each locking primitive in total.
* Added kernel tracing for the creation of semaphores and initialization
  of condition variables, mutexes, and rw locks. The enabling macro is
  SCHEDULING_ANALYSIS_TRACING. The only purpose is to provide
  _kern_analyze_scheduling() with more info on the locking primitives
  (the name in particular).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27304 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-09-03 15:10:44 +00:00

194 lines
3.2 KiB
C++

/*
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_SCHEDULING_ANALYSIS_H
#define _KERNEL_SCHEDULING_ANALYSIS_H
#include <tracing.h>
#include <thread_defs.h>
class ConditionVariable;
struct mutex;
struct rw_lock;
#if SCHEDULING_ANALYSIS_TRACING
namespace SchedulingAnalysisTracing {
class WaitObjectTraceEntry : public AbstractTraceEntry {
public:
virtual uint32 Type() const = 0;
virtual void* Object() const = 0;
virtual const char* Name() const = 0;
virtual void* ReferencedObject() const
{
return NULL;
}
};
class CreateSemaphore : public WaitObjectTraceEntry {
public:
CreateSemaphore(sem_id id, const char* name)
:
fID(id),
fName(alloc_tracing_buffer_strcpy(name, 128, false))
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("sem create \"%s\" -> %ld", fName, fID);
}
virtual uint32 Type() const
{
return THREAD_BLOCK_TYPE_SEMAPHORE;
}
virtual void* Object() const
{
return (void*)(addr_t)fID;
}
virtual const char* Name() const
{
return fName;
}
private:
sem_id fID;
const char* fName;
};
class InitConditionVariable : public WaitObjectTraceEntry {
public:
InitConditionVariable(ConditionVariable* variable, const void* object,
const char* objectType)
:
fVariable(variable),
fObject(object),
fObjectType(alloc_tracing_buffer_strcpy(objectType, 128, false))
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("cvar init variable %p: object: %p \"%s\"", fVariable,
fObject, fObjectType);
}
virtual uint32 Type() const
{
return THREAD_BLOCK_TYPE_CONDITION_VARIABLE;
}
virtual void* Object() const
{
return fVariable;
}
virtual const char* Name() const
{
return fObjectType;
}
virtual void* ReferencedObject() const
{
return (void*)fObject;
}
private:
ConditionVariable* fVariable;
const void* fObject;
const char* fObjectType;
};
class InitMutex : public WaitObjectTraceEntry {
public:
InitMutex(mutex* lock, const char* name)
:
fMutex(lock),
fName(alloc_tracing_buffer_strcpy(name, 128, false))
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("mutex init %p: name: \"%s\"", fMutex, fName);
}
virtual uint32 Type() const
{
return THREAD_BLOCK_TYPE_MUTEX;
}
virtual void* Object() const
{
return fMutex;
}
virtual const char* Name() const
{
return fName;
}
private:
mutex* fMutex;
const char* fName;
};
class InitRWLock : public WaitObjectTraceEntry {
public:
InitRWLock(rw_lock* lock, const char* name)
:
fLock(lock),
fName(alloc_tracing_buffer_strcpy(name, 128, false))
{
Initialized();
}
virtual void AddDump(TraceOutput& out)
{
out.Print("rwlock init %p: name: \"%s\"", fLock, fName);
}
virtual uint32 Type() const
{
return THREAD_BLOCK_TYPE_RW_LOCK;
}
virtual void* Object() const
{
return fLock;
}
virtual const char* Name() const
{
return fName;
}
private:
rw_lock* fLock;
const char* fName;
};
} // namespace SchedulingAnalysisTracing
# define T_SCHEDULING_ANALYSIS(x) \
new(std::nothrow) SchedulingAnalysisTracing::x;
#else
# define T_SCHEDULING_ANALYSIS(x) ;
#endif // SCHEDULING_ANALYSIS_TRACING
#endif // _KERNEL_SCHEDULING_ANALYSIS_H