Add simple aligned alloc helper
authorJens Axboe <jaxboe@fusionio.com>
Mon, 25 Apr 2011 18:46:58 +0000 (20:46 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Mon, 25 Apr 2011 18:46:58 +0000 (20:46 +0200)
We don't have posix_memalign() on some Solaris and Darwin, so just
add a poor mans implementation of it. Outside of arch code where
we have proper posix_memalign(), this is only used to ensure good
alignment of the io_u in the core code.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Makefile
fio.c
memalign.c [new file with mode: 0644]
memalign.h [new file with mode: 0644]

index 1d81562..0dc997c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,8 @@ SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \
                eta.c verify.c memory.c io_u.c parse.c mutex.c options.c \
                rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \
                lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
-               engines/mmap.c engines/sync.c engines/null.c engines/net.c
+               engines/mmap.c engines/sync.c engines/null.c engines/net.c \
+               memalign.c
 
 ifeq ($(UNAME), Linux)
   SOURCE += diskutil.c fifo.c blktrace.c helpers.c cgroup.c trim.c \
diff --git a/fio.c b/fio.c
index e205b3a..a737a31 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -45,6 +45,7 @@
 #include "cgroup.h"
 #include "profile.h"
 #include "lib/rand.h"
+#include "memalign.h"
 
 unsigned long page_mask;
 unsigned long page_size;
@@ -796,7 +797,7 @@ static void cleanup_io_u(struct thread_data *td)
                io_u = flist_entry(entry, struct io_u, list);
 
                flist_del(&io_u->list);
-               free(io_u);
+               fio_memfree(io_u, sizeof(*io_u));
        }
 
        free_io_mem(td);
@@ -843,8 +844,9 @@ static int init_io_u(struct thread_data *td)
                if (td->terminate)
                        return 1;
 
-               if (posix_memalign(&ptr, cl_align, sizeof(*io_u))) {
-                       log_err("fio: posix_memalign=%s\n", strerror(errno));
+               ptr = fio_memalign(cl_align, sizeof(*io_u));
+               if (!ptr) {
+                       log_err("fio: unable to allocate aligned memory\n");
                        break;
                }
 
diff --git a/memalign.c b/memalign.c
new file mode 100644 (file)
index 0000000..87667b4
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "memalign.h"
+
+struct align_footer {
+       unsigned int offset;
+};
+
+#define PTR_ALIGN(ptr, mask)   \
+       (char *) (((unsigned long) ((ptr) + (mask)) & ~(mask)))
+
+void *fio_memalign(size_t alignment, size_t size)
+{
+       struct align_footer *f;
+       void *ptr, *ret = NULL;
+
+       assert(!(alignment & (alignment - 1)));
+
+       ptr = malloc(size + alignment + size + sizeof(*f) - 1);
+       if (ptr) {
+               ret = PTR_ALIGN(ptr, alignment);
+               f = ret + size;
+               f->offset = (unsigned long) ret - (unsigned long) ptr;
+       }
+
+       return ret;
+}
+
+void fio_memfree(void *ptr, size_t size)
+{
+       struct align_footer *f = ptr + size;
+
+       free(ptr - f->offset);
+}
diff --git a/memalign.h b/memalign.h
new file mode 100644 (file)
index 0000000..df412e2
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef FIO_MEMALIGN_H
+#define FIO_MEMALIGN_H
+
+extern void *fio_memalign(size_t alignment, size_t size);
+extern void fio_memfree(void *ptr, size_t size);
+
+#endif