Skip to content

Commit 5ef9c84

Browse files
committed
Use cross-platform functions for allocating aligned memory
A malloc library is expected to provide a better implementation.
1 parent a55513a commit 5ef9c84

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ fi
409409
AC_FUNC_MEMCMP
410410
AC_FUNC_MMAP
411411
AC_FUNC_VPRINTF
412-
AC_CHECK_FUNCS([getcwd gettimeofday getwd memset munmap putenv realpath strcasecmp strchr strcspn strdup strerror strrchr strspn vsnprintf realpath mkstemp mktemp random rand sysconf atexit])
412+
AC_CHECK_FUNCS([getcwd gettimeofday getwd memset munmap putenv realpath strcasecmp strchr strcspn strdup strerror strrchr strspn vsnprintf realpath mkstemp mktemp random rand sysconf atexit _aligned_malloc posix_memalign memalign])
413413
AC_CHECK_LIB(m,cbrt,[AC_DEFINE(HAVE_CBRT,1,[have cbrt() in libm.])])
414414
AC_CHECK_LIB(m,hypot,[AC_DEFINE(HAVE_HYPOT,1,[have hypot() in libm.])])
415415
AC_CHECK_LIB(m,atan2,[AC_DEFINE(HAVE_ATAN2,1,[have atan2() in libm.])])

libvips/conversion/composite.cpp

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@
5555

5656
#include <stdio.h>
5757
#include <string.h>
58-
#if _MSC_VER
58+
#ifdef _MSC_VER
5959
#include <cstdlib>
6060
#else
6161
#include <stdlib.h>
6262
#endif
6363
#include <math.h>
6464

65+
#if defined(HAVE__ALIGNED_MALLOC) || defined(HAVE_MEMALIGN)
66+
#include <malloc.h>
67+
#endif
68+
6569
#include <vips/vips.h>
6670
#include <vips/internal.h>
6771
#include <vips/debug.h>
@@ -159,7 +163,8 @@ vips_composite_base_dispose( GObject *gobject )
159163
G_OBJECT_CLASS( vips_composite_base_parent_class )->dispose( gobject );
160164
}
161165

162-
/* Our sequence value.
166+
/* Our sequence value. This must be aligned on a 16-byte boundary when
167+
* HAVE_VECTOR_ARITH is defined.
163168
*/
164169
typedef struct {
165170
VipsCompositeBase *composite;
@@ -189,17 +194,46 @@ typedef struct {
189194
VipsPel **p;
190195

191196
#ifdef HAVE_VECTOR_ARITH
192-
/* A pointer to the 'real' memory.
193-
*/
194-
void *mem;
195-
196197
/* max_band as a vector, for the RGBA case.
197198
*/
198199
v4f max_band_vec;
199200
#endif /*HAVE_VECTOR_ARITH*/
200201

201202
} VipsCompositeSequence;
202203

204+
#ifdef HAVE_VECTOR_ARITH
205+
/* Allocate aligned memory. The return value can be released
206+
* by calling the vips_free_aligned() function, for example:
207+
* VIPS_FREEF( vips_free_aligned, ptr );
208+
*/
209+
static inline void *
210+
vips_alloc_aligned( size_t sz, size_t align )
211+
{
212+
g_assert( !(align & (align - 1)) );
213+
#ifdef HAVE__ALIGNED_MALLOC
214+
return _aligned_malloc( sz, align );
215+
#elif defined(HAVE_POSIX_MEMALIGN)
216+
void *ptr;
217+
if( posix_memalign( &ptr, align, sz ) ) return NULL;
218+
return ptr;
219+
#elif defined(HAVE_MEMALIGN)
220+
return memalign( align, sz );
221+
#else
222+
#error Missing aligned alloc implementation
223+
#endif
224+
}
225+
226+
static inline void
227+
vips_free_aligned( void* ptr )
228+
{
229+
#ifdef HAVE__ALIGNED_MALLOC
230+
_aligned_free( ptr );
231+
#else /*defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN)*/
232+
free( ptr );
233+
#endif
234+
}
235+
#endif /*HAVE_VECTOR_ARITH*/
236+
203237
static int
204238
vips_composite_stop( void *vseq, void *a, void *b )
205239
{
@@ -221,10 +255,7 @@ vips_composite_stop( void *vseq, void *a, void *b )
221255
VIPS_FREE( seq->p );
222256

223257
#ifdef HAVE_VECTOR_ARITH
224-
/* Must use g_free here, otherwise we end up writing to a
225-
* pointer that we just freed.
226-
*/
227-
g_free( seq->mem );
258+
VIPS_FREEF( vips_free_aligned, seq );
228259
#else /*!defined(HAVE_VECTOR_ARITH)*/
229260
VIPS_FREE( seq );
230261
#endif /*HAVE_VECTOR_ARITH*/
@@ -238,37 +269,18 @@ vips_composite_start( VipsImage *out, void *a, void *b )
238269
VipsImage **in = (VipsImage **) a;
239270
VipsCompositeBase *composite = (VipsCompositeBase *) b;
240271

241-
void *mem;
242272
VipsCompositeSequence *seq;
243-
int i, n, size;
244-
245-
/* The size of our struct.
246-
*/
247-
size = sizeof( VipsCompositeSequence );
273+
int i, n;
248274

249275
#ifdef HAVE_VECTOR_ARITH
250276
/* Ensure that the memory is aligned on a 16-byte boundary.
251277
*/
252-
size += 16 - 1;
253-
#endif /*HAVE_VECTOR_ARITH*/
254-
255-
/* Allocate a new chunk of memory.
256-
*/
257-
if( !(mem = vips_malloc( NULL, size )) )
258-
return( NULL );
259-
260-
#ifdef HAVE_VECTOR_ARITH
261-
/* Our aligned pointer.
262-
*/
263-
seq = (VipsCompositeSequence *)
264-
(((guintptr) mem + 15) & ~(guintptr) 0x0F);
265-
266-
/* Store the pointer to the 'real' memory.
267-
*/
268-
seq->mem = mem;
278+
if( !(seq = ((VipsCompositeSequence *) vips_alloc_aligned(
279+
sizeof( VipsCompositeSequence ), 16 ))) )
269280
#else /*!defined(HAVE_VECTOR_ARITH)*/
270-
seq = (VipsCompositeSequence *) mem;
281+
if( !(seq = VIPS_NEW( NULL, VipsCompositeSequence )) )
271282
#endif /*HAVE_VECTOR_ARITH*/
283+
return( NULL );
272284

273285
seq->composite = composite;
274286
seq->input_regions = NULL;

0 commit comments

Comments
 (0)