singrdk/base/Kernel/Native/EventController.cpp

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.