ArrayPoolEventSource.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Diagnostics.Tracing;
  5. namespace System.Buffers
  6. {
  7. [EventSource(Guid = "0866B2B8-5CEF-5DB9-2612-0C0FFD814A44", Name = "System.Buffers.ArrayPoolEventSource")]
  8. internal sealed class ArrayPoolEventSource : EventSource
  9. {
  10. internal readonly static ArrayPoolEventSource Log = new ArrayPoolEventSource();
  11. /// <summary>The reason for a BufferAllocated event.</summary>
  12. internal enum BufferAllocatedReason : int
  13. {
  14. /// <summary>The pool is allocating a buffer to be pooled in a bucket.</summary>
  15. Pooled,
  16. /// <summary>The requested buffer size was too large to be pooled.</summary>
  17. OverMaximumSize,
  18. /// <summary>The pool has already allocated for pooling as many buffers of a particular size as it's allowed.</summary>
  19. PoolExhausted
  20. }
  21. // The ArrayPoolEventSource GUID is {0866b2b8-5cef-5db9-2612-0c0ffd814a44}
  22. private ArrayPoolEventSource() : base(new Guid(0x0866b2b8, 0x5cef, 0x5db9, 0x26, 0x12, 0x0c, 0x0f, 0xfd, 0x81, 0x4a, 0x44), "System.Buffers.ArrayPoolEventSource") { }
  23. /// <summary>
  24. /// Event for when a buffer is rented. This is invoked once for every successful call to Rent,
  25. /// regardless of whether a buffer is allocated or a buffer is taken from the pool. In a
  26. /// perfect situation where all rented buffers are returned, we expect to see the number
  27. /// of BufferRented events exactly match the number of BuferReturned events, with the number
  28. /// of BufferAllocated events being less than or equal to those numbers (ideally significantly
  29. /// less than).
  30. /// </summary>
  31. [Event(1, Level = EventLevel.Verbose)]
  32. internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
  33. {
  34. EventData* payload = stackalloc EventData[4];
  35. payload[0].Size = sizeof(int);
  36. payload[0].DataPointer = ((IntPtr)(&bufferId));
  37. payload[0].Reserved = 0;
  38. payload[1].Size = sizeof(int);
  39. payload[1].DataPointer = ((IntPtr)(&bufferSize));
  40. payload[1].Reserved = 0;
  41. payload[2].Size = sizeof(int);
  42. payload[2].DataPointer = ((IntPtr)(&poolId));
  43. payload[2].Reserved = 0;
  44. payload[3].Size = sizeof(int);
  45. payload[3].DataPointer = ((IntPtr)(&bucketId));
  46. payload[3].Reserved = 0;
  47. WriteEventCore(1, 4, payload);
  48. }
  49. /// <summary>
  50. /// Event for when a buffer is allocated by the pool. In an ideal situation, the number
  51. /// of BufferAllocated events is significantly smaller than the number of BufferRented and
  52. /// BufferReturned events.
  53. /// </summary>
  54. [Event(2, Level = EventLevel.Informational)]
  55. internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
  56. {
  57. EventData* payload = stackalloc EventData[5];
  58. payload[0].Size = sizeof(int);
  59. payload[0].DataPointer = ((IntPtr)(&bufferId));
  60. payload[0].Reserved = 0;
  61. payload[1].Size = sizeof(int);
  62. payload[1].DataPointer = ((IntPtr)(&bufferSize));
  63. payload[1].Reserved = 0;
  64. payload[2].Size = sizeof(int);
  65. payload[2].DataPointer = ((IntPtr)(&poolId));
  66. payload[2].Reserved = 0;
  67. payload[3].Size = sizeof(int);
  68. payload[3].DataPointer = ((IntPtr)(&bucketId));
  69. payload[3].Reserved = 0;
  70. payload[4].Size = sizeof(BufferAllocatedReason);
  71. payload[4].DataPointer = ((IntPtr)(&reason));
  72. payload[4].Reserved = 0;
  73. WriteEventCore(2, 5, payload);
  74. }
  75. /// <summary>
  76. /// Event raised when a buffer is returned to the pool. This event is raised regardless of whether
  77. /// the returned buffer is stored or dropped. In an ideal situation, the number of BufferReturned
  78. /// events exactly matches the number of BufferRented events.
  79. /// </summary>
  80. [Event(3, Level = EventLevel.Verbose)]
  81. internal void BufferReturned(int bufferId, int bufferSize, int poolId) => WriteEvent(3, bufferId, bufferSize, poolId);
  82. /// <summary>
  83. /// Event raised when we attempt to free a buffer due to inactivity or memory pressure (by no longer
  84. /// referencing it). It is possible (although not commmon) this buffer could be rented as we attempt
  85. /// to free it. A rent event before or after this event for the same ID, is a rare, but expected case.
  86. /// </summary>
  87. [Event(4, Level = EventLevel.Informational)]
  88. internal void BufferTrimmed(int bufferId, int bufferSize, int poolId) => WriteEvent(4, bufferId, bufferSize, poolId);
  89. /// <summary>
  90. /// Event raised when we check to trim buffers.
  91. /// </summary>
  92. [Event(5, Level = EventLevel.Informational)]
  93. internal void BufferTrimPoll(int milliseconds, int pressure) => WriteEvent(5, milliseconds, pressure);
  94. }
  95. }