Statistics
| Branch: | Revision:

ffmpeg / libavutil / mem.c @ 08675bb3

History | View | Annotate | Download (4.86 KB)

1 d01fe86d Fabrice Bellard
/*
2 cea8f6f3 Luca Abeni
 * default memory allocator for libavutil
3 406792e7 Diego Biurrun
 * Copyright (c) 2002 Fabrice Bellard
4 d01fe86d Fabrice Bellard
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 d01fe86d Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 d01fe86d Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 d01fe86d Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 d01fe86d Fabrice Bellard
 */
21 115329f1 Diego Biurrun
22 983e3246 Michael Niedermayer
/**
23 ba87f080 Diego Biurrun
 * @file
24 89c9ff50 Diego Biurrun
 * default memory allocator for libavutil
25 983e3246 Michael Niedermayer
 */
26 115329f1 Diego Biurrun
27 dfcb6b56 Diego Biurrun
#include "config.h"
28 8e1e6f31 Fabrice Bellard
29 dfcb6b56 Diego Biurrun
#include <limits.h>
30 1f91cdce Ramiro Polla
#include <stdlib.h>
31 dfcb6b56 Diego Biurrun
#include <string.h>
32 b250f9c6 Aurelien Jacobs
#if HAVE_MALLOC_H
33 d01fe86d Fabrice Bellard
#include <malloc.h>
34
#endif
35
36 4ae40685 Måns Rullgård
#include "avutil.h"
37 77652a6a Diego Biurrun
#include "mem.h"
38
39 89c9ff50 Diego Biurrun
/* here we can use OS-dependent allocation functions */
40 1e60e933 Diego Biurrun
#undef free
41
#undef malloc
42
#undef realloc
43
44 4ae40685 Måns Rullgård
#ifdef MALLOC_PREFIX
45
46
#define malloc         AV_JOIN(MALLOC_PREFIX, malloc)
47
#define memalign       AV_JOIN(MALLOC_PREFIX, memalign)
48
#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
49
#define realloc        AV_JOIN(MALLOC_PREFIX, realloc)
50
#define free           AV_JOIN(MALLOC_PREFIX, free)
51
52
void *malloc(size_t size);
53
void *memalign(size_t align, size_t size);
54
int   posix_memalign(void **ptr, size_t align, size_t size);
55
void *realloc(void *ptr, size_t size);
56
void  free(void *ptr);
57
58
#endif /* MALLOC_PREFIX */
59
60 08675bb3 Michael Niedermayer
#define ALIGN (HAVE_AVX ? 32 : 16)
61
62 89c9ff50 Diego Biurrun
/* You can redefine av_malloc and av_free in your project to use your
63 d01fe86d Fabrice Bellard
   memory allocator. You do not need to suppress this file because the
64 89c9ff50 Diego Biurrun
   linker will do it automatically. */
65 d01fe86d Fabrice Bellard
66 490a022d Anton Khirnov
void *av_malloc(size_t size)
67 d01fe86d Fabrice Bellard
{
68 1f91cdce Ramiro Polla
    void *ptr = NULL;
69 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
70 ed96aeea Dieter
    long diff;
71 88730be6 Måns Rullgård
#endif
72 0ecca7a4 Michael Niedermayer
73 7d77d5f6 Diego Biurrun
    /* let's disallow possible ambiguous cases */
74 13dfce3d Vitor Sessak
    if(size > (INT_MAX-32) )
75 0ecca7a4 Michael Niedermayer
        return NULL;
76 115329f1 Diego Biurrun
77 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
78 08675bb3 Michael Niedermayer
    ptr = malloc(size+ALIGN);
79 a9493601 Herve W
    if(!ptr)
80
        return ptr;
81 08675bb3 Michael Niedermayer
    diff= ((-(long)ptr - 1)&(ALIGN-1)) + 1;
82 90d30570 avcoder
    ptr = (char*)ptr + diff;
83 da9b170c Michael Niedermayer
    ((char*)ptr)[-1]= diff;
84 b250f9c6 Aurelien Jacobs
#elif HAVE_POSIX_MEMALIGN
85 08675bb3 Michael Niedermayer
    if (posix_memalign(&ptr,ALIGN,size))
86 a90de11d Patrik Kullman
        ptr = NULL;
87 b250f9c6 Aurelien Jacobs
#elif HAVE_MEMALIGN
88 08675bb3 Michael Niedermayer
    ptr = memalign(ALIGN,size);
89 115329f1 Diego Biurrun
    /* Why 64?
90 d01fe86d Fabrice Bellard
       Indeed, we should align it:
91
         on 4 for 386
92
         on 16 for 486
93 89c9ff50 Diego Biurrun
         on 32 for 586, PPro - K6-III
94 bb270c08 Diego Biurrun
         on 64 for K7 (maybe for P3 too).
95 d01fe86d Fabrice Bellard
       Because L1 and L2 caches are aligned on those values.
96
       But I don't want to code such logic here!
97
     */
98 13dfce3d Vitor Sessak
     /* Why 32?
99
        For AVX ASM. SSE / NEON needs only 16.
100 2cab6401 Diego Biurrun
        Why not larger? Because I did not see a difference in benchmarks ...
101 8f2b21a8 Michael Niedermayer
     */
102 89c9ff50 Diego Biurrun
     /* benchmarks with P3
103 bb270c08 Diego Biurrun
        memalign(64)+1          3071,3051,3032
104
        memalign(64)+2          3051,3032,3041
105
        memalign(64)+4          2911,2896,2915
106
        memalign(64)+8          2545,2554,2550
107
        memalign(64)+16         2543,2572,2563
108
        memalign(64)+32         2546,2545,2571
109
        memalign(64)+64         2570,2533,2558
110 115329f1 Diego Biurrun

111 89c9ff50 Diego Biurrun
        BTW, malloc seems to do 8-byte alignment by default here.
112 8f2b21a8 Michael Niedermayer
     */
113 d01fe86d Fabrice Bellard
#else
114
    ptr = malloc(size);
115
#endif
116 c8981edd Michael Niedermayer
    if(!ptr && !size)
117
        ptr= av_malloc(1);
118 d01fe86d Fabrice Bellard
    return ptr;
119
}
120
121 490a022d Anton Khirnov
void *av_realloc(void *ptr, size_t size)
122 8e1e6f31 Fabrice Bellard
{
123 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
124 0a7c36af Michael Niedermayer
    int diff;
125
#endif
126 88730be6 Måns Rullgård
127 7d77d5f6 Diego Biurrun
    /* let's disallow possible ambiguous cases */
128 a9493601 Herve W
    if(size > (INT_MAX-16) )
129 0ecca7a4 Michael Niedermayer
        return NULL;
130
131 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
132 0a7c36af Michael Niedermayer
    //FIXME this isn't aligned correctly, though it probably isn't needed
133
    if(!ptr) return av_malloc(size);
134
    diff= ((char*)ptr)[-1];
135 90d30570 avcoder
    return (char*)realloc((char*)ptr - diff, size + diff) + diff;
136 0a7c36af Michael Niedermayer
#else
137 91ff05f6 Michael Niedermayer
    return realloc(ptr, size + !size);
138 da9b170c Michael Niedermayer
#endif
139 b7a22d84 Michael Niedermayer
}
140
141 d01fe86d Fabrice Bellard
void av_free(void *ptr)
142
{
143 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
144 0c8eb72e Clément Bœsch
    if (ptr)
145 90d30570 avcoder
        free((char*)ptr - ((char*)ptr)[-1]);
146 da9b170c Michael Niedermayer
#else
147 0c8eb72e Clément Bœsch
    free(ptr);
148 da9b170c Michael Niedermayer
#endif
149 d01fe86d Fabrice Bellard
}
150
151 79e47000 Luca Barbato
void av_freep(void *arg)
152
{
153
    void **ptr= (void**)arg;
154
    av_free(*ptr);
155
    *ptr = NULL;
156
}
157
158 490a022d Anton Khirnov
void *av_mallocz(size_t size)
159 79e47000 Luca Barbato
{
160 11362767 Michael Niedermayer
    void *ptr = av_malloc(size);
161 79e47000 Luca Barbato
    if (ptr)
162
        memset(ptr, 0, size);
163
    return ptr;
164
}
165
166
char *av_strdup(const char *s)
167
{
168 fdf35f26 Michael Niedermayer
    char *ptr= NULL;
169
    if(s){
170 19757f61 Michael Niedermayer
        int len = strlen(s) + 1;
171
        ptr = av_malloc(len);
172
        if (ptr)
173
            memcpy(ptr, s, len);
174 fdf35f26 Michael Niedermayer
    }
175 79e47000 Luca Barbato
    return ptr;
176
}
177
178 35ceaa73 Anton Khirnov
/* add one element to a dynamic array */
179
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
180
{
181
    /* see similar ffmpeg.c:grow_array() */
182
    int nb, nb_alloc;
183
    intptr_t *tab;
184
185
    nb = *nb_ptr;
186
    tab = *(intptr_t**)tab_ptr;
187
    if ((nb & (nb - 1)) == 0) {
188
        if (nb == 0)
189
            nb_alloc = 1;
190
        else
191
            nb_alloc = nb * 2;
192
        tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
193
        *(intptr_t**)tab_ptr = tab;
194
    }
195
    tab[nb++] = (intptr_t)elem;
196
    *nb_ptr = nb;
197
}