}
};
+ /*
+ * 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) {
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);
class raw_char;
class raw_pipe;
class raw_unshareable; // diagnostic, unshareable char buffer
+ class raw_combined;
class xio_mempool;
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);