Browse Source

- Fixed time line

- implemented ActivateProfiler/DeactivateProfiler

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5198 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 16 years ago
parent
commit
d4066cca92
  1. 2
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
  2. 69
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs
  3. 5
      src/AddIns/Misc/Profiler/Controller/Profiler.cs
  4. 1
      src/AddIns/Misc/Profiler/Controller/structs.cs
  5. 2
      src/AddIns/Misc/Profiler/Hook/LightweightList.cpp
  6. 18
      src/AddIns/Misc/Profiler/Hook/Profiler.cpp
  7. 2
      src/AddIns/Misc/Profiler/Hook/Profiler.h
  8. 2
      src/AddIns/Misc/Profiler/Hook/constants.cpp
  9. 1
      src/AddIns/Misc/Profiler/Hook/global.h
  10. 41
      src/AddIns/Misc/Profiler/Hook/main.cpp

2
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.Profiler.Controller.Data
/// <summary> /// <summary>
/// Creates a new SQLite profiling data provider and opens a database stored in a file. /// Creates a new SQLite profiling data provider and opens a database stored in a file.
/// </summary> /// </summary>
private ProfilingDataSQLiteProvider(string fileName, bool allowUpgrade) ProfilingDataSQLiteProvider(string fileName, bool allowUpgrade)
{ {
this.nameMappingCache = new Dictionary<int, NameMapping>(); this.nameMappingCache = new Dictionary<int, NameMapping>();

69
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs

@ -321,39 +321,48 @@ namespace ICSharpCode.Profiler.Controller.Data
{ {
using (SQLiteTransaction trans = this.connection.BeginTransaction()) { using (SQLiteTransaction trans = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) { using (SQLiteCommand cmd = this.connection.CreateCommand()) {
using (SQLiteCommand cmd2 = this.connection.CreateCommand()) {
SQLiteParameter idParam = new SQLiteParameter("id"); SQLiteParameter idParam = new SQLiteParameter("id");
SQLiteParameter nameParam = new SQLiteParameter("name"); SQLiteParameter nameParam = new SQLiteParameter("name");
SQLiteParameter dataSetParam = new SQLiteParameter("dataset"); SQLiteParameter dataSetParam = new SQLiteParameter("dataset");
SQLiteParameter valueParam = new SQLiteParameter("value"); SQLiteParameter valueParam = new SQLiteParameter("value");
SQLiteParameter minParam = new SQLiteParameter("min"); SQLiteParameter minParam = new SQLiteParameter("min");
SQLiteParameter maxParam = new SQLiteParameter("max"); SQLiteParameter maxParam = new SQLiteParameter("max");
SQLiteParameter unitParam = new SQLiteParameter("unit"); SQLiteParameter unitParam = new SQLiteParameter("unit");
SQLiteParameter formatParam = new SQLiteParameter("format");
cmd.CommandText =
"INSERT OR IGNORE INTO PerformanceCounter(id, name, minvalue, maxvalue, unit)" + // should I split these queries
"VALUES(@id,@name,@min,@max,@unit);" + // for better performance?
"INSERT INTO CounterData(datasetid, counterid, value)" +
"VALUES(@dataset,@id,@value);";
cmd.Parameters.AddRange(new SQLiteParameter[] { idParam, nameParam, dataSetParam, valueParam, minParam, maxParam, unitParam });
int id = 0;
foreach (PerformanceCounterDescriptor counter in counters) {
idParam.Value = id;
nameParam.Value = counter.Name;
minParam.Value = counter.MinValue;
maxParam.Value = counter.MaxValue;
unitParam.Value = counter.Unit;
for (int i = 0; i < counter.Values.Count; i++) { cmd.Parameters.AddRange(new SQLiteParameter[] { idParam, dataSetParam, valueParam });
dataSetParam.Value = i; cmd2.Parameters.AddRange(new SQLiteParameter[] { idParam, nameParam, minParam, maxParam, unitParam, formatParam });
valueParam.Value = counter.Values[i];
cmd.ExecuteNonQuery(); cmd2.CommandText =
} "INSERT INTO PerformanceCounter(id, name, minvalue, maxvalue, unit, format)" +
"VALUES(@id,@name,@min,@max,@unit,@format);";
id++; cmd.CommandText =
"INSERT INTO CounterData(datasetid, counterid, value)" +
"VALUES(@dataset,@id,@value);";
int id = 0;
foreach (PerformanceCounterDescriptor counter in counters) {
idParam.Value = id;
nameParam.Value = counter.Name;
minParam.Value = counter.MinValue;
maxParam.Value = counter.MaxValue;
unitParam.Value = counter.Unit;
formatParam.Value = counter.Format;
for (int i = 0; i < counter.Values.Count; i++) {
dataSetParam.Value = i;
valueParam.Value = counter.Values[i];
cmd.ExecuteNonQuery();
}
cmd2.ExecuteNonQuery();
id++;
}
} }
} }
trans.Commit(); trans.Commit();

5
src/AddIns/Misc/Profiler/Controller/Profiler.cs

@ -707,9 +707,9 @@ namespace ICSharpCode.Profiler.Controller
return true; return true;
} else if (readString.StartsWith("event ", StringComparison.Ordinal)) { } else if (readString.StartsWith("event ", StringComparison.Ordinal)) {
string[] parts = readString.Split(' '); IList<string> parts = readString.SplitSeparatedString(' ');
// event <typeid> <nameid> <data> // event <typeid> <nameid> <data>
if (parts.Length != 4) if (parts.Count != 4)
return false; return false;
int type = int.Parse(parts[1], CultureInfo.InvariantCulture); int type = int.Parse(parts[1], CultureInfo.InvariantCulture);
int name = int.Parse(parts[2], CultureInfo.InvariantCulture); int name = int.Parse(parts[2], CultureInfo.InvariantCulture);
@ -718,6 +718,7 @@ namespace ICSharpCode.Profiler.Controller
lock (this.dataWriter) { lock (this.dataWriter) {
this.dataWriter.WriteEventData(new[] { new EventDataEntry() { DataSetId = this.dataWriter.DataSetCount, NameId = name, Type = (EventType)type, Data = data } }); this.dataWriter.WriteEventData(new[] { new EventDataEntry() { DataSetId = this.dataWriter.DataSetCount, NameId = name, Type = (EventType)type, Data = data } });
} }
return true;
} else { } else {
if (readString.StartsWith("error-", StringComparison.Ordinal)) { if (readString.StartsWith("error-", StringComparison.Ordinal)) {
string[] parts = readString.Split('-'); string[] parts = readString.Split('-');

1
src/AddIns/Misc/Profiler/Controller/structs.cs

@ -221,6 +221,7 @@ namespace ICSharpCode.Profiler.Controller
{ {
public int ThreadID; public int ThreadID;
public volatile int InLock; public volatile int InLock;
public volatile bool Active;
public TargetProcessPointer32 Predecessor; public TargetProcessPointer32 Predecessor;
public TargetProcessPointer32 Follower; public TargetProcessPointer32 Follower;
public LightweightStack32 Stack; public LightweightStack32 Stack;

2
src/AddIns/Misc/Profiler/Hook/LightweightList.cpp

@ -23,6 +23,8 @@ ThreadLocalData *LightweightList::add()
void *itemMemory = stackAllocator.malloc(sizeof(ThreadLocalData)); void *itemMemory = stackAllocator.malloc(sizeof(ThreadLocalData));
assert(itemMemory != nullptr); assert(itemMemory != nullptr);
ThreadLocalData *item = new (itemMemory) ThreadLocalData(); ThreadLocalData *item = new (itemMemory) ThreadLocalData();
item->active = true;
if (this->lastItem == nullptr) { if (this->lastItem == nullptr) {
this->lastItem = item; this->lastItem = item;

18
src/AddIns/Misc/Profiler/Hook/Profiler.cpp

@ -77,6 +77,9 @@ ASSEMBLER_CALLBACK FunctionEnterGlobal(int functionID)
FunctionEnterCreateNewRoot(data, __rdtsc()); FunctionEnterCreateNewRoot(data, __rdtsc());
} else } else
profiler.EnterLock(data); profiler.EnterLock(data);
if (!data->active)
goto EXIT;
// this call allows GetOrAddChild to update the value at the top of the stack // this call allows GetOrAddChild to update the value at the top of the stack
// if the FunctionInfo is resized // if the FunctionInfo is resized
@ -109,7 +112,7 @@ ASSEMBLER_CALLBACK FunctionEnterGlobal(int functionID)
data->stack.push(StackEntry(child, __rdtsc())); data->stack.push(StackEntry(child, __rdtsc()));
} }
EXIT:
data->inLock = 0; data->inLock = 0;
} }
@ -131,6 +134,9 @@ ASSEMBLER_CALLBACK FunctionLeaveGlobal()
ThreadLocalData *data = getThreadLocalData(); ThreadLocalData *data = getThreadLocalData();
profiler.EnterLock(data); profiler.EnterLock(data);
if (!data->active)
goto EXIT;
if (data->stack.empty()) { if (data->stack.empty()) {
//DebugWriteLine(L"FunctionLeaveGlobal (but stack was empty)"); //DebugWriteLine(L"FunctionLeaveGlobal (but stack was empty)");
@ -143,7 +149,8 @@ ASSEMBLER_CALLBACK FunctionLeaveGlobal()
data->stack.pop(); data->stack.pop();
} }
} }
EXIT:
data->inLock = 0; data->inLock = 0;
} }
@ -238,7 +245,6 @@ CProfiler::CProfiler()
this->pICorProfilerInfo = nullptr; this->pICorProfilerInfo = nullptr;
this->pICorProfilerInfo2 = nullptr; this->pICorProfilerInfo2 = nullptr;
this->sigReader = nullptr; this->sigReader = nullptr;
this->active = true;
} }
// ---- ICorProfilerCallback IMPLEMENTATION ------------------ // ---- ICorProfilerCallback IMPLEMENTATION ------------------
@ -626,12 +632,14 @@ STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsS
void CProfiler::Activate() void CProfiler::Activate()
{ {
ThreadLocalData *data = getThreadLocalData();
data->active = true;
} }
void CProfiler::Deactivate() void CProfiler::Deactivate()
{ {
ThreadLocalData *data = getThreadLocalData();
data->active = false;
} }
const ULONG FAT_HEADER_SIZE = 0xC; /* 12 bytes = WORD + WORD + DWORD + DWORD */ const ULONG FAT_HEADER_SIZE = 0xC; /* 12 bytes = WORD + WORD + DWORD + DWORD */

2
src/AddIns/Misc/Profiler/Hook/Profiler.h

@ -132,8 +132,6 @@ private:
TUThreadIDMap unmanagedThreadIDMap; TUThreadIDMap unmanagedThreadIDMap;
TMethodTokenMap methodMap; TMethodTokenMap methodMap;
bool active;
// function to set up our event mask // function to set up our event mask
HRESULT SetEventMask(); HRESULT SetEventMask();
void Rewrite(FunctionID functionID, int type, int nameId, WCHAR *name); void Rewrite(FunctionID functionID, int type, int nameId, WCHAR *name);

2
src/AddIns/Misc/Profiler/Hook/constants.cpp

@ -18,5 +18,5 @@ WCHAR *winFormsGroupList[WINFORMS_GROUP_LENGTH] = {
}; };
WCHAR *wpfGroupList[WPF_GROUP_LENGTH] = { WCHAR *wpfGroupList[WPF_GROUP_LENGTH] = {
L"dummy" L"System.Windows.UIElement.OnLeftMouseButtonDown"
}; };

1
src/AddIns/Misc/Profiler/Hook/global.h

@ -40,6 +40,7 @@ struct StackEntry {
struct ThreadLocalData { struct ThreadLocalData {
int threadID; int threadID;
volatile int inLock; volatile int inLock;
volatile bool active;
ThreadLocalData *predecessor; ThreadLocalData *predecessor;
ThreadLocalData *follower; ThreadLocalData *follower;

41
src/AddIns/Misc/Profiler/Hook/main.cpp

@ -8,6 +8,7 @@
#include "main.h" #include "main.h"
#include "global.h" #include "global.h"
#include "FunctionInfo.h" #include "FunctionInfo.h"
#include "ProfilerMetaData.h"
//sharedMemoryAllocator mallocator; //sharedMemoryAllocator mallocator;
freeListAllocator<FunctionInfoAllocationSize> mallocator; freeListAllocator<FunctionInfoAllocationSize> mallocator;
@ -43,37 +44,41 @@ STDAPI rdtsc(ULONGLONG *tsc) {
return S_OK; return S_OK;
} }
std::wstring EscapeString(const WCHAR *input)
{
std::wostringstream output;
output.str(L"");
for (const WCHAR *ptr = input; *ptr != 0; ptr++) {
WCHAR c = *ptr;
if (c == '"')
output << "\"\"";
else
output << c;
}
return output.str();
}
extern "C" { extern "C" {
void __stdcall DeactivateProfiler() void __stdcall DeactivateProfiler()
{ {
profiler.LogString(L"DeactivateProfiler called!");
profiler.Deactivate(); profiler.Deactivate();
} }
void __stdcall ActivateProfiler() void __stdcall ActivateProfiler()
{ {
profiler.LogString(L"ActivateProfiler called!");
profiler.Activate(); profiler.Activate();
} }
void __stdcall LogEvent(int type, int id, WCHAR *controlName, WCHAR *controlText) void __stdcall LogEvent(int type, int id, WCHAR *controlName, WCHAR *controlText)
{ {
WCHAR *format = L""; if (controlName == nullptr)
controlName = L"";
switch (type) { if (controlText == nullptr)
case 0: controlText = L"";
format = L"event %d %d --";
break;
case 1:
format = L"event %d %d --";
break;
case 2:
format = L"event %d %d -name:\"%s\"text:\"%s\"-";
break;
case 3:
break;
}
DebugWriteLine(format, type, id, controlName, controlText); profiler.LogString(L"event %d %d \"%s:%s\"", type, id, EscapeString(controlName).c_str(), EscapeString(controlText).c_str());
} }
} }
Loading…
Cancel
Save