[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 03/07: volk: adding volk_malloc and volk_fr
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 03/07: volk: adding volk_malloc and volk_free functions to handle allocation of aligned memory. |
Date: |
Sat, 18 Jan 2014 20:31:59 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
trondeau pushed a commit to branch master
in repository gnuradio.
commit 6b19c5d5c7486f86aeb4ac6097131128b832c716
Author: Tom Rondeau <address@hidden>
Date: Tue Jan 14 17:17:56 2014 -0500
volk: adding volk_malloc and volk_free functions to handle allocation of
aligned memory.
---
volk/CMakeLists.txt | 1 +
volk/include/volk/volk_malloc.h | 66 +++++++++++++++
volk/lib/CMakeLists.txt | 1 +
volk/lib/volk_malloc.c | 176 ++++++++++++++++++++++++++++++++++++++++
volk/tmpl/volk.tmpl.h | 1 +
5 files changed, 245 insertions(+)
diff --git a/volk/CMakeLists.txt b/volk/CMakeLists.txt
index 40572f3..cf651ed 100644
--- a/volk/CMakeLists.txt
+++ b/volk/CMakeLists.txt
@@ -122,6 +122,7 @@ install(FILES
${CMAKE_BINARY_DIR}/include/volk/volk_cpu.h
${CMAKE_BINARY_DIR}/include/volk/volk_config_fixed.h
${CMAKE_BINARY_DIR}/include/volk/volk_typedefs.h
+ ${CMAKE_SOURCE_DIR}/include/volk/volk_malloc.h
DESTINATION include/volk
COMPONENT "volk_devel"
)
diff --git a/volk/include/volk/volk_malloc.h b/volk/include/volk/volk_malloc.h
new file mode 100644
index 0000000..6ec7391
--- /dev/null
+++ b/volk/include/volk/volk_malloc.h
@@ -0,0 +1,66 @@
+/* -*- c -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_VOLK_MALLOC_H
+#define INCLUDED_VOLK_MALLOC_H
+
+#include <volk/volk_common.h>
+#include <stdlib.h>
+
+__VOLK_DECL_BEGIN
+
+/*!
+ * \brief Allocate \p size bytes of data aligned to \p alignment.
+ *
+ * \details
+ * Because we don't have a standard method to allocate buffers in
+ * memory that are guaranteed to be on an alignment, VOLK handles this
+ * itself. The volk_malloc function behaves like malloc in that it
+ * returns a pointer to the allocated memory. However, it also takes
+ * in an alignment specfication, which is usually something like 16 or
+ * 32 to ensure that the aligned memory is located on a particular
+ * byte boundary for use with SIMD.
+ *
+ * Internally, the volk_malloc first checks if the compiler is C11
+ * compliant and uses the new aligned_alloc method. If not, it checks
+ * if the system is POSIX compliant and uses posix_memalign. If that
+ * fails, volk_malloc handles the memory allocation and alignment
+ * internally.
+ *
+ * Because of the ways in which volk_malloc may allocate memory, it is
+ * important to always free volk_malloc pointers using volk_free.
+ *
+ * \param size The number of bytes to allocate.
+ * \param alignment The byte alignment of the allocated memory.
+ * \return pointer to aligned memory.
+ */
+VOLK_API void *volk_malloc(size_t size, size_t alignment);
+
+/*!
+ * \brief Free's memory allocated by volk_malloc.
+ * \param aptr The aligned pointer allocaed by volk_malloc.
+ */
+VOLK_API void volk_free(void *aptr);
+
+__VOLK_DECL_END
+
+#endif /* INCLUDED_VOLK_MALLOC_H */
diff --git a/volk/lib/CMakeLists.txt b/volk/lib/CMakeLists.txt
index cda1087..dbebac0 100644
--- a/volk/lib/CMakeLists.txt
+++ b/volk/lib/CMakeLists.txt
@@ -413,6 +413,7 @@ endif()
list(APPEND volk_sources
${CMAKE_CURRENT_SOURCE_DIR}/volk_prefs.c
${CMAKE_CURRENT_SOURCE_DIR}/volk_rank_archs.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/volk_malloc.c
${volk_gen_sources}
)
diff --git a/volk/lib/volk_malloc.c b/volk/lib/volk_malloc.c
new file mode 100644
index 0000000..1333345
--- /dev/null
+++ b/volk/lib/volk_malloc.c
@@ -0,0 +1,176 @@
+/* -*- c -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <volk/volk_malloc.h>
+#include <stdio.h>
+#include <stdlib.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_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_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 2.
+#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
+
+void *volk_malloc(size_t size, size_t alignment)
+{
+ void *ptr;
+ int err = posix_memalign(&ptr, alignment, size);
+ if(err == 0) {
+ return ptr;
+ }
+ else {
+ fprintf(stderr, "VOLK: Error allocating memory (posix_memalign: %d)\n",
err);
+ return NULL;
+ }
+}
+
+void volk_free(void *ptr)
+{
+ free(ptr);
+}
+
+// No standard handlers; we'll do it ourselves.
+#else // _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
+
+typedef struct mbuf_t {
+ void *orig;
+ void *align;
+ struct mbuf_t *next;
+} mbuf;
+
+/*
+ Keep track of the pointers we've allocated. We hold a linked list
+ from volk_first_ptr to volk_last_ptr and the number of allocated
+ pointers. When allocating a new pointer, we create the pointer with
+ malloc, find how it is misaligned, and create a new pointer at the
+ alignment boundary. Both of these are stored in the linked list data
+ structure. When free, we are passed the aligned pointer and use that
+ to look up the original pointer, which we use to actually free the
+ entire allocated memory.
+*/
+unsigned int volk_nptrs = 0;
+mbuf* volk_first_ptr = NULL;
+mbuf* volk_last_ptr = NULL;
+
+void*
+volk_malloc(size_t size, size_t alignment)
+{
+ // Allocate memory plus enough extra to adjust alignment
+ void *ptr = malloc(size + (alignment - 1));
+ if(ptr == NULL) {
+ free(ptr);
+ fprintf(stderr, "VOLK: Error allocating memory (malloc)\n");
+ return NULL;
+ }
+
+ // Find and return the first aligned boundary of the pointer
+ void *aptr = ptr;
+ if((unsigned long)ptr % alignment != 0)
+ aptr = ptr + (alignment - ((unsigned long)ptr % alignment));
+
+ // Store original pointer and aligned pointers
+ mbuf *n = (mbuf*)malloc(sizeof(mbuf));
+ n->orig = ptr;
+ n->align = aptr;
+ n->next = NULL;
+ if(volk_first_ptr == NULL) {
+ volk_first_ptr = n;
+ }
+ else {
+ volk_last_ptr->next = n;
+ }
+ volk_last_ptr = n;
+ volk_nptrs++;
+
+ return aptr;
+}
+
+void volk_free(void *ptr)
+{
+ unsigned long aptr = (unsigned long)ptr;
+ mbuf *prev = volk_first_ptr;
+ mbuf *p = volk_first_ptr;
+
+ // Look for the aligned pointer until we either find it or have
+ // walked the entire list of allocated pointers
+ while(p != NULL) {
+ if((unsigned long)(p->align) == aptr) {
+ // If the memory is found at the first pointer, move this
+ // pointer to the next in the list
+ if(p == volk_first_ptr) {
+ if(volk_first_ptr == volk_last_ptr)
+ volk_last_ptr = NULL;
+ volk_first_ptr = p->next;
+ }
+ // Otherwise, link the previous to the following to skip the
+ // struct we're deleting.
+ else {
+ if(p == volk_last_ptr)
+ volk_last_ptr = prev;
+ prev->next = p->next;
+ }
+
+ // Free the original pointer to remove all memory allocated
+ free((void*)p->orig);
+ volk_nptrs--;
+
+ // Free the struct to clean up all memory and exit
+ free(p);
+
+ return;
+ }
+ // Not found, update our pointers to look at the next in the list
+ prev = p;
+ p = p->next;
+ }
+ fprintf(stderr, "VOLK: tried to free a non-VOLK pointer\n");
+}
+
+#endif // _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
+
+//#endif // _ISOC11_SOURCE
diff --git a/volk/tmpl/volk.tmpl.h b/volk/tmpl/volk.tmpl.h
index c8731ed..1d0957e 100644
--- a/volk/tmpl/volk.tmpl.h
+++ b/volk/tmpl/volk.tmpl.h
@@ -26,6 +26,7 @@
#include <volk/volk_config_fixed.h>
#include <volk/volk_common.h>
#include <volk/volk_complex.h>
+#include <volk/volk_malloc.h>
#include <stdlib.h>
#include <stdbool.h>
- [Commit-gnuradio] [gnuradio] branch master updated (67aa043 -> 213f244), git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 05/07: qtgui: switched from using fft::malloc to volk_malloc., git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 06/07: Merge branch 'maint', git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 03/07: volk: adding volk_malloc and volk_free functions to handle allocation of aligned memory.,
git <=
- [Commit-gnuradio] [gnuradio] 02/07: wxgui: Make sure to only start the flow graph once all init is done, git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 01/07: wx: Only call XInitThreads for linux, git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 04/07: filter: switched from using fft::malloc to volk_malloc., git, 2014/01/18
- [Commit-gnuradio] [gnuradio] 07/07: Merge branch 'volk_malloc', git, 2014/01/18