2004-06-16 19:41:29 +04:00
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/errno.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
2004-06-17 23:16:51 +04:00
|
|
|
#include "include/constants.h"
|
2004-06-16 19:41:29 +04:00
|
|
|
#include "util/output.h"
|
2004-06-17 20:13:20 +04:00
|
|
|
#include "util/sys_info.h"
|
2004-06-16 19:41:29 +04:00
|
|
|
#include "mca/pcm/pcm.h"
|
|
|
|
#include "mpool_sm.h"
|
|
|
|
#include "mpool_sm_mmap.h"
|
|
|
|
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(
|
|
|
|
mca_mpool_sm_mmap_t,
|
|
|
|
ompi_object_t,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
static mca_mpool_sm_mmap_t* mca_mpool_sm_mmap_open(char* path)
|
|
|
|
{
|
|
|
|
mca_mpool_sm_mmap_t* map;
|
|
|
|
mca_mpool_sm_segment_t* seg;
|
|
|
|
int fd = -1;
|
2004-06-17 00:01:19 +04:00
|
|
|
struct stat sbuf;
|
2004-06-16 19:41:29 +04:00
|
|
|
|
|
|
|
while(fd < 0) {
|
|
|
|
struct timespec ts;
|
|
|
|
fd = open(path, O_CREAT|O_RDWR, 0000);
|
|
|
|
if(fd < 0 && errno != EACCES) {
|
|
|
|
ompi_output(0, "mca_ptl_sm_mmap_open: open failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ts.tv_sec = 0;
|
|
|
|
ts.tv_nsec = 500000;
|
|
|
|
nanosleep(&ts,NULL);
|
|
|
|
}
|
|
|
|
|
2004-06-17 00:01:19 +04:00
|
|
|
if(fstat(fd, &sbuf) != 0) {
|
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_open: fstat failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-06-16 19:41:29 +04:00
|
|
|
/* map the file and initialize segment state */
|
2004-06-17 00:01:19 +04:00
|
|
|
seg = mmap(NULL, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
2004-06-16 19:41:29 +04:00
|
|
|
if(NULL == seg) {
|
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_open: mmap failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
map = OBJ_NEW(mca_mpool_sm_mmap_t);
|
|
|
|
map->map_seg = seg;
|
|
|
|
map->map_addr = (unsigned char*)(seg + 1);
|
|
|
|
map->map_size = seg->seg_size - sizeof(mca_mpool_sm_segment_t);
|
|
|
|
close(fd);
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mca_mpool_sm_mmap_t* mca_mpool_sm_mmap_init(size_t size)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
mca_mpool_sm_segment_t* seg;
|
|
|
|
mca_mpool_sm_mmap_t* map;
|
|
|
|
char path[PATH_MAX];
|
|
|
|
|
2004-06-17 20:13:20 +04:00
|
|
|
sprintf(path, "%s/mmap.%s", ompi_system_info.session_dir, ompi_system_info.nodename);
|
2004-06-16 19:41:29 +04:00
|
|
|
fd = open(path, O_CREAT|O_RDWR, 0000);
|
|
|
|
if(fd < 0) {
|
|
|
|
if(errno == EACCES)
|
|
|
|
return mca_mpool_sm_mmap_open(path);
|
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_init: open failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* truncate the file to the requested size */
|
2004-06-17 00:01:19 +04:00
|
|
|
if(ftruncate(fd, size) != 0) {
|
2004-06-16 19:41:29 +04:00
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_init: ftruncate failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* map the file and initialize segment state */
|
|
|
|
seg = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
2004-06-23 18:00:21 +04:00
|
|
|
if(seg == (void*)-1) {
|
2004-06-16 19:41:29 +04:00
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_init: mmap failed with errno=%d\n", errno);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
spinunlock(&seg->seg_lock);
|
|
|
|
seg->seg_offset = 0;
|
|
|
|
seg->seg_size = size;
|
|
|
|
|
|
|
|
map = OBJ_NEW(mca_mpool_sm_mmap_t);
|
|
|
|
strncpy(map->map_path, path, PATH_MAX);
|
|
|
|
map->map_seg = seg;
|
2004-06-17 20:13:20 +04:00
|
|
|
map->map_addr = (unsigned char*)(seg+1);
|
2004-06-16 19:41:29 +04:00
|
|
|
map->map_size = size - sizeof(mca_mpool_sm_segment_t);
|
|
|
|
|
|
|
|
/* enable access by other processes on this host */
|
|
|
|
if(fchmod(fd, 0600) != 0) {
|
|
|
|
ompi_output(0, "mca_mpool_sm_mmap_init: fchmod failed with errno=%d\n", errno);
|
|
|
|
OBJ_RELEASE(map);
|
|
|
|
close(fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void* mca_mpool_sm_mmap_alloc(size_t* size)
|
|
|
|
{
|
|
|
|
mca_mpool_sm_mmap_t* map = mca_mpool_sm_module.sm_mmap;
|
|
|
|
mca_mpool_sm_segment_t* seg = map->map_seg;
|
|
|
|
void* addr;
|
|
|
|
|
|
|
|
spinlock(&seg->seg_lock);
|
2004-06-17 20:13:20 +04:00
|
|
|
if(seg->seg_offset + *size > map->map_size) {
|
2004-06-16 19:41:29 +04:00
|
|
|
addr = NULL;
|
|
|
|
} else {
|
2004-06-17 00:01:19 +04:00
|
|
|
addr = map->map_addr + seg->seg_offset;
|
2004-06-16 19:41:29 +04:00
|
|
|
seg->seg_offset += *size;
|
|
|
|
}
|
|
|
|
spinunlock(&seg->seg_lock);
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
2004-06-18 00:33:52 +04:00
|
|
|
|