private static unsafe bool FindCounter(int counterNameHashCode, string counterName, CounterEntry *firstCounterPointer, CounterEntry **returnCounterPointerReference) { CounterEntry *currentCounterPointer = firstCounterPointer; CounterEntry *previousCounterPointer = firstCounterPointer; for (;;) { WaitForCriticalSection(&(currentCounterPointer->SpinLock)); if (currentCounterPointer->CounterNameHashCode == counterNameHashCode) { string currentCounterName = Marshal.PtrToStringUni((IntPtr)(ResolveOffset(currentCounterPointer->CounterNameOffset))); if (counterName == currentCounterName) { *returnCounterPointerReference = currentCounterPointer; return(true); } } previousCounterPointer = currentCounterPointer; if (currentCounterPointer->NextCounterOffset != 0) { currentCounterPointer = (CounterEntry *)(ResolveOffset(currentCounterPointer->NextCounterOffset)); } else { *returnCounterPointerReference = previousCounterPointer; return(false); } } }
internal unsafe long IncrementBy(long value) { if (fileMapping.IsGhosted) { return(0); } CounterEntry *counterEntry = (CounterEntry *)this.counterEntryPointer; long newValue; int spinCount = 10000; while (!EnterCriticalSection(&(counterEntry->SpinLock)) && spinCount > 0) { --spinCount; } try { newValue = counterEntry->Value + value; counterEntry->Value = newValue; } finally { ExitCriticalSection(&(counterEntry->SpinLock)); } return(newValue); }
public static unsafe long GetCounterValue(int categoryNameHashCode, string categoryName, int counterNameHashCode, string counterName, int instanceNameHashCode, string instanceName) { CategoryEntry *categoryPointer = (CategoryEntry *)(ResolveOffset(4)); if (!FindCategory(categoryNameHashCode, categoryName, categoryPointer, &categoryPointer)) { return(0); } InstanceEntry *instancePointer = (InstanceEntry *)(ResolveOffset(categoryPointer->FirstInstanceOffset)); if (!FindInstance(instanceNameHashCode, instanceName, instancePointer, &instancePointer)) { return(0); } CounterEntry *counterPointer = (CounterEntry *)(ResolveOffset(instancePointer->FirstCounterOffset)); if (!FindCounter(counterNameHashCode, counterName, counterPointer, &counterPointer)) { return(0); } return(counterPointer->Value); }
private static unsafe int CreateCounter(int counterNameHashCode, string counterName) { int counterNameLength = (counterName.Length + 1) * 2; IntPtr baseAddress = FileView.FileViewAddress; int totalSize = sizeof(CounterEntry) + counterNameLength; //Need to guarantee that the location where we store the counter //value, is DWORD aligend, so 64 bit interlocked operations don't fail. if (totalSize % 8 != 0) { totalSize = totalSize + (8 - (totalSize % 8)); } int freeMemoryOffset = SafeNativeMethods.InterlockedExchangeAdd(baseAddress, totalSize); if (freeMemoryOffset + totalSize > FileView.FileMappingSize) { throw new InvalidOperationException(SR.GetString(SR.CountersOOM)); } CounterEntry *newCounterEntryPointer = (CounterEntry *)((long)baseAddress + freeMemoryOffset); newCounterEntryPointer->CounterNameOffset = freeMemoryOffset + sizeof(CounterEntry); newCounterEntryPointer->CounterNameHashCode = counterNameHashCode; newCounterEntryPointer->NextCounterOffset = 0; newCounterEntryPointer->Value = 0; Marshal.Copy(counterName.ToCharArray(), 0, (IntPtr)((long)baseAddress + newCounterEntryPointer->CounterNameOffset), counterName.Length); return(freeMemoryOffset); }
internal static unsafe void RemoveInstance(string categoryName, string instanceName) { if (instanceName == "" || instanceName == null) { return; } int categoryNameHashCode = categoryName.GetHashCode(); int instanceNameHashCode = instanceName.GetHashCode(); CategoryEntry *categoryPointer = (CategoryEntry *)(ResolveOffset(4)); if (!FindCategory(categoryNameHashCode, categoryName, categoryPointer, &categoryPointer)) { return; } InstanceEntry *instancePointer = (InstanceEntry *)(ResolveOffset(categoryPointer->FirstInstanceOffset)); if (!FindInstance(instanceNameHashCode, instanceName, instancePointer, &instancePointer)) { return; } while (!EnterCriticalSection(&(instancePointer->SpinLock))) { WaitForCriticalSection(&(instancePointer->SpinLock)); } try { instancePointer->RefCount = 0; //Clear counter instance values CounterEntry *currentCounterPointer = null; if (instancePointer->FirstCounterOffset != 0) { currentCounterPointer = (CounterEntry *)(ResolveOffset(instancePointer->FirstCounterOffset)); } while (currentCounterPointer != null) { currentCounterPointer->Value = 0; if (currentCounterPointer->NextCounterOffset != 0) { currentCounterPointer = (CounterEntry *)(ResolveOffset(currentCounterPointer->NextCounterOffset)); } else { currentCounterPointer = null; } } } finally { ExitCriticalSection(&(instancePointer->SpinLock)); } }
internal unsafe long Decrement() { if (fileMapping.IsGhosted) { return(0); } CounterEntry *counterEntry = (CounterEntry *)this.counterEntryPointer; return(Interlocked.Decrement(ref counterEntry->Value)); }
internal unsafe SharedPerformanceCounter(string catName, string counterName, string instanceName, PerformanceCounterInstanceLifetime lifetime) { this.InitialOffset = 4; this.thisInstanceOffset = -1; this.categoryName = catName; this.categoryNameHashCode = GetWstrHashCode(this.categoryName); this.categoryData = this.GetCategoryData(); if (this.categoryData.UseUniqueSharedMemory) { if ((instanceName != null) && (instanceName.Length > 0x7f)) { throw new InvalidOperationException(SR.GetString("InstanceNameTooLong")); } } else if (lifetime != PerformanceCounterInstanceLifetime.Global) { throw new InvalidOperationException(SR.GetString("ProcessLifetimeNotValidInGlobal")); } if (((counterName != null) && (instanceName != null)) && this.categoryData.CounterNames.Contains(counterName)) { this.counterEntryPointer = this.GetCounter(counterName, instanceName, this.categoryData.EnableReuse, lifetime); } }
private static unsafe IntPtr GetCounter(string categoryName, string counterName, string instanceName) { int categoryNameHashCode = categoryName.GetHashCode(); int counterNameHashCode = counterName.GetHashCode(); int instanceNameHashCode; if (instanceName != "" && instanceName != null) { instanceNameHashCode = instanceName.GetHashCode(); } else { instanceNameHashCode = SingleInstanceHashCode; instanceName = SingleInstanceName; } CategoryEntry *categoryPointer = (CategoryEntry *)(ResolveOffset(4)); while (!FindCategory(categoryNameHashCode, categoryName, categoryPointer, &categoryPointer)) { if (EnterCriticalSection(&(categoryPointer->SpinLock))) { try { int newCategoryOffset = CreateCategory(categoryNameHashCode, categoryName, counterNameHashCode, counterName, instanceNameHashCode, instanceName); //If not the first category node, link it. if (newCategoryOffset != 4) { categoryPointer->NextCategoryOffset = newCategoryOffset; } return((IntPtr)(ResolveOffset(((InstanceEntry *)(ResolveOffset(((CategoryEntry *)(ResolveOffset(newCategoryOffset)))->FirstInstanceOffset)))->FirstCounterOffset))); } finally { ExitCriticalSection(&(categoryPointer->SpinLock)); } } } InstanceEntry *instancePointer = (InstanceEntry *)(ResolveOffset(categoryPointer->FirstInstanceOffset)); while (!FindInstance(instanceNameHashCode, instanceName, instancePointer, &instancePointer)) { if (EnterCriticalSection(&(instancePointer->SpinLock))) { try { int newInstanceOffset = CreateInstance(counterNameHashCode, counterName, instanceNameHashCode, instanceName); //This will never be the first instance node, no need to check instancePointer->NextInstanceOffset = newInstanceOffset; return((IntPtr)(ResolveOffset(((InstanceEntry *)(ResolveOffset(newInstanceOffset)))->FirstCounterOffset))); } finally { ExitCriticalSection(&(instancePointer->SpinLock)); } } } CounterEntry *counterPointer = (CounterEntry *)(ResolveOffset(instancePointer->FirstCounterOffset)); while (!FindCounter(counterNameHashCode, counterName, counterPointer, &counterPointer)) { if (EnterCriticalSection(&(counterPointer->SpinLock))) { try { int newCounterOffset = CreateCounter(counterNameHashCode, counterName); //This will never be the first counter node, no need to check counterPointer->NextCounterOffset = newCounterOffset; return((IntPtr)(ResolveOffset(newCounterOffset))); } finally { ExitCriticalSection(&(counterPointer->SpinLock)); } } } return((IntPtr)counterPointer); }
internal unsafe SharedPerformanceCounter(string catName, string counterName, string instanceName, PerformanceCounterInstanceLifetime lifetime) { this.categoryName = catName; this.categoryNameHashCode = GetWstrHashCode(categoryName); categoryData = GetCategoryData(); // Check that the instance name isn't too long if we're using the new shared memory. // We allocate InstanceNameSlotSize bytes in the shared memory if (categoryData.UseUniqueSharedMemory) { if (instanceName != null && instanceName.Length > InstanceNameMaxLength) throw new InvalidOperationException(SR.GetString(SR.InstanceNameTooLong)); } else { if (lifetime != PerformanceCounterInstanceLifetime.Global) throw new InvalidOperationException(SR.GetString(SR.ProcessLifetimeNotValidInGlobal)); } if (counterName != null && instanceName != null) { if (!categoryData.CounterNames.Contains(counterName)) Debug.Assert(false, "Counter " + counterName + " does not exist in category " + catName); else this.counterEntryPointer = GetCounter(counterName, instanceName, categoryData.EnableReuse, lifetime); } }