diff mbox series

[FFmpeg-devel,01/16] avutil/buffer: add helper to allocate aligned memory

Message ID b49ec4ef9bf9b1e7cc4407e1813b4a87b3967922.1717083799.git.averne381@gmail.com
State New
Headers show
Series NVidia Tegra hardware decoding backend | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

averne May 30, 2024, 7:43 p.m. UTC
This is useful eg. for memory-mapped buffers that need page-aligned memory, when dealing with hardware devices

Signed-off-by: averne <averne381@gmail.com>
---
 libavutil/buffer.c | 31 +++++++++++++++++++++++++++++++
 libavutil/buffer.h |  7 +++++++
 2 files changed, 38 insertions(+)

Comments

Rémi Denis-Courmont May 30, 2024, 8:38 p.m. UTC | #1
Le torstaina 30. toukokuuta 2024, 22.43.03 EEST averne a écrit :
> This is useful eg. for memory-mapped buffers that need page-aligned memory,
> when dealing with hardware devices
> 
> Signed-off-by: averne <averne381@gmail.com>
> ---
>  libavutil/buffer.c | 31 +++++++++++++++++++++++++++++++
>  libavutil/buffer.h |  7 +++++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
> index e4562a79b1..b8e357f540 100644
> --- a/libavutil/buffer.c
> +++ b/libavutil/buffer.c
> @@ -16,9 +16,14 @@
>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA */
> 
> +#include "config.h"
> +
>  #include <stdatomic.h>
>  #include <stdint.h>
>  #include <string.h>
> +#if HAVE_MALLOC_H
> +#include <malloc.h>
> +#endif
> 
>  #include "avassert.h"
>  #include "buffer_internal.h"
> @@ -100,6 +105,32 @@ AVBufferRef *av_buffer_allocz(size_t size)
>      return ret;
>  }
> 
> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align)
> +{
> +    AVBufferRef *ret = NULL;
> +    uint8_t    *data = NULL;
> +
> +#if HAVE_POSIX_MEMALIGN
> +    if (posix_memalign((void **)&data, align, size))

Invalid cast.

> +        return NULL;
> +#elif HAVE_ALIGNED_MALLOC
> +    data = aligned_alloc(align, size);
> +#elif HAVE_MEMALIGN
> +    data = memalign(align, size);
> +#else
> +    return NULL;
> +#endif
> +
> +    if (!data)
> +        return NULL;
> +
> +    ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
> +    if (!ret)
> +        av_freep(&data);
> +
> +    return ret;
> +}
> +
>  AVBufferRef *av_buffer_ref(const AVBufferRef *buf)
>  {
>      AVBufferRef *ret = av_mallocz(sizeof(*ret));
> diff --git a/libavutil/buffer.h b/libavutil/buffer.h
> index e1ef5b7f07..8422ec3453 100644
> --- a/libavutil/buffer.h
> +++ b/libavutil/buffer.h
> @@ -107,6 +107,13 @@ AVBufferRef *av_buffer_alloc(size_t size);
>   */
>  AVBufferRef *av_buffer_allocz(size_t size);
> 
> +/**
> + * Allocate an AVBuffer of the given size and alignment.
> + *
> + * @return an AVBufferRef of given size or NULL when out of memory
> + */
> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align);
> +
>  /**
>   * Always treat the buffer as read-only, even when it has only one
>   * reference.
averne May 31, 2024, 9:06 p.m. UTC | #2
Le 30/05/2024 à 22:38, Rémi Denis-Courmont a écrit :
> Le torstaina 30. toukokuuta 2024, 22.43.03 EEST averne a écrit :
>> This is useful eg. for memory-mapped buffers that need page-aligned memory,
>> when dealing with hardware devices
>>
>> Signed-off-by: averne <averne381@gmail.com>
>> ---
>>  libavutil/buffer.c | 31 +++++++++++++++++++++++++++++++
>>  libavutil/buffer.h |  7 +++++++
>>  2 files changed, 38 insertions(+)
>>
>> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
>> index e4562a79b1..b8e357f540 100644
>> --- a/libavutil/buffer.c
>> +++ b/libavutil/buffer.c
>> @@ -16,9 +16,14 @@
>>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
>> USA */
>>
>> +#include "config.h"
>> +
>>  #include <stdatomic.h>
>>  #include <stdint.h>
>>  #include <string.h>
>> +#if HAVE_MALLOC_H
>> +#include <malloc.h>
>> +#endif
>>
>>  #include "avassert.h"
>>  #include "buffer_internal.h"
>> @@ -100,6 +105,32 @@ AVBufferRef *av_buffer_allocz(size_t size)
>>      return ret;
>>  }
>>
>> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align)
>> +{
>> +    AVBufferRef *ret = NULL;
>> +    uint8_t    *data = NULL;
>> +
>> +#if HAVE_POSIX_MEMALIGN
>> +    if (posix_memalign((void **)&data, align, size))
> 
> Invalid cast.
> 

Neither gcc or clang emit a warning here, even on -Weverything.
What would be your idea of a valid cast then? First cast to intptr_t, 
then void** ?

>> +        return NULL;
>> +#elif HAVE_ALIGNED_MALLOC
>> +    data = aligned_alloc(align, size);
>> +#elif HAVE_MEMALIGN
>> +    data = memalign(align, size);
>> +#else
>> +    return NULL;
>> +#endif
>> +
>> +    if (!data)
>> +        return NULL;
>> +
>> +    ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
>> +    if (!ret)
>> +        av_freep(&data);
>> +
>> +    return ret;
>> +}
>> +
>>  AVBufferRef *av_buffer_ref(const AVBufferRef *buf)
>>  {
>>      AVBufferRef *ret = av_mallocz(sizeof(*ret));
>> diff --git a/libavutil/buffer.h b/libavutil/buffer.h
>> index e1ef5b7f07..8422ec3453 100644
>> --- a/libavutil/buffer.h
>> +++ b/libavutil/buffer.h
>> @@ -107,6 +107,13 @@ AVBufferRef *av_buffer_alloc(size_t size);
>>   */
>>  AVBufferRef *av_buffer_allocz(size_t size);
>>
>> +/**
>> + * Allocate an AVBuffer of the given size and alignment.
>> + *
>> + * @return an AVBufferRef of given size or NULL when out of memory
>> + */
>> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align);
>> +
>>  /**
>>   * Always treat the buffer as read-only, even when it has only one
>>   * reference.
> 
>
Michael Niedermayer May 31, 2024, 9:44 p.m. UTC | #3
On Fri, May 31, 2024 at 11:06:49PM +0200, averne wrote:
> Le 30/05/2024 à 22:38, Rémi Denis-Courmont a écrit :
> > Le torstaina 30. toukokuuta 2024, 22.43.03 EEST averne a écrit :
> >> This is useful eg. for memory-mapped buffers that need page-aligned memory,
> >> when dealing with hardware devices
> >>
> >> Signed-off-by: averne <averne381@gmail.com>
> >> ---
> >>  libavutil/buffer.c | 31 +++++++++++++++++++++++++++++++
> >>  libavutil/buffer.h |  7 +++++++
> >>  2 files changed, 38 insertions(+)
> >>
> >> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
> >> index e4562a79b1..b8e357f540 100644
> >> --- a/libavutil/buffer.c
> >> +++ b/libavutil/buffer.c
> >> @@ -16,9 +16,14 @@
> >>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> >> USA */
> >>
> >> +#include "config.h"
> >> +
> >>  #include <stdatomic.h>
> >>  #include <stdint.h>
> >>  #include <string.h>
> >> +#if HAVE_MALLOC_H
> >> +#include <malloc.h>
> >> +#endif
> >>
> >>  #include "avassert.h"
> >>  #include "buffer_internal.h"
> >> @@ -100,6 +105,32 @@ AVBufferRef *av_buffer_allocz(size_t size)
> >>      return ret;
> >>  }
> >>
> >> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align)
> >> +{
> >> +    AVBufferRef *ret = NULL;
> >> +    uint8_t    *data = NULL;
> >> +
> >> +#if HAVE_POSIX_MEMALIGN
> >> +    if (posix_memalign((void **)&data, align, size))
> > 
> > Invalid cast.
> > 
> 
> Neither gcc or clang emit a warning here, even on -Weverything.
> What would be your idea of a valid cast then? First cast to intptr_t, 
> then void** ?
> 
> >> +        return NULL;
> >> +#elif HAVE_ALIGNED_MALLOC
> >> +    data = aligned_alloc(align, size);

on mingw64:

src/libavutil/buffer.c: In function ‘av_buffer_aligned_alloc’:
src/libavutil/buffer.c:117:12: error: implicit declaration of function ‘aligned_alloc’ [-Werror=implicit-function-declaration]
  117 |     data = aligned_alloc(align, size);
      |            ^~~~~~~~~~~~~

thx

[...]
Rémi Denis-Courmont June 1, 2024, 6:59 a.m. UTC | #4
Le 1 juin 2024 00:06:49 GMT+03:00, averne <averne381@gmail.com> a écrit :
>Le 30/05/2024 à 22:38, Rémi Denis-Courmont a écrit :
>> Le torstaina 30. toukokuuta 2024, 22.43.03 EEST averne a écrit :
>>> This is useful eg. for memory-mapped buffers that need page-aligned memory,
>>> when dealing with hardware devices
>>>
>>> Signed-off-by: averne <averne381@gmail.com>
>>> ---

>> Invalid cast.
>> 
>
>Neither gcc or clang emit a warning here, even on -Weverything.
>What would be your idea of a valid cast then? First cast to intptr_t, 
>then void** ?

They don't warn because the explicit cast conventionally mutes the warning. Remove it and you'll get the warning.
averne June 2, 2024, 6:37 p.m. UTC | #5
Le 31/05/2024 à 23:44, Michael Niedermayer a écrit :
> On Fri, May 31, 2024 at 11:06:49PM +0200, averne wrote:
>> Le 30/05/2024 à 22:38, Rémi Denis-Courmont a écrit :
>>> Le torstaina 30. toukokuuta 2024, 22.43.03 EEST averne a écrit :
>>>> This is useful eg. for memory-mapped buffers that need page-aligned memory,
>>>> when dealing with hardware devices
>>>>
>>>> Signed-off-by: averne <averne381@gmail.com>
>>>> ---
>>>>  libavutil/buffer.c | 31 +++++++++++++++++++++++++++++++
>>>>  libavutil/buffer.h |  7 +++++++
>>>>  2 files changed, 38 insertions(+)
>>>>
>>>> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
>>>> index e4562a79b1..b8e357f540 100644
>>>> --- a/libavutil/buffer.c
>>>> +++ b/libavutil/buffer.c
>>>> @@ -16,9 +16,14 @@
>>>>   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
>>>> USA */
>>>>
>>>> +#include "config.h"
>>>> +
>>>>  #include <stdatomic.h>
>>>>  #include <stdint.h>
>>>>  #include <string.h>
>>>> +#if HAVE_MALLOC_H
>>>> +#include <malloc.h>
>>>> +#endif
>>>>
>>>>  #include "avassert.h"
>>>>  #include "buffer_internal.h"
>>>> @@ -100,6 +105,32 @@ AVBufferRef *av_buffer_allocz(size_t size)
>>>>      return ret;
>>>>  }
>>>>
>>>> +AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align)
>>>> +{
>>>> +    AVBufferRef *ret = NULL;
>>>> +    uint8_t    *data = NULL;
>>>> +
>>>> +#if HAVE_POSIX_MEMALIGN
>>>> +    if (posix_memalign((void **)&data, align, size))
>>>
>>> Invalid cast.
>>>
>>
>> Neither gcc or clang emit a warning here, even on -Weverything.
>> What would be your idea of a valid cast then? First cast to intptr_t, 
>> then void** ?
>>
>>>> +        return NULL;
>>>> +#elif HAVE_ALIGNED_MALLOC
>>>> +    data = aligned_alloc(align, size);
> 
> on mingw64:
> 
> src/libavutil/buffer.c: In function ‘av_buffer_aligned_alloc’:
> src/libavutil/buffer.c:117:12: error: implicit declaration of function ‘aligned_alloc’ [-Werror=implicit-function-declaration]
>   117 |     data = aligned_alloc(align, size);
>       |            ^~~~~~~~~~~~~
> 
> thx

Missing include of stdlib.h, probably. Will fix, thanks.
diff mbox series

Patch

diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index e4562a79b1..b8e357f540 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -16,9 +16,14 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+
 #include <stdatomic.h>
 #include <stdint.h>
 #include <string.h>
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
 
 #include "avassert.h"
 #include "buffer_internal.h"
@@ -100,6 +105,32 @@  AVBufferRef *av_buffer_allocz(size_t size)
     return ret;
 }
 
+AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align)
+{
+    AVBufferRef *ret = NULL;
+    uint8_t    *data = NULL;
+
+#if HAVE_POSIX_MEMALIGN
+    if (posix_memalign((void **)&data, align, size))
+        return NULL;
+#elif HAVE_ALIGNED_MALLOC
+    data = aligned_alloc(align, size);
+#elif HAVE_MEMALIGN
+    data = memalign(align, size);
+#else
+    return NULL;
+#endif
+
+    if (!data)
+        return NULL;
+
+    ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
+    if (!ret)
+        av_freep(&data);
+
+    return ret;
+}
+
 AVBufferRef *av_buffer_ref(const AVBufferRef *buf)
 {
     AVBufferRef *ret = av_mallocz(sizeof(*ret));
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
index e1ef5b7f07..8422ec3453 100644
--- a/libavutil/buffer.h
+++ b/libavutil/buffer.h
@@ -107,6 +107,13 @@  AVBufferRef *av_buffer_alloc(size_t size);
  */
 AVBufferRef *av_buffer_allocz(size_t size);
 
+/**
+ * Allocate an AVBuffer of the given size and alignment.
+ *
+ * @return an AVBufferRef of given size or NULL when out of memory
+ */
+AVBufferRef *av_buffer_aligned_alloc(size_t size, size_t align);
+
 /**
  * Always treat the buffer as read-only, even when it has only one
  * reference.