mirror of https://github.com/gnss-sdr/gnss-sdr
153 lines
4.0 KiB
C
153 lines
4.0 KiB
C
/*
|
|
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
|
|
*
|
|
* This file is part of GNSS-SDR.
|
|
*
|
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GNSS-SDR 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
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "volk_gnsssdr/volk_gnsssdr_malloc.h"
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/*
|
|
* For #defines used to determine support for allocation functions,
|
|
* see: http://linux.die.net/man/3/aligned_alloc
|
|
*/
|
|
|
|
// Disabling use of aligned_alloc. This function requires that size be
|
|
// a multiple of alignment, which is too restrictive for many uses of
|
|
// VOLK.
|
|
|
|
//// If we are using C11 standard, use the aligned_alloc
|
|
//#ifdef _ISOC11_SOURCE
|
|
//
|
|
//void *volk_gnsssdr_malloc(size_t size, size_t alignment)
|
|
//{
|
|
// void *ptr = aligned_alloc(alignment, size);
|
|
// if(ptr == NULL) {
|
|
// fprintf(stderr, "VOLK: Error allocating memory (aligned_alloc)\n");
|
|
// }
|
|
// return ptr;
|
|
//}
|
|
//
|
|
//void volk_gnsssdr_free(void *ptr)
|
|
//{
|
|
// free(ptr);
|
|
//}
|
|
//
|
|
//#else // _ISOC11_SOURCE
|
|
|
|
// Otherwise, test if we are a POSIX or X/Open system
|
|
// This only has a restriction that alignment be a power of 2and a
|
|
// multiple of sizeof(void *).
|
|
#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || HAVE_POSIX_MEMALIGN
|
|
|
|
void *volk_gnsssdr_malloc(size_t size, size_t alignment)
|
|
{
|
|
void *ptr;
|
|
|
|
// quoting posix_memalign() man page:
|
|
// "alignment must be a power of two and a multiple of sizeof(void *)"
|
|
// volk_get_alignment() could return 1 for some machines (e.g. generic_orc)
|
|
if (alignment == 1)
|
|
return malloc(size);
|
|
|
|
int err = posix_memalign(&ptr, alignment, size);
|
|
if(err == 0)
|
|
{
|
|
return ptr;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr,
|
|
"VOLK: Error allocating memory "
|
|
"(posix_memalign: error %d: %s)\n", err, strerror(err));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void volk_gnsssdr_free(void *ptr)
|
|
{
|
|
free(ptr);
|
|
}
|
|
|
|
// _aligned_malloc has no restriction on size,
|
|
// available on Windows since Visual C++ 2005
|
|
#elif _MSC_VER >= 1400
|
|
|
|
void *volk_gnsssdr_malloc(size_t size, size_t alignment)
|
|
{
|
|
void *ptr = _aligned_malloc(size, alignment);
|
|
if(ptr == NULL)
|
|
{
|
|
fprintf(stderr, "VOLK: Error allocating memory (_aligned_malloc)\n");
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
void volk_gnsssdr_free(void *ptr)
|
|
{
|
|
_aligned_free(ptr);
|
|
}
|
|
|
|
// No standard handlers; we'll do it ourselves.
|
|
#else // _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || HAVE_POSIX_MEMALIGN
|
|
|
|
struct block_info
|
|
{
|
|
void *real;
|
|
};
|
|
|
|
void *
|
|
volk_gnsssdr_malloc(size_t size, size_t alignment)
|
|
{
|
|
void *real, *user;
|
|
struct block_info *info;
|
|
|
|
/* At least align to sizeof our struct */
|
|
if (alignment < sizeof(struct block_info))
|
|
alignment = sizeof(struct block_info);
|
|
|
|
/* Alloc */
|
|
real = malloc(size + (2 * alignment - 1));
|
|
|
|
/* Get pointer to the various zones */
|
|
user = (void *)((((uintptr_t) real) + sizeof(struct block_info) + alignment - 1) & ~(alignment - 1));
|
|
info = (struct block_info *)(((uintptr_t)user) - sizeof(struct block_info));
|
|
|
|
/* Store the info for the free */
|
|
info->real = real;
|
|
|
|
/* Return pointer to user */
|
|
return user;
|
|
}
|
|
|
|
void
|
|
volk_gnsssdr_free(void *ptr)
|
|
{
|
|
struct block_info *info;
|
|
|
|
/* Get the real pointer */
|
|
info = (struct block_info *)(((uintptr_t)ptr) - sizeof(struct block_info));
|
|
|
|
/* Release real pointer */
|
|
free(info->real);
|
|
}
|
|
|
|
#endif // _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || HAVE_POSIX_MEMALIGN
|
|
|
|
//#endif // _ISOC11_SOURCE
|