]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
buffer: combine data and buffer::raw into single allocation
authorSage Weil <sage@redhat.com>
Wed, 10 Feb 2016 22:42:07 +0000 (17:42 -0500)
committerSage Weil <sage@redhat.com>
Tue, 1 Mar 2016 13:47:28 +0000 (08:47 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/common/buffer.cc
src/include/buffer.h

index 3c090e4c294990f8ec986d953a76d64109615bac..80a5d513d43d3052c008a2ba55565b4094903579 100644 (file)
@@ -235,6 +235,34 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     }
   };
 
+  /*
+   * raw_combined is always placed within a single allocation along
+   * with the data buffer.  the data goes at the beginning, and
+   * raw_combined at the end.  see create_combined.
+   */
+  class buffer::raw_combined : public buffer::raw {
+    size_t alignment;
+  public:
+    raw_combined(char *dataptr, unsigned l, unsigned align=0)
+      : raw(dataptr, l),
+       alignment(align) {
+      inc_total_alloc(len);
+    }
+    ~raw_combined() {
+      dec_total_alloc(len);
+    }
+    raw* clone_empty() {
+      if (alignment)
+       return create_aligned(len, alignment);
+      return create(len);
+    }
+
+    static void operator delete(void *ptr) {
+      raw_combined *raw = (raw_combined *)ptr;
+      ::free((void *)raw->data);
+    }
+  };
+
   class buffer::raw_malloc : public buffer::raw {
   public:
     explicit raw_malloc(unsigned l) : raw(l) {
@@ -654,6 +682,31 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   buffer::raw* buffer::create_static(unsigned len, char *buf) {
     return new raw_static(buf, len);
   }
+
+  buffer::raw* buffer::create_combined(unsigned len, unsigned align) {
+    if (!align)
+      align = sizeof(size_t);
+    size_t rawlen = ROUND_UP_TO(sizeof(buffer::raw_combined), sizeof(size_t));
+    size_t datalen = ROUND_UP_TO(len, sizeof(size_t));
+
+#ifdef DARWIN
+    char *ptr = (char *) valloc(rawlen + datalen);
+#else
+    char *ptr = 0;
+    int r = ::posix_memalign((void**)(void*)&ptr, align, rawlen + datalen);
+    if (r)
+      throw bad_alloc();
+#endif /* DARWIN */
+    if (!ptr)
+      throw bad_alloc();
+
+    // actual data first, since it has presumably larger alignment restriction
+    // then put the raw_combined at the end
+    raw *ret = new (ptr + datalen) raw_combined(ptr, len, align);
+    assert((char *)ret == ptr + datalen);
+    return ret;
+  }
+
   buffer::raw* buffer::create_aligned(unsigned len, unsigned align) {
 #ifndef __CYGWIN__
     //return new raw_mmap_pages(len);
index c07a82cc26504d963bab4dcb44a62ccab255152a..81ce336c05a19681b73b5d635bfc3695b4fe4edd 100644 (file)
@@ -136,6 +136,7 @@ namespace buffer CEPH_BUFFER_API {
   class raw_char;
   class raw_pipe;
   class raw_unshareable; // diagnostic, unshareable char buffer
+  class raw_combined;
 
 
   class xio_mempool;
@@ -150,6 +151,7 @@ namespace buffer CEPH_BUFFER_API {
   raw* create_malloc(unsigned len);
   raw* claim_malloc(unsigned len, char *buf);
   raw* create_static(unsigned len, char *buf);
+  raw* create_combined(unsigned len, unsigned align=0);
   raw* create_aligned(unsigned len, unsigned align);
   raw* create_page_aligned(unsigned len);
   raw* create_zero_copy(unsigned len, int fd, int64_t *offset);