예제 #1
0
        /// <summary>
        /// Performs binary search of an address on the list.
        /// </summary>
        /// <param name="address">Address to search</param>
        /// <returns>Index of the item, or complement of the index of the nearest item with lower value</returns>
        private int BinarySearch(ulong address)
        {
            int left  = 0;
            int right = _items.Count - 1;

            while (left <= right)
            {
                int range = right - left;

                int middle = left + (range >> 1);

                CounterEntry item = _items[middle];

                if (item.Address == address)
                {
                    return(middle);
                }

                if (address < item.Address)
                {
                    right = middle - 1;
                }
                else
                {
                    left = middle + 1;
                }
            }

            return(~left);
        }
예제 #2
0
        public async Task <int> GetCounterAsync(
            string address,
            string head,
            string rpcNodeUri)
        {
            var currentCounter = await GetCounterFromRpcAsync(address, head, rpcNodeUri)
                                 .ConfigureAwait(false);

            // update offline counter if need
            lock (_offlineCounters)
            {
                if (_offlineCounters.TryGetValue(address, out var offlineCounterEntry))
                {
                    if (offlineCounterEntry.Value < currentCounter ||
                        DateTimeOffset.UtcNow > offlineCounterEntry.Expiration)
                    {
                        _offlineCounters[address] = new CounterEntry
                        {
                            Value      = currentCounter,
                            Expiration = DateTimeOffset.UtcNow + ExpirationPeriod
                        };
                    }
                }
                else
                {
                    _offlineCounters[address] = new CounterEntry
                    {
                        Value      = currentCounter,
                        Expiration = DateTimeOffset.UtcNow + ExpirationPeriod
                    };
                }
            }

            return(++currentCounter);
        }
예제 #3
0
        public async Task <int> GetCounter(
            Atomex.Tezos tezos,
            string address,
            JObject head,
            bool ignoreCache = false)
        {
            var rpc = new Rpc(tezos.RpcNodeUri);

            var account = await rpc
                          .GetAccountForBlock(head["hash"].ToString(), address)
                          .ConfigureAwait(false);

            var counter = int.Parse(account["counter"].ToString());

            lock (_syncRoot)
            {
                if (_counters.TryGetValue(address, out var offlineCounter))
                {
                    if (!ignoreCache &&
                        offlineCounter.Value > counter &&
                        DateTime.UtcNow - offlineCounter.LastUpdatedTimeUtc <= ExpirationTimeOut)
                    {
                        return(++offlineCounter.Value);
                    }
                    else
                    {
                        //++counter;
                        _counters[address] = new CounterEntry
                        {
                            Value = ignoreCache ? counter : counter + 1,
                            LastUpdatedTimeUtc = DateTime.UtcNow
                        };

                        return(++counter);
                    }
                }
                else
                {
                    //++counter;
                    _counters.Add(address, new CounterEntry
                    {
                        Value = ignoreCache ? counter : counter + 1,
                        LastUpdatedTimeUtc = DateTime.UtcNow
                    });

                    return(++counter);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Adds a new counter to the counter cache, or updates a existing one.
        /// </summary>
        /// <param name="gpuVa">GPU virtual address where the counter will be written in memory</param>
        public void AddOrUpdate(ulong gpuVa, ICounterEvent evt)
        {
            int index = BinarySearch(gpuVa);

            CounterEntry entry = new CounterEntry(gpuVa, evt);

            if (index < 0)
            {
                _items.Insert(~index, entry);
            }
            else
            {
                _items[index] = entry;
            }
        }
 private static unsafe long AddToValue(CounterEntry* counterEntry, long addend)
 {
     if (IsMisaligned(counterEntry))
     {
         CounterEntryMisaligned* misalignedPtr = (CounterEntryMisaligned*) counterEntry;
         ulong num = (ulong) misalignedPtr->Value_hi;
         num = num << 0x20;
         num |= (ulong) misalignedPtr->Value_lo;
         num += (ulong) addend;
         misalignedPtr->Value_hi = (int) (num >> 0x20);
         misalignedPtr->Value_lo = (int) (num & 0xffffffffL);
         return (long) num;
     }
     return Interlocked.Add(ref counterEntry.Value, addend);
 }
예제 #6
0
        private unsafe long GetPerfCounterValue(ClrObject perfCounter)
        {
            if (perfCounter == null)
            {
                return(0);
            }
            ulong       entryPoint = perfCounter.ReadField <ulong>("counterEntryPointer");
            int         v          = sizeof(CounterEntry);
            Span <byte> buffer     = new byte[v];
            int         read       = Target.DataReader.Read(entryPoint, buffer);

            fixed(byte *ptr = buffer)
            {
                CounterEntry counterEntry = *(CounterEntry *)ptr;

                return(counterEntry.Value);
            }
        }
예제 #7
0
        public async Task <int> GetOfflineCounterAsync(
            string address,
            string head,
            string rpcNodeUri,
            int numberOfCounters = 1)
        {
            var currentCounter = await GetCounterFromRpcAsync(address, head, rpcNodeUri)
                                 .ConfigureAwait(false);

            lock (_offlineCounters)
            {
                if (_offlineCounters.TryGetValue(address, out var offlineCounterEntry))
                {
                    // update offline counter
                    var offlineCounter = offlineCounterEntry.Value <currentCounter || DateTimeOffset.UtcNow> offlineCounterEntry.Expiration
                        ? currentCounter
                        : offlineCounterEntry.Value;

                    _offlineCounters[address] = new CounterEntry
                    {
                        Value      = offlineCounter + numberOfCounters,
                        Expiration = DateTimeOffset.UtcNow + ExpirationPeriod
                    };

                    return(++offlineCounter);
                }
                else
                {
                    _offlineCounters[address] = new CounterEntry
                    {
                        Value      = currentCounter + numberOfCounters,
                        Expiration = DateTimeOffset.UtcNow + ExpirationPeriod
                    };

                    return(++currentCounter);
                }
            }
        }
 private static unsafe long GetValue(CounterEntry* counterEntry)
 {
     if (IsMisaligned(counterEntry))
     {
         CounterEntryMisaligned* misalignedPtr = (CounterEntryMisaligned*) counterEntry;
         ulong num = (ulong) misalignedPtr->Value_hi;
         num = num << 0x20;
         num |= (ulong) misalignedPtr->Value_lo;
         return (long) num;
     }
     return counterEntry.Value;
 }
        private unsafe bool FindCounter(int counterNameHashCode, string counterName, InstanceEntry* instancePointer, CounterEntry** returnCounterPointerReference) {
            CounterEntry* currentCounterPointer = (CounterEntry*)(ResolveOffset(instancePointer->FirstCounterOffset, CounterEntrySize));
            CounterEntry* previousCounterPointer = currentCounterPointer;
            for(;;) {
                if (currentCounterPointer->CounterNameHashCode == counterNameHashCode) {
                    if (StringEquals(counterName, currentCounterPointer->CounterNameOffset)) {
                        *returnCounterPointerReference = currentCounterPointer;
                        return true;
                    }
                }

                previousCounterPointer = currentCounterPointer;
                if (currentCounterPointer->NextCounterOffset != 0)
                    currentCounterPointer = (CounterEntry*)(ResolveOffset(currentCounterPointer->NextCounterOffset, CounterEntrySize));
                else {
                    *returnCounterPointerReference = previousCounterPointer;
                    return false;
                }
            }
        }
        private unsafe int CreateCounter(CounterEntry* lastCounterPointer, 
                                           int counterNameHashCode, string counterName) {
            int counterNameLength = (counterName.Length + 1) * 2;
            int totalSize = sizeof(CounterEntry) + counterNameLength;
            int alignmentAdjustment;
            int freeMemoryOffset;

            Debug.Assert(!categoryData.UseUniqueSharedMemory, "We should never be calling CreateCounter in the unique shared memory");
            freeMemoryOffset = CalculateAndAllocateMemory(totalSize, out alignmentAdjustment);

            freeMemoryOffset += alignmentAdjustment;

            long nextPtr = ResolveOffset(freeMemoryOffset, totalSize);
            CounterEntry* newCounterEntryPointer = (CounterEntry*) nextPtr;
            nextPtr += sizeof(CounterEntry);

            newCounterEntryPointer->CounterNameOffset = (int) (nextPtr - baseAddress);
            newCounterEntryPointer->CounterNameHashCode = counterNameHashCode;
            newCounterEntryPointer->NextCounterOffset = 0;
            SetValue(newCounterEntryPointer, 0);
            SafeMarshalCopy(counterName, (IntPtr)nextPtr);

            Debug.Assert(nextPtr + counterNameLength - baseAddress == freeMemoryOffset + totalSize, "We should have used all of the space we requested at this point");

            lastCounterPointer->NextCounterOffset = (int) ((long) newCounterEntryPointer - baseAddress);
            return freeMemoryOffset;
        }
 private static unsafe bool IsMisaligned(CounterEntry* counterEntry) {
     return (( (Int64)counterEntry & 0x7) != 0);
 }
 private static unsafe void SetValue(CounterEntry* counterEntry, long value) {
     if (IsMisaligned(counterEntry)) {
         CounterEntryMisaligned* entry = (CounterEntryMisaligned*) counterEntry;
         entry->Value_lo = (int) (value & 0xffffffff);
         entry->Value_hi = (int) (value >> 32);
     }
     else
         counterEntry->Value = value;
 }
 private static unsafe long IncrementUnaligned(CounterEntry* counterEntry) {
     if (IsMisaligned(counterEntry)) 
         return AddToValue(counterEntry, 1);
     else
         return Interlocked.Increment(ref counterEntry->Value);
 }
        private static unsafe long GetValue(CounterEntry* counterEntry) {
            if (IsMisaligned(counterEntry)) {
                ulong value;
                CounterEntryMisaligned* entry = (CounterEntryMisaligned*) counterEntry;
                value = (uint)entry->Value_hi;                
                value <<= 32;
                value |= (uint)entry->Value_lo;

                return (long) value;
            }
            else
                return counterEntry->Value;
        }
        private static unsafe long AddToValue(CounterEntry* counterEntry, long addend) {
            // Called while holding a lock - shouldn't have to worry about
            // reading misaligned data & getting old vs. new parts of an Int64.
            if (IsMisaligned(counterEntry)) {
                ulong newvalue;

                CounterEntryMisaligned* entry = (CounterEntryMisaligned*) counterEntry;
                newvalue = (uint)entry->Value_hi;                
                newvalue <<= 32;
                newvalue |= (uint)entry->Value_lo;


                newvalue = (ulong) ((long) newvalue + addend);

                entry->Value_hi = (int) (newvalue >> 32);
                entry->Value_lo = (int) (newvalue & 0xffffffff);

                return (long) newvalue;
            }
            else 
                return Interlocked.Add(ref counterEntry->Value, addend);
        }
 private static unsafe bool IsMisaligned(CounterEntry* counterEntry)
 {
     return ((((ulong) counterEntry) & 7L) != 0L);
 }
 private static unsafe void SetValue(CounterEntry* counterEntry, long value)
 {
     if (IsMisaligned(counterEntry))
     {
         CounterEntryMisaligned* misalignedPtr = (CounterEntryMisaligned*) counterEntry;
         misalignedPtr->Value_lo = (int) (((ulong) value) & 0xffffffffL);
         misalignedPtr->Value_hi = (int) (value >> 0x20);
     }
     else
     {
         counterEntry.Value = value;
     }
 }
 private unsafe bool FindCounter(int counterNameHashCode, string counterName, InstanceEntry* instancePointer, CounterEntry** returnCounterPointerReference)
 {
     CounterEntry* entryPtr = (CounterEntry*) this.ResolveOffset(instancePointer.FirstCounterOffset, CounterEntrySize);
     CounterEntry* entryPtr2 = entryPtr;
 Label_0015:
     if ((entryPtr->CounterNameHashCode == counterNameHashCode) && this.StringEquals(counterName, entryPtr->CounterNameOffset))
     {
         *((IntPtr*) returnCounterPointerReference) = entryPtr;
         return true;
     }
     entryPtr2 = entryPtr;
     if (entryPtr->NextCounterOffset != 0)
     {
         entryPtr = (CounterEntry*) this.ResolveOffset(entryPtr->NextCounterOffset, CounterEntrySize);
         goto Label_0015;
     }
     *((IntPtr*) returnCounterPointerReference) = entryPtr2;
     return false;
 }
 private static unsafe long DecrementUnaligned(CounterEntry* counterEntry)
 {
     if (IsMisaligned(counterEntry))
     {
         return AddToValue(counterEntry, -1L);
     }
     return Interlocked.Decrement(ref counterEntry.Value);
 }
 private unsafe int CreateCounter(CounterEntry* lastCounterPointer, int counterNameHashCode, string counterName)
 {
     int num3;
     int num = (counterName.Length + 1) * 2;
     int totalSize = sizeof(CounterEntry) + num;
     int offset = this.CalculateAndAllocateMemory(totalSize, out num3) + num3;
     long num5 = this.ResolveOffset(offset, totalSize);
     CounterEntry* counterEntry = (CounterEntry*) num5;
     num5 += sizeof(CounterEntry);
     counterEntry->CounterNameOffset = (int) (num5 - this.baseAddress);
     counterEntry->CounterNameHashCode = counterNameHashCode;
     counterEntry->NextCounterOffset = 0;
     SetValue(counterEntry, 0L);
     SafeMarshalCopy(counterName, (IntPtr) num5);
     lastCounterPointer.NextCounterOffset = (int) (((ulong) counterEntry) - this.baseAddress);
     return offset;
 }