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