You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
5.2KB

  1. /*
  2. * Copyright (c) 2002 Fabrice Bellard
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #ifndef AVUTIL_MEM_INTERNAL_H
  21. #define AVUTIL_MEM_INTERNAL_H
  22. #include "config.h"
  23. #include <stdint.h>
  24. #include "avassert.h"
  25. #include "mem.h"
  26. #include "version.h"
  27. #if !FF_API_DECLARE_ALIGNED
  28. /**
  29. * @def DECLARE_ALIGNED(n,t,v)
  30. * Declare a variable that is aligned in memory.
  31. *
  32. * @code{.c}
  33. * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42;
  34. * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128];
  35. *
  36. * // The default-alignment equivalent would be
  37. * uint16_t aligned_int = 42;
  38. * uint8_t aligned_array[128];
  39. * @endcode
  40. *
  41. * @param n Minimum alignment in bytes
  42. * @param t Type of the variable (or array element)
  43. * @param v Name of the variable
  44. */
  45. /**
  46. * @def DECLARE_ASM_ALIGNED(n,t,v)
  47. * Declare an aligned variable appropriate for use in inline assembly code.
  48. *
  49. * @code{.c}
  50. * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008);
  51. * @endcode
  52. *
  53. * @param n Minimum alignment in bytes
  54. * @param t Type of the variable (or array element)
  55. * @param v Name of the variable
  56. */
  57. /**
  58. * @def DECLARE_ASM_CONST(n,t,v)
  59. * Declare a static constant aligned variable appropriate for use in inline
  60. * assembly code.
  61. *
  62. * @code{.c}
  63. * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008);
  64. * @endcode
  65. *
  66. * @param n Minimum alignment in bytes
  67. * @param t Type of the variable (or array element)
  68. * @param v Name of the variable
  69. */
  70. #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
  71. #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
  72. #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
  73. #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v
  74. #elif defined(__DJGPP__)
  75. #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v
  76. #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
  77. #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
  78. #elif defined(__GNUC__) || defined(__clang__)
  79. #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v
  80. #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v
  81. #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v
  82. #elif defined(_MSC_VER)
  83. #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v
  84. #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v
  85. #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v
  86. #else
  87. #define DECLARE_ALIGNED(n,t,v) t v
  88. #define DECLARE_ASM_ALIGNED(n,t,v) t v
  89. #define DECLARE_ASM_CONST(n,t,v) static const t v
  90. #endif
  91. #endif
  92. // Some broken preprocessors need a second expansion
  93. // to be forced to tokenize __VA_ARGS__
  94. #define E1(x) x
  95. #define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \
  96. uint8_t la_##v[sizeof(t s o) + (a)]; \
  97. t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
  98. #define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \
  99. DECLARE_ALIGNED(a, t, la_##v) s o; \
  100. t (*v) o = la_##v
  101. #define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__)
  102. #if HAVE_LOCAL_ALIGNED
  103. # define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,))
  104. #else
  105. # define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,))
  106. #endif
  107. #if HAVE_LOCAL_ALIGNED
  108. # define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
  109. #else
  110. # define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,))
  111. #endif
  112. #if HAVE_LOCAL_ALIGNED
  113. # define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
  114. #else
  115. # define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,))
  116. #endif
  117. #if HAVE_LOCAL_ALIGNED
  118. # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
  119. #else
  120. # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,))
  121. #endif
  122. static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
  123. {
  124. void *val;
  125. memcpy(&val, ptr, sizeof(val));
  126. if (min_size <= *size) {
  127. av_assert0(val || !min_size);
  128. return 0;
  129. }
  130. min_size = FFMAX(min_size + min_size / 16 + 32, min_size);
  131. av_freep(ptr);
  132. val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
  133. memcpy(ptr, &val, sizeof(val));
  134. if (!val)
  135. min_size = 0;
  136. *size = min_size;
  137. return 1;
  138. }
  139. #endif /* AVUTIL_MEM_INTERNAL_H */