ObjectPool.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System;
  2. using System.Threading;
  3. namespace Ryujinx.Common
  4. {
  5. public class ObjectPool<T>
  6. where T : class
  7. {
  8. private T _firstItem;
  9. private readonly T[] _items;
  10. private readonly Func<T> _factory;
  11. public ObjectPool(Func<T> factory, int size)
  12. {
  13. _items = new T[size - 1];
  14. _factory = factory;
  15. }
  16. public T Allocate()
  17. {
  18. T instance = _firstItem;
  19. if (instance == null || instance != Interlocked.CompareExchange(ref _firstItem, null, instance))
  20. {
  21. instance = AllocateInternal();
  22. }
  23. return instance;
  24. }
  25. private T AllocateInternal()
  26. {
  27. T[] items = _items;
  28. for (int i = 0; i < items.Length; i++)
  29. {
  30. T instance = items[i];
  31. if (instance != null && instance == Interlocked.CompareExchange(ref items[i], null, instance))
  32. {
  33. return instance;
  34. }
  35. }
  36. return _factory();
  37. }
  38. public void Release(T obj)
  39. {
  40. if (_firstItem == null)
  41. {
  42. _firstItem = obj;
  43. }
  44. else
  45. {
  46. ReleaseInternal(obj);
  47. }
  48. }
  49. private void ReleaseInternal(T obj)
  50. {
  51. T[] items = _items;
  52. for (int i = 0; i < items.Length; i++)
  53. {
  54. if (items[i] == null)
  55. {
  56. items[i] = obj;
  57. break;
  58. }
  59. }
  60. }
  61. }
  62. }