bmem.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (c) 2023 Lain Bailey <[email protected]>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "base.h"
  19. #include "bmem.h"
  20. #include "platform.h"
  21. #include "threading.h"
  22. /*
  23. * NOTE: totally jacked the mem alignment trick from ffmpeg, credit to them:
  24. * http://www.ffmpeg.org/
  25. */
  26. #define ALIGNMENT 32
  27. /*
  28. * Attention, intrepid adventurers, exploring the depths of the libobs code!
  29. *
  30. * There used to be a TODO comment here saying that we should use memalign on
  31. * non-Windows platforms. However, since *nix/POSIX systems do not provide an
  32. * aligned realloc(), this is currently not (easily) achievable.
  33. * So while the use of posix_memalign()/memalign() would be a fairly trivial
  34. * change, it would also ruin our memory alignment for some reallocated memory
  35. * on those platforms.
  36. */
  37. #if defined(_WIN32)
  38. #define ALIGNED_MALLOC 1
  39. #else
  40. #define ALIGNMENT_HACK 1
  41. #endif
  42. static void *a_malloc(size_t size)
  43. {
  44. #ifdef ALIGNED_MALLOC
  45. return _aligned_malloc(size, ALIGNMENT);
  46. #elif ALIGNMENT_HACK
  47. void *ptr = NULL;
  48. long diff;
  49. ptr = malloc(size + ALIGNMENT);
  50. if (ptr) {
  51. diff = ((~(long)ptr) & (ALIGNMENT - 1)) + 1;
  52. ptr = (char *)ptr + diff;
  53. ((char *)ptr)[-1] = (char)diff;
  54. }
  55. return ptr;
  56. #else
  57. return malloc(size);
  58. #endif
  59. }
  60. static void *a_realloc(void *ptr, size_t size)
  61. {
  62. #ifdef ALIGNED_MALLOC
  63. return _aligned_realloc(ptr, size, ALIGNMENT);
  64. #elif ALIGNMENT_HACK
  65. long diff;
  66. if (!ptr)
  67. return a_malloc(size);
  68. diff = ((char *)ptr)[-1];
  69. ptr = realloc((char *)ptr - diff, size + diff);
  70. if (ptr)
  71. ptr = (char *)ptr + diff;
  72. return ptr;
  73. #else
  74. return realloc(ptr, size);
  75. #endif
  76. }
  77. static void a_free(void *ptr)
  78. {
  79. #ifdef ALIGNED_MALLOC
  80. _aligned_free(ptr);
  81. #elif ALIGNMENT_HACK
  82. if (ptr)
  83. free((char *)ptr - ((char *)ptr)[-1]);
  84. #else
  85. free(ptr);
  86. #endif
  87. }
  88. static long num_allocs = 0;
  89. void *bmalloc(size_t size)
  90. {
  91. if (!size) {
  92. blog(LOG_ERROR,
  93. "bmalloc: Allocating 0 bytes is broken behavior, please "
  94. "fix your code! This will crash in future versions of "
  95. "OBS.");
  96. size = 1;
  97. }
  98. void *ptr = a_malloc(size);
  99. if (!ptr) {
  100. os_breakpoint();
  101. bcrash("Out of memory while trying to allocate %lu bytes",
  102. (unsigned long)size);
  103. }
  104. os_atomic_inc_long(&num_allocs);
  105. return ptr;
  106. }
  107. void *brealloc(void *ptr, size_t size)
  108. {
  109. if (!ptr)
  110. os_atomic_inc_long(&num_allocs);
  111. if (!size) {
  112. blog(LOG_ERROR,
  113. "brealloc: Allocating 0 bytes is broken behavior, please "
  114. "fix your code! This will crash in future versions of "
  115. "OBS.");
  116. size = 1;
  117. }
  118. ptr = a_realloc(ptr, size);
  119. if (!ptr) {
  120. os_breakpoint();
  121. bcrash("Out of memory while trying to allocate %lu bytes",
  122. (unsigned long)size);
  123. }
  124. return ptr;
  125. }
  126. void bfree(void *ptr)
  127. {
  128. if (ptr) {
  129. os_atomic_dec_long(&num_allocs);
  130. a_free(ptr);
  131. }
  132. }
  133. long bnum_allocs(void)
  134. {
  135. return num_allocs;
  136. }
  137. int base_get_alignment(void)
  138. {
  139. return ALIGNMENT;
  140. }
  141. void *bmemdup(const void *ptr, size_t size)
  142. {
  143. void *out = bmalloc(size);
  144. if (size)
  145. memcpy(out, ptr, size);
  146. return out;
  147. }