2018-05-08 14:08:29 +03:00
|
|
|
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
|
|
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
|
|
*/
|
|
|
|
/******************************************************************************\
|
|
|
|
*
|
|
|
|
* Implement of abstract I/O interface for MMAP.
|
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h> /* IO operations */
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "ior.h"
|
|
|
|
#include "aiori.h"
|
|
|
|
#include "iordef.h"
|
|
|
|
#include "utilities.h"
|
|
|
|
|
|
|
|
/**************************** P R O T O T Y P E S *****************************/
|
2020-05-31 13:58:34 +03:00
|
|
|
static void *MMAP_Create(char *, int flags, aiori_mod_opt_t *);
|
|
|
|
static void *MMAP_Open(char *, int flags, aiori_mod_opt_t *);
|
2018-05-08 14:08:29 +03:00
|
|
|
static IOR_offset_t MMAP_Xfer(int, void *, IOR_size_t *,
|
2020-05-31 13:58:34 +03:00
|
|
|
IOR_offset_t, aiori_mod_opt_t *);
|
|
|
|
static void MMAP_Close(void *, aiori_mod_opt_t *);
|
|
|
|
static void MMAP_Fsync(void *, aiori_mod_opt_t *);
|
|
|
|
static option_help * MMAP_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values);
|
2020-05-30 20:19:48 +03:00
|
|
|
static void MMAP_init_xfer_options(IOR_param_t * params);
|
2020-05-31 13:58:34 +03:00
|
|
|
static int MMAP_check_params(aiori_mod_opt_t * options);
|
2018-05-08 14:08:29 +03:00
|
|
|
/************************** D E C L A R A T I O N S ***************************/
|
|
|
|
|
|
|
|
ior_aiori_t mmap_aiori = {
|
|
|
|
.name = "MMAP",
|
|
|
|
.create = MMAP_Create,
|
|
|
|
.open = MMAP_Open,
|
|
|
|
.xfer = MMAP_Xfer,
|
|
|
|
.close = MMAP_Close,
|
|
|
|
.delete = POSIX_Delete,
|
2020-05-30 20:19:48 +03:00
|
|
|
.init_xfer_options = MMAP_init_xfer_options,
|
2018-07-14 10:41:35 +03:00
|
|
|
.get_version = aiori_get_version,
|
2018-05-08 14:08:29 +03:00
|
|
|
.fsync = MMAP_Fsync,
|
|
|
|
.get_file_size = POSIX_GetFileSize,
|
2019-03-28 01:32:59 +03:00
|
|
|
.get_options = MMAP_options,
|
2020-05-30 20:19:48 +03:00
|
|
|
.check_params = MMAP_check_params
|
2018-05-08 14:08:29 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/***************************** F U N C T I O N S ******************************/
|
2019-03-28 01:32:59 +03:00
|
|
|
typedef struct{
|
|
|
|
int direct_io_ignored; /* this option is ignored */
|
|
|
|
void* mmap_ptr; /* for internal usage */
|
|
|
|
|
|
|
|
int madv_dont_need;
|
|
|
|
int madv_pattern;
|
|
|
|
} mmap_options_t;
|
|
|
|
|
2020-05-31 13:58:34 +03:00
|
|
|
static option_help * MMAP_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){
|
2019-03-28 01:32:59 +03:00
|
|
|
mmap_options_t * o = malloc(sizeof(mmap_options_t));
|
|
|
|
|
|
|
|
if (init_values != NULL){
|
|
|
|
memcpy(o, init_values, sizeof(mmap_options_t));
|
|
|
|
}else{
|
2019-05-23 11:31:05 +03:00
|
|
|
memset(o, 0, sizeof(mmap_options_t));
|
2019-03-28 01:32:59 +03:00
|
|
|
}
|
|
|
|
|
2020-05-31 13:58:34 +03:00
|
|
|
*init_backend_options = (aiori_mod_opt_t*) o;
|
2019-03-28 01:32:59 +03:00
|
|
|
|
|
|
|
option_help h [] = {
|
|
|
|
{0, "mmap.madv_dont_need", "Use advise don't need", OPTION_FLAG, 'd', & o->madv_dont_need},
|
|
|
|
{0, "mmap.madv_pattern", "Use advise to indicate the pattern random/sequential", OPTION_FLAG, 'd', & o->madv_pattern},
|
|
|
|
LAST_OPTION
|
|
|
|
};
|
|
|
|
option_help * help = malloc(sizeof(h));
|
|
|
|
memcpy(help, h, sizeof(h));
|
|
|
|
return help;
|
|
|
|
}
|
2018-05-08 14:08:29 +03:00
|
|
|
|
2020-05-30 20:19:48 +03:00
|
|
|
static IOR_param_t * ior_param = NULL;
|
|
|
|
|
|
|
|
static void MMAP_init_xfer_options(IOR_param_t * params){
|
|
|
|
ior_param = params;
|
2020-05-30 22:09:37 +03:00
|
|
|
aiori_posix_init_xfer_options(params);
|
2020-05-30 20:19:48 +03:00
|
|
|
}
|
|
|
|
|
2020-05-31 13:58:34 +03:00
|
|
|
static int MMAP_check_params(aiori_mod_opt_t * options){
|
2020-05-30 20:19:48 +03:00
|
|
|
if (ior_param->fsyncPerWrite && (ior_param->transferSize & (sysconf(_SC_PAGESIZE) - 1)))
|
|
|
|
ERR("transfer size must be aligned with PAGESIZE for MMAP with fsyncPerWrite");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ior_mmap_file(int *file, int mflags, void *param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
|
|
|
int flags = PROT_READ;
|
2020-05-30 20:19:48 +03:00
|
|
|
IOR_offset_t size = ior_param->expectedAggFileSize;
|
2018-05-08 14:08:29 +03:00
|
|
|
|
2020-05-30 20:19:48 +03:00
|
|
|
if (mflags & IOR_WRONLY || mflags & IOR_RDWR)
|
2018-05-08 14:08:29 +03:00
|
|
|
flags |= PROT_WRITE;
|
2020-05-30 20:19:48 +03:00
|
|
|
mmap_options_t *o = (mmap_options_t*) param;
|
2018-05-08 14:08:29 +03:00
|
|
|
|
2019-03-28 01:32:59 +03:00
|
|
|
o->mmap_ptr = mmap(NULL, size, flags, MAP_SHARED,
|
2018-05-08 14:08:29 +03:00
|
|
|
*file, 0);
|
2019-03-28 01:32:59 +03:00
|
|
|
if (o->mmap_ptr == MAP_FAILED)
|
2018-05-08 14:08:29 +03:00
|
|
|
ERR("mmap() failed");
|
|
|
|
|
2020-05-30 20:19:48 +03:00
|
|
|
if (ior_param->randomOffset)
|
2018-05-08 14:08:29 +03:00
|
|
|
flags = POSIX_MADV_RANDOM;
|
|
|
|
else
|
|
|
|
flags = POSIX_MADV_SEQUENTIAL;
|
2020-05-30 20:19:48 +03:00
|
|
|
|
2019-03-28 01:32:59 +03:00
|
|
|
if(o->madv_pattern){
|
|
|
|
if (posix_madvise(o->mmap_ptr, size, flags) != 0)
|
|
|
|
ERR("madvise() failed");
|
|
|
|
}
|
2018-05-08 14:08:29 +03:00
|
|
|
|
2019-03-28 01:32:59 +03:00
|
|
|
if (o->madv_dont_need){
|
|
|
|
if (posix_madvise(o->mmap_ptr, size, POSIX_MADV_DONTNEED) != 0)
|
|
|
|
ERR("madvise() failed");
|
|
|
|
}
|
2018-05-08 14:08:29 +03:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Creat and open a file through the POSIX interface, then setup mmap.
|
|
|
|
*/
|
2020-05-31 13:58:34 +03:00
|
|
|
static void *MMAP_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
|
|
|
int *fd;
|
|
|
|
|
2020-05-30 20:19:48 +03:00
|
|
|
fd = POSIX_Create(testFileName, flags, param);
|
|
|
|
if (ftruncate(*fd, ior_param->expectedAggFileSize) != 0)
|
2018-05-08 14:08:29 +03:00
|
|
|
ERR("ftruncate() failed");
|
2020-05-30 20:19:48 +03:00
|
|
|
ior_mmap_file(fd, flags, param);
|
2018-05-08 14:08:29 +03:00
|
|
|
return ((void *)fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open a file through the POSIX interface and setup mmap.
|
|
|
|
*/
|
2020-05-31 13:58:34 +03:00
|
|
|
static void *MMAP_Open(char *testFileName, int flags, aiori_mod_opt_t * param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
|
|
|
int *fd;
|
2020-05-30 20:19:48 +03:00
|
|
|
fd = POSIX_Open(testFileName, flags, param);
|
|
|
|
ior_mmap_file(fd, flags, param);
|
2018-05-08 14:08:29 +03:00
|
|
|
return ((void *)fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write or read access to file using mmap
|
|
|
|
*/
|
|
|
|
static IOR_offset_t MMAP_Xfer(int access, void *file, IOR_size_t * buffer,
|
2020-05-31 13:58:34 +03:00
|
|
|
IOR_offset_t length, aiori_mod_opt_t * param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
2020-05-30 20:19:48 +03:00
|
|
|
mmap_options_t *o = (mmap_options_t*) param;
|
2018-05-08 14:08:29 +03:00
|
|
|
if (access == WRITE) {
|
2020-05-30 20:19:48 +03:00
|
|
|
memcpy(o->mmap_ptr + ior_param->offset, buffer, length);
|
2018-05-08 14:08:29 +03:00
|
|
|
} else {
|
2020-05-30 20:19:48 +03:00
|
|
|
memcpy(buffer, o->mmap_ptr + ior_param->offset, length);
|
2018-05-08 14:08:29 +03:00
|
|
|
}
|
|
|
|
|
2020-05-30 20:19:48 +03:00
|
|
|
if (ior_param->fsyncPerWrite == TRUE) {
|
|
|
|
if (msync(o->mmap_ptr + ior_param->offset, length, MS_SYNC) != 0)
|
2018-05-08 14:08:29 +03:00
|
|
|
ERR("msync() failed");
|
2020-05-30 20:19:48 +03:00
|
|
|
if (posix_madvise(o->mmap_ptr + ior_param->offset, length,
|
2018-05-08 14:08:29 +03:00
|
|
|
POSIX_MADV_DONTNEED) != 0)
|
|
|
|
ERR("madvise() failed");
|
|
|
|
}
|
|
|
|
return (length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Perform msync().
|
|
|
|
*/
|
2020-05-31 13:58:34 +03:00
|
|
|
static void MMAP_Fsync(void *fd, aiori_mod_opt_t * param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
2020-05-30 20:19:48 +03:00
|
|
|
mmap_options_t *o = (mmap_options_t*) param;
|
|
|
|
if (msync(o->mmap_ptr, ior_param->expectedAggFileSize, MS_SYNC) != 0)
|
2018-05-08 14:08:29 +03:00
|
|
|
EWARN("msync() failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Close a file through the POSIX interface, after tear down the mmap.
|
|
|
|
*/
|
2020-05-31 13:58:34 +03:00
|
|
|
static void MMAP_Close(void *fd, aiori_mod_opt_t * param)
|
2018-05-08 14:08:29 +03:00
|
|
|
{
|
2020-05-30 20:19:48 +03:00
|
|
|
mmap_options_t *o = (mmap_options_t*) param;
|
|
|
|
if (munmap(o->mmap_ptr, ior_param->expectedAggFileSize) != 0)
|
2018-05-08 14:08:29 +03:00
|
|
|
ERR("munmap failed");
|
2019-03-28 01:32:59 +03:00
|
|
|
o->mmap_ptr = NULL;
|
2018-05-08 14:08:29 +03:00
|
|
|
POSIX_Close(fd, param);
|
|
|
|
}
|