1/*
2 * Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2007, Axel D��rfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef KERNEL_SCHEDULER_TRACING_H
7#define KERNEL_SCHEDULER_TRACING_H
8
9
10#include <arch/debug.h>
11#include <cpu.h>
12#include <thread.h>
13#include <tracing.h>
14
15
16#if SCHEDULER_TRACING
17
18namespace SchedulerTracing {
19
20class SchedulerTraceEntry : public AbstractTraceEntry {
21public:
22	SchedulerTraceEntry(Thread* thread)
23		:
24		fID(thread->id)
25	{
26	}
27
28	thread_id ThreadID() const	{ return fID; }
29
30	virtual const char* Name() const = 0;
31
32protected:
33	thread_id			fID;
34};
35
36
37class EnqueueThread : public SchedulerTraceEntry {
38public:
39	EnqueueThread(Thread* thread, Thread* previous, Thread* next)
40		:
41		SchedulerTraceEntry(thread),
42		fPreviousID(-1),
43		fNextID(-1),
44		fPriority(thread->priority)
45	{
46		if (previous != NULL)
47			fPreviousID = previous->id;
48		if (next != NULL)
49			fNextID = next->id;
50		fName = alloc_tracing_buffer_strcpy(thread->name, B_OS_NAME_LENGTH,
51			false);
52		Initialized();
53	}
54
55	virtual void AddDump(TraceOutput& out);
56
57	virtual const char* Name() const;
58
59private:
60	thread_id			fPreviousID;
61	thread_id			fNextID;
62	char*				fName;
63	uint8				fPriority;
64};
65
66
67class RemoveThread : public SchedulerTraceEntry {
68public:
69	RemoveThread(Thread* thread)
70		:
71		SchedulerTraceEntry(thread),
72		fPriority(thread->priority)
73	{
74		Initialized();
75	}
76
77	virtual void AddDump(TraceOutput& out);
78
79	virtual const char* Name() const;
80
81private:
82	uint8				fPriority;
83};
84
85
86class ScheduleThread : public SchedulerTraceEntry {
87public:
88	ScheduleThread(Thread* thread, Thread* previous)
89		:
90		SchedulerTraceEntry(thread),
91		fPreviousID(previous->id),
92		fCPU(previous->cpu->cpu_num),
93		fPriority(thread->priority),
94		fPreviousState(previous->state),
95		fPreviousWaitObjectType(previous->wait.type)
96	{
97		fName = alloc_tracing_buffer_strcpy(thread->name, B_OS_NAME_LENGTH,
98			false);
99
100#if SCHEDULER_TRACING >= 2
101		if (fPreviousState == B_THREAD_READY)
102			fPreviousPC = arch_debug_get_interrupt_pc(NULL);
103		else
104#endif
105			fPreviousWaitObject = previous->wait.object;
106
107		Initialized();
108	}
109
110	virtual void AddDump(TraceOutput& out);
111
112	virtual const char* Name() const;
113
114	thread_id PreviousThreadID() const		{ return fPreviousID; }
115	uint8 PreviousState() const				{ return fPreviousState; }
116	uint16 PreviousWaitObjectType() const	{ return fPreviousWaitObjectType; }
117	const void* PreviousWaitObject() const	{ return fPreviousWaitObject; }
118
119private:
120	thread_id			fPreviousID;
121	int32				fCPU;
122	char*				fName;
123	uint8				fPriority;
124	uint8				fPreviousState;
125	uint16				fPreviousWaitObjectType;
126	union {
127		const void*		fPreviousWaitObject;
128		void*			fPreviousPC;
129	};
130};
131
132}	// namespace SchedulerTracing
133
134#	define T(x) new(std::nothrow) SchedulerTracing::x;
135#else
136#	define T(x) ;
137#endif
138
139
140#if SCHEDULER_TRACING
141
142namespace SchedulerTracing {
143
144enum ScheduleState {
145	RUNNING,
146	STILL_RUNNING,
147	PREEMPTED,
148	READY,
149	WAITING,
150	UNKNOWN
151};
152
153}
154
155int cmd_scheduler(int argc, char** argv);
156
157#endif	// SCHEDULER_TRACING
158
159#endif	// KERNEL_SCHEDULER_TRACING_H
160