2017-08-01 14:30:58 +02:00
|
|
|
#ifndef GIM_MEMORY_H_INCLUDED
|
|
|
|
#define GIM_MEMORY_H_INCLUDED
|
|
|
|
/*! \file gim_memory.h
|
|
|
|
\author Francisco Leon Najera
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
This source file is part of GIMPACT Library.
|
|
|
|
|
|
|
|
For the latest info, see http://gimpact.sourceforge.net/
|
|
|
|
|
|
|
|
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
|
|
|
email: projectileman@yahoo.com
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of EITHER:
|
|
|
|
(1) The GNU Lesser General Public License as published by the Free
|
|
|
|
Software Foundation; either version 2.1 of the License, or (at
|
|
|
|
your option) any later version. The text of the GNU Lesser
|
|
|
|
General Public License is included with this library in the
|
|
|
|
file GIMPACT-LICENSE-LGPL.TXT.
|
|
|
|
(2) The BSD-style license that is included with this library in
|
|
|
|
the file GIMPACT-LICENSE-BSD.TXT.
|
|
|
|
(3) The zlib/libpng license that is included with this library in
|
|
|
|
the file GIMPACT-LICENSE-ZLIB.TXT.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
|
|
|
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "gim_math.h"
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#ifdef PREFETCH
|
2019-01-03 14:26:51 +01:00
|
|
|
#include <xmmintrin.h> // for prefetch
|
|
|
|
#define pfval 64
|
|
|
|
#define pfval2 128
|
2017-08-01 14:30:58 +02:00
|
|
|
//! Prefetch 64
|
2019-01-03 14:26:51 +01:00
|
|
|
#define pf(_x, _i) _mm_prefetch((void *)(_x + _i + pfval), 0)
|
2017-08-01 14:30:58 +02:00
|
|
|
//! Prefetch 128
|
2019-01-03 14:26:51 +01:00
|
|
|
#define pf2(_x, _i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
|
2017-08-01 14:30:58 +02:00
|
|
|
#else
|
|
|
|
//! Prefetch 64
|
2019-01-03 14:26:51 +01:00
|
|
|
#define pf(_x, _i)
|
2017-08-01 14:30:58 +02:00
|
|
|
//! Prefetch 128
|
2019-01-03 14:26:51 +01:00
|
|
|
#define pf2(_x, _i)
|
2017-08-01 14:30:58 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
///Functions for manip packed arrays of numbers
|
2019-01-03 14:26:51 +01:00
|
|
|
#define GIM_COPY_ARRAYS(dest_array, source_array, element_count) \
|
|
|
|
{ \
|
|
|
|
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
|
|
|
{ \
|
|
|
|
dest_array[_i_] = source_array[_i_]; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GIM_COPY_ARRAYS_1(dest_array, source_array, element_count, copy_macro) \
|
|
|
|
{ \
|
|
|
|
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
|
|
|
{ \
|
|
|
|
copy_macro(dest_array[_i_], source_array[_i_]); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GIM_ZERO_ARRAY(array, element_count) \
|
|
|
|
{ \
|
|
|
|
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
|
|
|
{ \
|
|
|
|
array[_i_] = 0; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GIM_CONSTANT_ARRAY(array, element_count, constant) \
|
|
|
|
{ \
|
|
|
|
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
|
|
|
{ \
|
|
|
|
array[_i_] = constant; \
|
|
|
|
} \
|
|
|
|
}
|
2017-08-01 14:30:58 +02:00
|
|
|
|
|
|
|
///Function prototypes to allocate and free memory.
|
2019-01-03 14:26:51 +01:00
|
|
|
typedef void *gim_alloc_function(size_t size);
|
|
|
|
typedef void *gim_alloca_function(size_t size); //Allocs on the heap
|
|
|
|
typedef void *gim_realloc_function(void *ptr, size_t oldsize, size_t newsize);
|
|
|
|
typedef void gim_free_function(void *ptr);
|
2017-08-01 14:30:58 +02:00
|
|
|
|
|
|
|
///Memory Function Handlers
|
|
|
|
///set new memory management functions. if fn is 0, the default handlers are used.
|
2019-01-03 14:26:51 +01:00
|
|
|
void gim_set_alloc_handler(gim_alloc_function *fn);
|
|
|
|
void gim_set_alloca_handler(gim_alloca_function *fn);
|
|
|
|
void gim_set_realloc_handler(gim_realloc_function *fn);
|
|
|
|
void gim_set_free_handler(gim_free_function *fn);
|
2017-08-01 14:30:58 +02:00
|
|
|
|
|
|
|
///get current memory management functions.
|
2019-01-03 14:26:51 +01:00
|
|
|
gim_alloc_function *gim_get_alloc_handler(void);
|
2017-08-01 14:30:58 +02:00
|
|
|
gim_alloca_function *gim_get_alloca_handler(void);
|
2019-01-03 14:26:51 +01:00
|
|
|
gim_realloc_function *gim_get_realloc_handler(void);
|
|
|
|
gim_free_function *gim_get_free_handler(void);
|
2017-08-01 14:30:58 +02:00
|
|
|
|
|
|
|
///Standar Memory functions
|
2019-01-03 14:26:51 +01:00
|
|
|
void *gim_alloc(size_t size);
|
|
|
|
void *gim_alloca(size_t size);
|
|
|
|
void *gim_realloc(void *ptr, size_t oldsize, size_t newsize);
|
2017-08-01 14:30:58 +02:00
|
|
|
void gim_free(void *ptr);
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
|
|
|
#define GIM_SIMD_MEMORY 1
|
2017-08-01 14:30:58 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
//! SIMD POINTER INTEGER
|
|
|
|
#define SIMD_T GUINT64
|
|
|
|
//! SIMD INTEGER SIZE
|
|
|
|
#define SIMD_T_SIZE sizeof(SIMD_T)
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
inline void gim_simd_memcpy(void *dst, const void *src, size_t copysize)
|
2017-08-01 14:30:58 +02:00
|
|
|
{
|
|
|
|
#ifdef GIM_SIMD_MEMORY
|
2019-01-03 14:26:51 +01:00
|
|
|
/*
|
2017-08-01 14:30:58 +02:00
|
|
|
//'long long int' is incompatible with visual studio 6...
|
|
|
|
//copy words
|
|
|
|
SIMD_T * ui_src_ptr = (SIMD_T *)src;
|
|
|
|
SIMD_T * ui_dst_ptr = (SIMD_T *)dst;
|
|
|
|
while(copysize>=SIMD_T_SIZE)
|
|
|
|
{
|
|
|
|
*(ui_dst_ptr++) = *(ui_src_ptr++);
|
|
|
|
copysize-=SIMD_T_SIZE;
|
|
|
|
}
|
|
|
|
if(copysize==0) return;
|
|
|
|
*/
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
char *c_src_ptr = (char *)src;
|
|
|
|
char *c_dst_ptr = (char *)dst;
|
|
|
|
while (copysize > 0)
|
|
|
|
{
|
|
|
|
*(c_dst_ptr++) = *(c_src_ptr++);
|
|
|
|
copysize--;
|
|
|
|
}
|
|
|
|
return;
|
2017-08-01 14:30:58 +02:00
|
|
|
#else
|
2019-01-03 14:26:51 +01:00
|
|
|
memcpy(dst, src, copysize);
|
2017-08-01 14:30:58 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
template <class T>
|
|
|
|
inline void gim_swap_elements(T *_array, size_t _i, size_t _j)
|
2017-08-01 14:30:58 +02:00
|
|
|
{
|
|
|
|
T _e_tmp_ = _array[_i];
|
|
|
|
_array[_i] = _array[_j];
|
|
|
|
_array[_j] = _e_tmp_;
|
|
|
|
}
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
template <class T>
|
|
|
|
inline void gim_swap_elements_memcpy(T *_array, size_t _i, size_t _j)
|
2017-08-01 14:30:58 +02:00
|
|
|
{
|
|
|
|
char _e_tmp_[sizeof(T)];
|
2019-01-03 14:26:51 +01:00
|
|
|
gim_simd_memcpy(_e_tmp_, &_array[_i], sizeof(T));
|
|
|
|
gim_simd_memcpy(&_array[_i], &_array[_j], sizeof(T));
|
|
|
|
gim_simd_memcpy(&_array[_j], _e_tmp_, sizeof(T));
|
2017-08-01 14:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template <int SIZE>
|
2019-01-03 14:26:51 +01:00
|
|
|
inline void gim_swap_elements_ptr(char *_array, size_t _i, size_t _j)
|
2017-08-01 14:30:58 +02:00
|
|
|
{
|
|
|
|
char _e_tmp_[SIZE];
|
2019-01-03 14:26:51 +01:00
|
|
|
_i *= SIZE;
|
|
|
|
_j *= SIZE;
|
|
|
|
gim_simd_memcpy(_e_tmp_, _array + _i, SIZE);
|
|
|
|
gim_simd_memcpy(_array + _i, _array + _j, SIZE);
|
|
|
|
gim_simd_memcpy(_array + _j, _e_tmp_, SIZE);
|
2017-08-01 14:30:58 +02:00
|
|
|
}
|
|
|
|
|
2019-01-03 14:26:51 +01:00
|
|
|
#endif // GIM_MEMORY_H_INCLUDED
|