Buf.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include "Buf.hpp"
  14. namespace ZeroTier {
  15. #ifdef __GNUC__
  16. uintptr_t _Buf_pool = 0;
  17. #else
  18. std::atomic<uintptr_t> _Buf_pool(0);
  19. #endif
  20. void _Buf_release(void *ptr,std::size_t sz)
  21. {
  22. if (ptr) {
  23. uintptr_t bb;
  24. const uintptr_t locked = ~((uintptr_t)0);
  25. for (;;) {
  26. #ifdef __GNUC__
  27. bb = __sync_fetch_and_or(&_Buf_pool,locked); // get value of s_pool and "lock" by filling with all 1's
  28. #else
  29. bb = s_pool.fetch_or(locked);
  30. #endif
  31. if (bb != locked)
  32. break;
  33. }
  34. ((Buf<> *)ptr)->__nextInPool = bb;
  35. #ifdef __GNUC__
  36. __sync_fetch_and_and(&_Buf_pool,(uintptr_t)ptr);
  37. #else
  38. s_pool.store((uintptr_t)ptr);
  39. #endif
  40. }
  41. }
  42. void *_Buf_get()
  43. {
  44. uintptr_t bb;
  45. const uintptr_t locked = ~((uintptr_t)0);
  46. for (;;) {
  47. #ifdef __GNUC__
  48. bb = __sync_fetch_and_or(&_Buf_pool,locked); // get value of s_pool and "lock" by filling with all 1's
  49. #else
  50. bb = s_pool.fetch_or(locked);
  51. #endif
  52. if (bb != locked)
  53. break;
  54. }
  55. Buf<> *b;
  56. if (bb == 0) {
  57. #ifdef __GNUC__
  58. __sync_fetch_and_and(&_Buf_pool,bb);
  59. #else
  60. s_pool.store(bb);
  61. #endif
  62. b = (Buf<> *)malloc(sizeof(Buf<>));
  63. if (!b)
  64. return nullptr;
  65. } else {
  66. b = (Buf<> *)bb;
  67. #ifdef __GNUC__
  68. __sync_fetch_and_and(&_Buf_pool,b->__nextInPool);
  69. #else
  70. s_pool.store(b->__nextInPool);
  71. #endif
  72. }
  73. b->__refCount.zero();
  74. return (void *)b;
  75. }
  76. void freeBufPool()
  77. {
  78. uintptr_t bb;
  79. const uintptr_t locked = ~((uintptr_t)0);
  80. for (;;) {
  81. #ifdef __GNUC__
  82. bb = __sync_fetch_and_or(&_Buf_pool,locked); // get value of s_pool and "lock" by filling with all 1's
  83. #else
  84. bb = s_pool.fetch_or(locked);
  85. #endif
  86. if (bb != locked)
  87. break;
  88. }
  89. #ifdef __GNUC__
  90. __sync_fetch_and_and(&_Buf_pool,(uintptr_t)0);
  91. #else
  92. s_pool.store((uintptr_t)0);
  93. #endif
  94. while (bb != 0) {
  95. uintptr_t next = ((Buf<> *)bb)->__nextInPool;
  96. free((void *)bb);
  97. bb = next;
  98. }
  99. }
  100. } // namespace ZeroTier