/// <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); }
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); }
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); } } }
/// <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); }
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); } }
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; }