commit-gnuradio
[Top][All Lists]
Advanced

[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>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]