static int alloc_mem_shm(struct thread_data *td, unsigned int total_mem)
{
+#ifndef CONFIG_NO_SHM
int flags = IPC_CREAT | S_IRUSR | S_IWUSR;
if (td->o.mem_type == MEM_SHMHUGE) {
" support huge pages.\n");
} else if (errno == ENOMEM) {
log_err("fio: no huge pages available, do you"
- " need to alocate some? See HOWTO.\n");
+ " need to allocate some? See HOWTO.\n");
}
}
}
return 0;
+#else
+ log_err("fio: shm not supported\n");
+ return 1;
+#endif
}
static void free_mem_shm(struct thread_data *td)
{
+#ifndef CONFIG_NO_SHM
struct shmid_ds sbuf;
dprint(FD_MEM, "shmdt/ctl %d %p\n", td->shm_id, td->orig_buffer);
shmdt(td->orig_buffer);
shmctl(td->shm_id, IPC_RMID, &sbuf);
+#endif
}
static int alloc_mem_mmap(struct thread_data *td, size_t total_mem)
{
int flags = 0;
- td->mmapfd = 1;
+ td->mmapfd = -1;
if (td->o.mem_type == MEM_MMAPHUGE) {
unsigned long mask = td->o.hugepage_size - 1;
return 1;
}
if (td->o.mem_type != MEM_MMAPHUGE &&
+ td->o.mem_type != MEM_MMAPSHARED &&
ftruncate(td->mmapfd, total_mem) < 0) {
td_verror(td, errno, "truncate mmap file");
td->orig_buffer = NULL;
return 1;
}
- if (td->o.mem_type == MEM_MMAPHUGE)
+ if (td->o.mem_type == MEM_MMAPHUGE ||
+ td->o.mem_type == MEM_MMAPSHARED)
flags |= MAP_SHARED;
else
flags |= MAP_PRIVATE;
if (td->orig_buffer == MAP_FAILED) {
td_verror(td, errno, "mmap");
td->orig_buffer = NULL;
- if (td->mmapfd != 1) {
+ if (td->mmapfd != 1 && td->mmapfd != -1) {
close(td->mmapfd);
if (td->o.mmapfile)
unlink(td->o.mmapfile);
td->orig_buffer);
munmap(td->orig_buffer, td->orig_buffer_size);
if (td->o.mmapfile) {
- close(td->mmapfd);
+ if (td->mmapfd != -1)
+ close(td->mmapfd);
unlink(td->o.mmapfile);
free(td->o.mmapfile);
}
dprint(FD_MEM, "Alloc %llu for buffers\n", (unsigned long long) total_mem);
- if (td->o.mem_type == MEM_MALLOC)
+ /*
+ * If the IO engine has hooks to allocate/free memory, use those. But
+ * error out if the user explicitly asked for something else.
+ */
+ if (td->io_ops->iomem_alloc) {
+ if (fio_option_is_set(&td->o, mem_type)) {
+ log_err("fio: option 'mem/iomem' conflicts with specified IO engine\n");
+ ret = 1;
+ } else
+ ret = td->io_ops->iomem_alloc(td, total_mem);
+ } else if (td->o.mem_type == MEM_MALLOC)
ret = alloc_mem_malloc(td, total_mem);
else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE)
ret = alloc_mem_shm(td, total_mem);
- else if (td->o.mem_type == MEM_MMAP || td->o.mem_type == MEM_MMAPHUGE)
+ else if (td->o.mem_type == MEM_MMAP || td->o.mem_type == MEM_MMAPHUGE ||
+ td->o.mem_type == MEM_MMAPSHARED)
ret = alloc_mem_mmap(td, total_mem);
else {
log_err("fio: bad mem type: %d\n", td->o.mem_type);
if (td->o.odirect || td->o.oatomic)
total_mem += page_mask;
- if (td->o.mem_type == MEM_MALLOC)
+ if (td->io_ops->iomem_alloc) {
+ if (td->io_ops->iomem_free)
+ td->io_ops->iomem_free(td);
+ } else if (td->o.mem_type == MEM_MALLOC)
free_mem_malloc(td);
else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE)
free_mem_shm(td);
- else if (td->o.mem_type == MEM_MMAP || td->o.mem_type == MEM_MMAPHUGE)
+ else if (td->o.mem_type == MEM_MMAP || td->o.mem_type == MEM_MMAPHUGE ||
+ td->o.mem_type == MEM_MMAPSHARED)
free_mem_mmap(td, total_mem);
else
log_err("Bad memory type %u\n", td->o.mem_type);