571 lines
16 KiB
C++
571 lines
16 KiB
C++
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: EventController.cpp
|
||
|
//
|
||
|
// Note: Kernel & Process
|
||
|
//
|
||
|
|
||
|
#include "hal.h"
|
||
|
#include "eventing.h"
|
||
|
|
||
|
bool GetTracingHandles(UIntPtr * storageHandle,
|
||
|
UIntPtr * sourceHandle,
|
||
|
UIntPtr * eventTypeHandle);
|
||
|
|
||
|
bool GetMonitoringHandles(UIntPtr * storageHandle,
|
||
|
UIntPtr * sourceHandle,
|
||
|
UIntPtr * eventTypeHandle);
|
||
|
|
||
|
SOURCE_CONTROLLER SourceController = {NULL, NULL, NULL, NULL, NULL};
|
||
|
|
||
|
char * ConvertToChars(char * dst, bartok_char *src, int32 length)
|
||
|
{
|
||
|
if (src != NULL) {
|
||
|
bartok_char *end = src + length;
|
||
|
|
||
|
while (src < end) {
|
||
|
*dst++ = (uint8)*src++;
|
||
|
}
|
||
|
}
|
||
|
*dst++ = '\0';
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
void ConvertToChars(char * dst, Class_System_String *arg)
|
||
|
{
|
||
|
ConvertToChars(dst, &arg->m_firstChar, arg->m_stringLength);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
RegisterRepositoryStorage(PMEMORY_STORAGE storage)
|
||
|
{
|
||
|
EV_ASSERT(SourceController.SourceRepository == NULL);
|
||
|
SourceController.SourceRepository = storage;
|
||
|
RegisterNativeTypes();
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
RegisterStorage(PMEMORY_STORAGE storage)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
if (SourceController.SourceRepository == NULL) {
|
||
|
|
||
|
// The first storage registered needs to be the type repository
|
||
|
|
||
|
RegisterRepositoryStorage(storage);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
storage->Link = SourceController.StorageList;
|
||
|
SourceController.StorageList = storage;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
UnRegisterStorage(PMEMORY_STORAGE storage)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
PMEMORY_STORAGE tmpStorage = SourceController.StorageList;
|
||
|
|
||
|
EV_ASSERT(tmpStorage != NULL);
|
||
|
|
||
|
if (tmpStorage == storage) {
|
||
|
|
||
|
SourceController.StorageList = tmpStorage->Link;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
while (tmpStorage->Link != storage) {
|
||
|
|
||
|
tmpStorage = tmpStorage->Link;
|
||
|
}
|
||
|
|
||
|
if (tmpStorage->Link == storage) {
|
||
|
|
||
|
tmpStorage->Link = storage->Link;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
RegisterExternalController(PEXTERNAL_CONTROLLER_DESCRIPTOR controller)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
controller->Link = SourceController.ExternalControllers;
|
||
|
SourceController.ExternalControllers = controller;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
UnRegisterExternalController(PEXTERNAL_CONTROLLER_DESCRIPTOR controller)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
PEXTERNAL_CONTROLLER_DESCRIPTOR tmpController = SourceController.ExternalControllers;
|
||
|
|
||
|
EV_ASSERT(tmpController != NULL);
|
||
|
|
||
|
if (tmpController == controller) {
|
||
|
|
||
|
SourceController.ExternalControllers = tmpController->Link;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
while (tmpController->Link != controller) {
|
||
|
|
||
|
tmpController = tmpController->Link;
|
||
|
}
|
||
|
|
||
|
if (tmpController->Link == controller) {
|
||
|
|
||
|
tmpController->Link = controller->Link;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Insert it to the free llist
|
||
|
|
||
|
controller->Link = SourceController.FreeControllerList;
|
||
|
SourceController.FreeControllerList = controller;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
RegisterQueryView(PQUERY_VIEW queryView)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutula exclusion
|
||
|
|
||
|
queryView->Link = SourceController.QueryViews;
|
||
|
SourceController.QueryViews = queryView;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
UnRegisterQueryView(PQUERY_VIEW queryView)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
PQUERY_VIEW tmpQueryView = SourceController.QueryViews;
|
||
|
|
||
|
EV_ASSERT(tmpQueryView != NULL);
|
||
|
|
||
|
if (tmpQueryView == queryView) {
|
||
|
|
||
|
SourceController.QueryViews = tmpQueryView->Link;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
while (tmpQueryView->Link != queryView) {
|
||
|
|
||
|
tmpQueryView = tmpQueryView->Link;
|
||
|
}
|
||
|
|
||
|
if (tmpQueryView->Link == queryView) {
|
||
|
|
||
|
tmpQueryView->Link = queryView->Link;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Insert it to the free llist
|
||
|
|
||
|
queryView->Link = SourceController.QueryViews;
|
||
|
SourceController.FreeQueryViews = queryView;
|
||
|
|
||
|
}
|
||
|
|
||
|
PQUERY_VIEW AllocateQueryView( )
|
||
|
{
|
||
|
if (SourceController.FreeQueryViews != NULL) {
|
||
|
|
||
|
PQUERY_VIEW queryView = SourceController.FreeQueryViews;
|
||
|
SourceController.FreeQueryViews = queryView->Link;
|
||
|
RegisterQueryView(queryView);
|
||
|
return queryView;
|
||
|
}
|
||
|
|
||
|
QUERY_VIEW source;
|
||
|
|
||
|
PMEMORY_HEADER Entry = InternalLogFixedRecord( GetLocalRepositoryHandle(),
|
||
|
RECORD_EVENT_CONTROLLER,
|
||
|
0,
|
||
|
&source,
|
||
|
sizeof(source));
|
||
|
|
||
|
if (Entry == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
PQUERY_VIEW newSource = (PQUERY_VIEW)GetUserRecordStructure(Entry);
|
||
|
RegisterQueryView(newSource);
|
||
|
return newSource;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool
|
||
|
RegisterSource(PSOURCE_DESCRIPTOR newSource)
|
||
|
{
|
||
|
// Note the caller of this function needs to assure mutual exclusion
|
||
|
|
||
|
newSource->Link = (UIntPtr)SourceController.SourceDescriptors;
|
||
|
SourceController.SourceDescriptors = newSource;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// ABI entries
|
||
|
//
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_FetchLocalStorage()
|
||
|
{
|
||
|
return (UIntPtr)GetLocalRepository();
|
||
|
}
|
||
|
|
||
|
bool Class_Microsoft_Singularity_Eventing_LocalController::g_SetRepositoryStorage(UIntPtr storageHandle)
|
||
|
{
|
||
|
if (SourceController.SourceRepository != NULL) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
RegisterRepositoryStorage(HANDLE_TO_STORAGE(storageHandle));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_RegisterEventDescriptorInternal(Class_System_String * eventName,
|
||
|
Class_System_String * eventDescription)
|
||
|
{
|
||
|
return (UIntPtr)RegisterEventDescriptorImplementation(Class_Microsoft_Singularity_Eventing_DataType___string,
|
||
|
&eventName->m_firstChar,
|
||
|
eventName->m_stringLength,
|
||
|
&eventDescription->m_firstChar,
|
||
|
eventDescription->m_stringLength);
|
||
|
}
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_RegisterEventFieldInternal(UIntPtr eventHandle,
|
||
|
Class_System_String * fieldName,
|
||
|
uint16 offset,
|
||
|
uint16 type)
|
||
|
{
|
||
|
return (UIntPtr) RegisterFieldDescriptorImplementation(
|
||
|
Class_Microsoft_Singularity_Eventing_DataType___string,
|
||
|
HANDLE_TO_HEADER(eventHandle),
|
||
|
&fieldName->m_firstChar,
|
||
|
fieldName->m_stringLength,
|
||
|
offset,
|
||
|
type);
|
||
|
}
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_RegisterEventGenericFieldInternal(UIntPtr eventHandle,
|
||
|
Class_System_String * fieldName,
|
||
|
uint16 offset,
|
||
|
uint16 size,
|
||
|
UIntPtr typeFieldDescriptor)
|
||
|
{
|
||
|
return (UIntPtr)RegisterGenericFieldDescriptorImplementation(
|
||
|
Class_Microsoft_Singularity_Eventing_DataType___string,
|
||
|
HANDLE_TO_HEADER(eventHandle),
|
||
|
&fieldName->m_firstChar,
|
||
|
fieldName->m_stringLength,
|
||
|
offset,
|
||
|
size,
|
||
|
typeFieldDescriptor);
|
||
|
}
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_RegisterEnumDescriptorInternal(Class_System_String * name,
|
||
|
uint16 type)
|
||
|
{
|
||
|
return (UIntPtr)RegisterEnumDescriptorImplementation(
|
||
|
Class_Microsoft_Singularity_Eventing_DataType___string,
|
||
|
&name->m_firstChar,
|
||
|
name->m_stringLength,
|
||
|
type);
|
||
|
}
|
||
|
|
||
|
UIntPtr Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_RegisterValueDescriptorInternal(UIntPtr eventHandle,
|
||
|
Class_System_String * name,
|
||
|
uint64 value,
|
||
|
uint8 flagLetter)
|
||
|
{
|
||
|
return (UIntPtr)RegisterValueDescriptorImplementation(
|
||
|
Class_Microsoft_Singularity_Eventing_DataType___string,
|
||
|
HANDLE_TO_HEADER(eventHandle),
|
||
|
&name->m_firstChar,
|
||
|
name->m_stringLength,
|
||
|
value,
|
||
|
flagLetter);
|
||
|
}
|
||
|
|
||
|
|
||
|
bool
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_RegisterStorageImpl(UIntPtr storageHandle)
|
||
|
{
|
||
|
return RegisterStorage(HANDLE_TO_STORAGE(storageHandle));
|
||
|
}
|
||
|
void
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_UnRegisterStorageImpl(UIntPtr storageHandle)
|
||
|
{
|
||
|
UnRegisterStorage(HANDLE_TO_STORAGE(storageHandle));
|
||
|
}
|
||
|
|
||
|
UIntPtr
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_AllocateSourceHandleImpl(
|
||
|
Class_System_String * sourceName)
|
||
|
{
|
||
|
SOURCE_DESCRIPTOR source = {NULL, 0};
|
||
|
PVOID ExtendedBuffer;
|
||
|
|
||
|
PMEMORY_HEADER Entry = InternalLogRecord( GetLocalRepositoryHandle(),
|
||
|
RECORD_EVENT_SOURCE,
|
||
|
0,
|
||
|
&source,
|
||
|
sizeof(source),
|
||
|
&ExtendedBuffer,
|
||
|
sourceName->m_stringLength + 1);
|
||
|
|
||
|
if (Entry != NULL) {
|
||
|
|
||
|
PSOURCE_DESCRIPTOR newSource = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(Entry);
|
||
|
|
||
|
ConvertToChars((char *)ExtendedBuffer, sourceName);
|
||
|
RegisterSource(newSource);
|
||
|
CommitEventEntry(Entry);
|
||
|
}
|
||
|
|
||
|
return (UIntPtr)Entry;
|
||
|
}
|
||
|
|
||
|
PSOURCE_DESCRIPTOR
|
||
|
GetSourceFromHandle(UIntPtr sourceHandle)
|
||
|
{
|
||
|
if (sourceHandle == 0) {
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
PMEMORY_HEADER entry = HANDLE_TO_HEADER(sourceHandle);
|
||
|
|
||
|
if (entry->Flags == RECORD_EVENT_SOURCE) {
|
||
|
|
||
|
return (PSOURCE_DESCRIPTOR)GetUserRecordStructure(entry);
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
UIntPtr
|
||
|
AllocateNativeSourceHandle(char * sourceName)
|
||
|
{
|
||
|
SOURCE_DESCRIPTOR source = {0,NULL,0,0,0,0,0,0};
|
||
|
|
||
|
PVOID ExtendedBuffer;
|
||
|
uint16 sourceLen = strlen(sourceName) + 1;
|
||
|
|
||
|
PMEMORY_HEADER Entry = InternalLogRecord( GetLocalRepositoryHandle(),
|
||
|
RECORD_EVENT_SOURCE,
|
||
|
0,
|
||
|
&source,
|
||
|
sizeof(source),
|
||
|
&ExtendedBuffer,
|
||
|
sourceLen);
|
||
|
|
||
|
if (Entry != NULL) {
|
||
|
|
||
|
PSOURCE_DESCRIPTOR newSource = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(Entry);
|
||
|
memcpy(ExtendedBuffer, sourceName, sourceLen);
|
||
|
|
||
|
RegisterSource(newSource);
|
||
|
CommitEventEntry(Entry);
|
||
|
}
|
||
|
|
||
|
return (UIntPtr)Entry;
|
||
|
}
|
||
|
|
||
|
UIntPtr
|
||
|
RegisterNativeSource(char * sourceName, UIntPtr storageHandle, uint32 controlFlags)
|
||
|
{
|
||
|
UIntPtr sourceHandle = AllocateNativeSourceHandle(sourceName);
|
||
|
|
||
|
if (sourceHandle != 0) {
|
||
|
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_RegisterSourceStorageImpl(
|
||
|
sourceHandle, storageHandle, controlFlags);
|
||
|
|
||
|
if (storageHandle != 0) {
|
||
|
|
||
|
RegisterStorage(HANDLE_TO_STORAGE(storageHandle));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return sourceHandle;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_RegisterSourceStorageImpl(
|
||
|
UIntPtr sourceHandle,
|
||
|
UIntPtr storageHandle,
|
||
|
uint32 controlFlags)
|
||
|
{
|
||
|
PSOURCE_DESCRIPTOR Source;
|
||
|
|
||
|
Source = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(HANDLE_TO_HEADER(sourceHandle));
|
||
|
|
||
|
if (Source) {
|
||
|
Source->StorageHandle = storageHandle;
|
||
|
Source->EventTypeHandle = 0;
|
||
|
Source->DebuggerBufferAddress = 0;
|
||
|
Source->Count = 0;
|
||
|
Source->EntrySize = 0;
|
||
|
Source->ControlFlags = controlFlags;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_RegisterActiveSourceImpl(
|
||
|
UIntPtr sourceHandle,
|
||
|
UIntPtr eventTypeHandle,
|
||
|
UIntPtr debuggerBufferAddress,
|
||
|
uint16 count,
|
||
|
uint16 entrySize)
|
||
|
{
|
||
|
PSOURCE_DESCRIPTOR Source;
|
||
|
|
||
|
Source = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(HANDLE_TO_HEADER(sourceHandle));
|
||
|
|
||
|
if (Source) {
|
||
|
|
||
|
Source->StorageHandle = 0;
|
||
|
Source->EventTypeHandle = eventTypeHandle;
|
||
|
Source->DebuggerBufferAddress = debuggerBufferAddress;
|
||
|
Source->Count = count;
|
||
|
Source->EntrySize = entrySize;
|
||
|
Source->ControlFlags = 0xFFFF0000;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Class_Microsoft_Singularity_Eventing_LocalController::g_UnRegisterSourceImpl(
|
||
|
UIntPtr sourceHandle)
|
||
|
{
|
||
|
PSOURCE_DESCRIPTOR Source;
|
||
|
|
||
|
Source = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(HANDLE_TO_HEADER(sourceHandle));
|
||
|
|
||
|
if (Source) {
|
||
|
|
||
|
EV_ASSERT(Source->StorageHandle == 0);
|
||
|
Source->StorageHandle = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_GetControllerHandle(UIntPtr *storageHandle, UIntPtr *contextHandle)
|
||
|
{
|
||
|
// ????? Some correct values are needed that would allow switching to the right context in debugger
|
||
|
// Note these values are not being accessed programatically. Correct contracts should be established
|
||
|
// to query entries cross SIPs
|
||
|
|
||
|
*storageHandle = (UIntPtr)&SourceController;
|
||
|
*contextHandle = 0;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_QueryNativeSourceInfo(UIntPtr sourceHandle,
|
||
|
UIntPtr * storageHandle,
|
||
|
bartok_char * bufferName,
|
||
|
uint16 bufferSize)
|
||
|
{
|
||
|
PMEMORY_HEADER Entry = HANDLE_TO_HEADER(sourceHandle);
|
||
|
PSOURCE_DESCRIPTOR source = (PSOURCE_DESCRIPTOR)GetUserRecordStructure(Entry);
|
||
|
|
||
|
*storageHandle = source->StorageHandle;
|
||
|
|
||
|
char * src = (char *)(source + 1);
|
||
|
|
||
|
if ((bufferName != NULL) && (bufferSize != 0)) {
|
||
|
|
||
|
while ((bufferSize != 0) && (*src)) {
|
||
|
|
||
|
*bufferName++ = *src++;
|
||
|
bufferSize -= sizeof(bartok_char);
|
||
|
}
|
||
|
|
||
|
if (bufferSize == 0) {
|
||
|
|
||
|
// Move back one position to insert the null terminator.
|
||
|
// We have at least this character in the buffer due to the test two levels above
|
||
|
|
||
|
bufferSize -= sizeof(bartok_char);
|
||
|
}
|
||
|
|
||
|
*bufferName = 0;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
int Class_Microsoft_Singularity_Eventing_LocalController::
|
||
|
g_QuerySystemSources(UIntPtr * sourceHandles,
|
||
|
uint16 arraySize)
|
||
|
{
|
||
|
|
||
|
int totalSources = 0;
|
||
|
|
||
|
PSOURCE_DESCRIPTOR source = SourceController.SourceDescriptors;
|
||
|
|
||
|
while (source != NULL) {
|
||
|
|
||
|
if (totalSources < arraySize) {
|
||
|
|
||
|
sourceHandles[totalSources] = (UIntPtr)((PMEMORY_HEADER)source - 1);
|
||
|
}
|
||
|
|
||
|
source = (PSOURCE_DESCRIPTOR)source->Link;
|
||
|
totalSources += 1;
|
||
|
}
|
||
|
|
||
|
return totalSources;
|
||
|
}
|
||
|
|
||
|
bool Class_Microsoft_Singularity_Eventing_Controller::
|
||
|
g_GetSharedSourceHandlesInternal(uint32 infoId,
|
||
|
UIntPtr * storageHandle,
|
||
|
UIntPtr * sourceHandle,
|
||
|
UIntPtr * eventTypeHandle)
|
||
|
{
|
||
|
switch (infoId) {
|
||
|
case Class_Microsoft_Singularity_Eventing_Controller_TracingInfo:
|
||
|
return GetTracingHandles(storageHandle, sourceHandle, eventTypeHandle);
|
||
|
|
||
|
case Class_Microsoft_Singularity_Eventing_Controller_MonitoringInfo:
|
||
|
return GetMonitoringHandles(storageHandle, sourceHandle, eventTypeHandle);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////// End of File.
|
||
|
|