예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        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);
     }
 }
예제 #8
0
        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);
            }
        }