singrdk/base/Kernel/Native/EventDescriptor.cpp

538 lines
16 KiB
C++
Raw Normal View History

2008-11-17 18:29:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: EventDescriptor.cpp
//
// Note: Kernel & Process
//
#include "hal.h"
#include "eventing.h"
#ifdef SINGULARITY_KERNEL
extern UIntPtr MonitoringTypeHandle;
extern UIntPtr TracingTypeHandle;
#endif
#define _LOGGING_TO_REPOSITORY
#define DECLARE_STRUCTURE_BEGIN(x,d) UIntPtr Handle_##x;
#define DECLARE_ENUM_BEGIN(x,sz) UIntPtr Handle_##x;
#include "SystemEvents.inl"
#undef _LOGGING_TO_REPOSITORY
uint16 GetFieldSize(uint16 type)
{
if (type & EVENT_FIELD_TYPE_arrayType) {
return sizeof(uint16);
}
switch (type) {
case EVENT_FIELD_TYPE_int8:
case EVENT_FIELD_TYPE_uint8:
return sizeof(uint8);
case EVENT_FIELD_TYPE_int16:
case EVENT_FIELD_TYPE_uint16:
return sizeof(uint16);
case EVENT_FIELD_TYPE_int32:
case EVENT_FIELD_TYPE_uint32:
return sizeof(uint32);
case EVENT_FIELD_TYPE_int64:
case EVENT_FIELD_TYPE_uint64:
return sizeof(uint64);
case EVENT_FIELD_TYPE_IntPtr:
case EVENT_FIELD_TYPE_UIntPtr:
return sizeof(UIntPtr);
}
return 0;
}
uint16 GetFixedTypeSize(PEVENT_DESCRIPTOR typeEntry)
{
PEVENT_FIELD_DESCRIPTOR field;
uint16 size = 0;
for (field = typeEntry->fieldsLink; field != NULL; field = field->fieldsLink) {
uint16 fieldSize = GetFieldSize(field->Type);
if (size < (field->Offset + fieldSize)) {
size = field->Offset + fieldSize;
}
}
return size;
}
char * GetExtendedString(UIntPtr EntryHandle, int index)
{
PMEMORY_HEADER entry = HANDLE_TO_HEADER(EntryHandle);
char * endPtr = (char *)(entry) + entry->Size;
int entrySize;
switch (entry->Flags) {
case RECORD_EVENT_TYPE:
entrySize = sizeof(EVENT_DESCRIPTOR);
break;
case RECORD_EVENT_FIELD:
entrySize = sizeof(EVENT_FIELD_DESCRIPTOR);
break;
case RECORD_EVENT_GENERIC_FIELD:
entrySize = sizeof(EVENT_GENERIC_TYPE_DESCRIPTOR);
break;
case RECORD_EVENT_VALUE:
entrySize = sizeof(EVENT_VALUE_DESCRIPTOR);
break;
case RECORD_EVENT_ENUM:
entrySize = sizeof(ENUM_DESCRIPTOR);
break;
default : {
PEVENT_DESCRIPTOR typeEntry = HANDLE_TO_TYPE(entry->Type);
entrySize = GetFixedTypeSize(typeEntry);
}
}
void * base = GetUserRecordStructure(entry);
char * crtPtr = (char *)base + entrySize;
crtPtr = (char *)ROUND_UP_TO_POWER2(crtPtr, sizeof(int));
if (crtPtr >= endPtr) {
return NULL;
}
for (int i = 1; i < index; i++) {
uint16 length;
// copy the structure localy since it may not be aligned.
memcpy(&length, crtPtr, sizeof(uint16));
crtPtr += length + sizeof(uint16);
if (crtPtr >= endPtr) {
return NULL;
}
}
char * ptr = crtPtr + sizeof(uint16); // skip also the size of the string
if (ptr >= endPtr) {
return NULL;
}
return ptr;
}
//
// Shared routines to handle both unicode and ascii names for eventing
//
PMEMORY_HEADER
RegisterEventDescriptorImplementation(int stringType,
PVOID name,
uint16 nameLength,
PVOID description,
uint16 descriptionLength)
{
EVENT_DESCRIPTOR Event = {NULL, 0, 1, 2};
Struct_Microsoft_Singularity_Eventing_ArrayType array[] = {
{nameLength,
sizeof(char),
stringType,
name},
{descriptionLength,
sizeof(char),
stringType,
description}};
if (descriptionLength == 0) {
Event.Description = 0;
}
PMEMORY_HEADER Entry = InternalLogVariableRecord( true,
GetLocalRepositoryHandle(),
RECORD_EVENT_TYPE,
0,
&Event,
sizeof(Event),
(descriptionLength) ? 2 : 1,
array);
return Entry;
}
PMEMORY_HEADER
RegisterFieldDescriptorImplementation(int stringType,
PMEMORY_HEADER Descriptor,
PVOID name,
uint32 nameLength,
uint16 offset,
uint16 type )
{
PEVENT_DESCRIPTOR eventDescriptor = (PEVENT_DESCRIPTOR)GetUserRecordStructure(Descriptor);
int fieldSize = GetFieldSize(type);
if (offset == 0) {
offset = eventDescriptor->Size;
//
// Align naturaly the field
//
offset = (uint16)ROUND_UP_TO_POWER2(offset, fieldSize);
}
EV_ASSERT(offset == ROUND_UP_TO_POWER2(offset, fieldSize));
EV_ASSERT(offset >= eventDescriptor->Size);
EVENT_FIELD_DESCRIPTOR Field = {NULL, offset, type, NULL};
Struct_Microsoft_Singularity_Eventing_ArrayType array[] = {
{nameLength,
sizeof(char),
stringType,
name}};
PMEMORY_HEADER Entry = InternalLogVariableRecord( false,
GetLocalRepositoryHandle(),
RECORD_EVENT_FIELD,
(UIntPtr)Descriptor,
&Field,
sizeof(Field),
1,
array);
if (Entry != NULL) {
PEVENT_FIELD_DESCRIPTOR newField = (PEVENT_FIELD_DESCRIPTOR)GetUserRecordStructure(Entry);
newField->fieldsLink = eventDescriptor->fieldsLink;
eventDescriptor->fieldsLink = newField;
eventDescriptor->Size = offset + fieldSize;
CommitEventEntry(Entry);
}
return Entry;
}
PMEMORY_HEADER
RegisterGenericFieldDescriptorImplementation( int stringType,
PMEMORY_HEADER event,
PVOID name,
uint32 nameLength,
uint16 offset,
uint16 size,
UIntPtr typeFieldDescriptor)
{
PEVENT_DESCRIPTOR eventDescriptor = (PEVENT_DESCRIPTOR)GetUserRecordStructure(event);
if (offset == 0) {
offset = eventDescriptor->Size;
//
// Align naturaly the field
//
offset = (uint16)ROUND_UP_TO_POWER2(offset, size);
}
EV_ASSERT(offset == ROUND_UP_TO_POWER2(offset, size));
EV_ASSERT(offset >= eventDescriptor->Size);
EVENT_GENERIC_TYPE_DESCRIPTOR Field = {NULL,
offset,
GENERIC_TYPE_SIGNATURE,
size,
typeFieldDescriptor,
1};
Struct_Microsoft_Singularity_Eventing_ArrayType array[] = {
{nameLength,
sizeof(char),
stringType,
name}};
PMEMORY_HEADER Entry = InternalLogVariableRecord( false,
GetLocalRepositoryHandle(),
RECORD_EVENT_GENERIC_FIELD,
(UIntPtr)event,
&Field,
sizeof(Field),
1,
array);
if (Entry != NULL) {
PEVENT_FIELD_DESCRIPTOR newField = (PEVENT_FIELD_DESCRIPTOR)GetUserRecordStructure(Entry);
newField->fieldsLink = eventDescriptor->fieldsLink;
eventDescriptor->fieldsLink = newField;
eventDescriptor->Size = offset + size;
CommitEventEntry(Entry);
}
return Entry;
}
PMEMORY_HEADER
RegisterEnumDescriptorImplementation(int stringType,
PVOID name,
uint16 nameLength,
uint16 type)
{
ENUM_DESCRIPTOR Event = {NULL, type, 0, 1, 2};
Struct_Microsoft_Singularity_Eventing_ArrayType array[] = {
{nameLength,
sizeof(char),
stringType,
name}};
PMEMORY_HEADER Entry = InternalLogVariableRecord( true,
GetLocalRepositoryHandle(),
RECORD_EVENT_ENUM,
0,
&Event,
sizeof(Event),
1,
array);
return Entry;
}
PMEMORY_HEADER
RegisterValueDescriptorImplementation(int stringType,
PMEMORY_HEADER descriptor,
PVOID name,
uint32 nameLength,
uint64 value,
uint8 flagLetter)
{
EVENT_VALUE_DESCRIPTOR Field = {NULL, flagLetter, value, NULL };
Struct_Microsoft_Singularity_Eventing_ArrayType array[] = {
{nameLength,
sizeof(char),
stringType,
name}};
PMEMORY_HEADER Entry = InternalLogVariableRecord( false,
GetLocalRepositoryHandle(),
RECORD_EVENT_VALUE,
(UIntPtr)descriptor,
&Field,
sizeof(Field),
1,
array);
if (Entry != NULL) {
PENUM_DESCRIPTOR eventDescriptor = (PENUM_DESCRIPTOR)GetUserRecordStructure(descriptor);
PEVENT_VALUE_DESCRIPTOR newField = (PEVENT_VALUE_DESCRIPTOR)GetUserRecordStructure(Entry);
newField->fieldsLink = eventDescriptor->fieldsLink;
eventDescriptor->fieldsLink = newField;
if (flagLetter) {
eventDescriptor->FlagsMask |= value;
}
CommitEventEntry(Entry);
}
return Entry;
}
PMEMORY_HEADER
RegisterEventDescriptor(PCHAR name,
uint16 nameLength,
PCHAR description,
uint16 descriptionLength)
{
return RegisterEventDescriptorImplementation(EVENT_FIELD_TYPE_szChar,
name,
nameLength,
description,
descriptionLength);
}
PMEMORY_HEADER
RegisterFieldDescriptor(PMEMORY_HEADER Descriptor,
PCHAR name,
uint32 nameLength,
uint16 offset,
uint16 type )
{
return RegisterFieldDescriptorImplementation(
EVENT_FIELD_TYPE_szChar,
Descriptor,
name,
nameLength,
offset,
type);
}
PMEMORY_HEADER
RegisterGenericFieldDescriptor(PMEMORY_HEADER event,
PCHAR name,
uint32 nameLength,
uint16 offset,
uint16 size,
UIntPtr typeFieldDescriptor)
{
return RegisterGenericFieldDescriptorImplementation( EVENT_FIELD_TYPE_szChar,
event,
name,
nameLength,
offset,
size,
typeFieldDescriptor);
}
PMEMORY_HEADER
RegisterEnumDescriptor(PCHAR name,
uint16 nameLength,
uint16 type)
{
return RegisterEnumDescriptorImplementation(EVENT_FIELD_TYPE_szChar,
name,
nameLength,
type);
}
PMEMORY_HEADER
RegisterValueDescriptor(PMEMORY_HEADER descriptor,
PCHAR name,
uint32 nameLength,
uint64 value,
uint8 flagLetter)
{
return RegisterValueDescriptorImplementation(EVENT_FIELD_TYPE_szChar,
descriptor,
name,
nameLength,
value,
flagLetter);
}
// Declare the system event structures
void
InitializeRegistrationSystem(void * buffer, size_t size)
{
// Create a bufffer which does not recycle memory
UIntPtr LocalStorageHandle = Class_Microsoft_Singularity_Eventing_MemoryStorage::
g_MemoryStorageCreateImpl(MEMORY_STORAGE_FLAGS_PERMANENT, (uint8 *)buffer, (uint32)size, 0);
RegisterRepositoryStorage(HANDLE_TO_STORAGE(LocalStorageHandle));
}
void
RegisterNativeTypes()
{
//
// Use this opportunity to validate the assumptions around the basic definition
// layouts
//
#define _VALIDATE_INVARIANTS
#define _LOGGING_TO_REPOSITORY
#define DECLARE_STRUCTURE_BEGIN(x,d) \
{ \
PMEMORY_HEADER __Event; \
__Event = RegisterEventDescriptor("System."#x, sizeof("System."#x) - 1, d, sizeof(d)); \
if (__Event != NULL) { \
PMEMORY_HEADER __Field; \
Handle_##x = (UIntPtr)__Event;
#define DECLARE_ENUM_BEGIN(x,t) \
{ \
PMEMORY_HEADER __Event; \
__Event = RegisterEnumDescriptor("System."#x, sizeof("System."#x) - 1, EVENT_FIELD_##t); \
if (__Event != NULL) { \
PMEMORY_HEADER __Field; \
Handle_##x = (UIntPtr)__Event;
#define DECLARE_STRUCTURE_END(x) }}
#define DECLARE_ENUM_END DECLARE_STRUCTURE_END
#define DECLARE_FIELD(s,t,n) \
__Field = RegisterFieldDescriptor(__Event, #n, sizeof(#n), offsetof(s, n), EVENT_FIELD_##t);
#define DECLARE_SPECIAL_FIELD(s,t,n) \
__Field = RegisterFieldDescriptor(__Event, #n, sizeof(#n), offsetof(s, n), \
EVENT_FIELD_TYPE_UIntPtr);
#define DECLARE_EXTENDED_ARRAY_FIELD(s,t,n) \
__Field = RegisterFieldDescriptor(__Event, #n, sizeof(#n), offsetof(s, n), \
EVENT_FIELD_TYPE_arrayType | EVENT_FIELD_##t);
#define DECLARE_VALUE(s,v,f,n) \
__Field = RegisterValueDescriptor(__Event, #n, sizeof(#n), v, f);
#define DECLARE_GENERIC_FIELD(s,t,sz,t1,n) \
__Field = RegisterGenericFieldDescriptor(__Event, #n, sizeof(#n), offsetof(s, n), sz, Handle_##t1);
#include "SystemEvents.inl"
#undef _LOGGING_TO_REPOSITORY
#ifdef SINGULARITY_KERNEL
//
// For apps, discard the use of handles that have been registered, since these shared
// events are going to use the system handles
//
MonitoringTypeHandle = Handle_MONITORING_ENTRY;
TracingTypeHandle = Handle_LEGACY_LOG_ENTRY;
#endif
}
//
///////////////////////////////////////////////////////////////// End of File.