2014-02-03 21:01:46 +04:00
|
|
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
2012-08-16 23:11:35 +04:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copyright (c) 2009-2012 Oak Ridge National Laboratory. All rights reserved.
|
|
|
|
* Copyright (c) 2009-2012 Mellanox Technologies. All rights reserved.
|
2014-02-03 21:01:46 +04:00
|
|
|
* Copyright (c) 2012-2014 Los Alamos National Security, LLC. All rights
|
|
|
|
* reserved.
|
2014-01-09 07:57:55 +04:00
|
|
|
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
2012-08-16 23:11:35 +04:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ompi_config.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
2014-01-09 07:57:55 +04:00
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
#include <strings.h>
|
|
|
|
#endif
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
#include "ompi/proc/proc.h"
|
2013-02-06 01:52:55 +04:00
|
|
|
#include "ompi/patterns/comm/coll_ops.h"
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
#include "opal/dss/dss.h"
|
|
|
|
#include "opal/util/error.h"
|
|
|
|
#include "opal/util/output.h"
|
|
|
|
#include "opal/class/opal_list.h"
|
|
|
|
#include "opal/class/opal_hash_table.h"
|
|
|
|
#include "opal/align.h"
|
|
|
|
|
|
|
|
#include "bcol_basesmuma.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define SM_BACKING_FILE_NAME_MAX_LEN 256
|
|
|
|
|
|
|
|
struct file_info_t {
|
|
|
|
uint32_t vpid;
|
|
|
|
uint32_t jobid;
|
|
|
|
uint64_t file_size;
|
|
|
|
uint64_t size_ctl_structure;
|
|
|
|
uint64_t data_seg_alignment;
|
|
|
|
char file_name[SM_BACKING_FILE_NAME_MAX_LEN];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* need to allocate space for the peer */
|
|
|
|
static void bcol_basesmuma_smcm_proc_item_t_construct
|
2013-01-28 03:25:10 +04:00
|
|
|
(bcol_basesmuma_smcm_proc_item_t * item) {
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* need to free the space for the peer */
|
|
|
|
static void bcol_basesmuma_smcm_proc_item_t_destruct
|
2014-02-03 21:01:46 +04:00
|
|
|
(bcol_basesmuma_smcm_proc_item_t * item) {
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(bcol_basesmuma_smcm_proc_item_t,
|
2014-02-03 21:01:46 +04:00
|
|
|
opal_list_item_t,
|
|
|
|
bcol_basesmuma_smcm_proc_item_t_construct,
|
|
|
|
bcol_basesmuma_smcm_proc_item_t_destruct);
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bcol_basesmuma_smcm_mmap_t* bcol_basesmuma_smcm_create_mmap(int fd, size_t size, char *file_name,
|
2014-02-03 21:01:46 +04:00
|
|
|
size_t size_ctl_structure,
|
|
|
|
size_t data_seg_alignment)
|
2012-08-16 23:11:35 +04:00
|
|
|
{
|
|
|
|
bcol_basesmuma_smcm_mmap_t *map;
|
|
|
|
bcol_basesmuma_smcm_file_header_t *seg;
|
|
|
|
unsigned char *addr = NULL;
|
|
|
|
|
|
|
|
/* map the file and initialize segment state */
|
|
|
|
seg = (bcol_basesmuma_smcm_file_header_t*)
|
|
|
|
mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if((void*)-1 == seg) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set up the map object */
|
|
|
|
map = (bcol_basesmuma_smcm_mmap_t* )malloc(sizeof(bcol_basesmuma_smcm_mmap_t));
|
|
|
|
assert(map);
|
|
|
|
|
|
|
|
strncpy(map->map_path, file_name, OPAL_PATH_MAX);
|
|
|
|
/* the first entry in the file is the control structure. The first
|
|
|
|
entry in the control structure is an mca_common_sm_file_header_t
|
|
|
|
element */
|
|
|
|
map->map_seg = seg;
|
|
|
|
|
|
|
|
addr = ((unsigned char *)seg) + size_ctl_structure;
|
|
|
|
/* If we have a data segment (i.e., if 0 != data_seg_alignment),
|
|
|
|
then make it the first aligned address after the control
|
|
|
|
structure. */
|
|
|
|
if (0 != data_seg_alignment) {
|
|
|
|
addr = OPAL_ALIGN_PTR(addr, data_seg_alignment, unsigned char*);
|
|
|
|
|
|
|
|
/* is addr past end of file ? */
|
|
|
|
if((unsigned char*)seg + size < addr) {
|
|
|
|
opal_output(0, "bcol_basesmuma_smcm_mmap_init: "
|
2014-02-03 21:01:46 +04:00
|
|
|
"memory region too small len %lu addr %p\n",
|
|
|
|
(unsigned long)size, addr);
|
2012-08-16 23:11:35 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
map->data_addr = addr;
|
|
|
|
map->map_addr = (unsigned char *)seg;
|
|
|
|
map->map_size = size;
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* smcm_allgather_connection:
|
|
|
|
This function is called when a shared memory subgroup wants to establish shared memory "connections" among
|
|
|
|
a group of processes.
|
|
|
|
|
2012-08-16 23:11:35 +04:00
|
|
|
This function DOES NOT create any shared memory backing files, it only mmaps already existing files. Shared
|
2014-02-03 21:01:46 +04:00
|
|
|
memory files are created by the shared memory registration function
|
2012-08-16 23:11:35 +04:00
|
|
|
-----------------------------------------------------------------------------------------------------------
|
|
|
|
Input params:
|
|
|
|
|
|
|
|
- sbgp module The subgrouping module contains the list of ranks to wire up.
|
|
|
|
|
|
|
|
- peer_list An opal list containing a list of bcol_basesmuma_smcm_proc_item_t types. This
|
2014-02-03 21:01:46 +04:00
|
|
|
contains a list of peers whose shared memory files I have already mapped.
|
2012-08-16 23:11:35 +04:00
|
|
|
Upon completion of the allgather exchange with all members of the group and depending on the
|
|
|
|
value of "map_all", my peers' shared memory files are mapped into my local virtual memory
|
2014-02-03 21:01:46 +04:00
|
|
|
space, with all pertinent information being stored in an bcol_basesmuma_smcm_proc_item_t which is
|
|
|
|
subsequently appended onto the "peer_list".
|
|
|
|
|
|
|
|
- comm The ompi_communicator_t communicator.
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
- input A data struct that caches the information about my shared memory file.
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
- map_all Bool that determines whether or not to go ahead and map the files from all of the peers
|
2012-08-16 23:11:35 +04:00
|
|
|
defined in the sbgp-ing module. If map_all == true, then go ahead and mmap all of the files
|
|
|
|
obtained in the exchange and append the information to the "peer_list". If map_all == false
|
2014-02-03 21:01:46 +04:00
|
|
|
then make a check and only mmap those peers' files whose vpid/jobid/filename combination do
|
|
|
|
not already exist in the "peer_list". Once mapping is completed, append this peer's information
|
2012-08-16 23:11:35 +04:00
|
|
|
to the "peer_list".
|
|
|
|
-----------------------------------------------------------------------------------------------------------
|
2014-02-03 21:01:46 +04:00
|
|
|
*
|
|
|
|
*/
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
|
|
|
|
int bcol_basesmuma_smcm_allgather_connection(
|
2014-02-03 21:01:46 +04:00
|
|
|
mca_bcol_basesmuma_module_t *sm_bcol_module,
|
|
|
|
mca_sbgp_base_module_t *module,
|
|
|
|
opal_list_t *peer_list,
|
|
|
|
bcol_basesmuma_smcm_proc_item_t ***back_files,
|
|
|
|
ompi_communicator_t *comm,
|
|
|
|
bcol_basesmuma_smcm_file_t input,
|
|
|
|
char *base_fname,
|
|
|
|
bool map_all)
|
2012-08-16 23:11:35 +04:00
|
|
|
{
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* define local variables */
|
|
|
|
|
|
|
|
int rc, i, fd, n_files_mapped;
|
|
|
|
ptrdiff_t mem_offset;
|
|
|
|
ompi_proc_t *proc_temp, *my_id;
|
|
|
|
bcol_basesmuma_smcm_proc_item_t *temp;
|
|
|
|
bcol_basesmuma_smcm_proc_item_t *item_ptr;
|
|
|
|
bcol_basesmuma_smcm_proc_item_t **backing_files;
|
|
|
|
struct file_info_t local_file;
|
|
|
|
struct file_info_t *all_files=NULL;
|
|
|
|
signal(SIGSEGV, SIG_DFL);
|
|
|
|
signal(SIGABRT, SIG_DFL);
|
|
|
|
/* sanity check */
|
|
|
|
if (strlen(input.file_name) > SM_BACKING_FILE_NAME_MAX_LEN-1) {
|
|
|
|
opal_output (0, "backing file name too long: %s len :: %d\n",
|
|
|
|
input.file_name, (int) strlen(input.file_name));
|
|
|
|
return OMPI_ERR_BAD_PARAM;
|
2014-01-22 19:39:19 +04:00
|
|
|
}
|
2014-02-03 21:01:46 +04:00
|
|
|
|
|
|
|
backing_files = (bcol_basesmuma_smcm_proc_item_t **)
|
|
|
|
calloc(module->group_size, sizeof(bcol_basesmuma_smcm_proc_item_t *));
|
|
|
|
if (!backing_files) {
|
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*back_files = backing_files;
|
|
|
|
|
|
|
|
my_id = ompi_proc_local();
|
|
|
|
|
|
|
|
/* check to see if we have already mapped all the files, if we have
|
|
|
|
* just need to fill in backing_files array, and we are done
|
|
|
|
*/
|
|
|
|
for (i = 0, n_files_mapped = 0; i < module->group_size; i++) {
|
|
|
|
/* get the proc info */
|
|
|
|
proc_temp = ompi_comm_peer_lookup(comm,module->group_list[i]);
|
|
|
|
|
|
|
|
if (i == sm_bcol_module->super.sbgp_partner_module->my_index) {
|
|
|
|
continue;
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
2014-02-03 21:01:46 +04:00
|
|
|
|
|
|
|
OPAL_LIST_FOREACH(item_ptr, peer_list, bcol_basesmuma_smcm_proc_item_t) {
|
|
|
|
/* if the vpid/jobid/filename combination already exists in the list,
|
|
|
|
then do not map this peer's file --- because you already have */
|
|
|
|
if (proc_temp->proc_name.vpid == item_ptr->peer.vpid &&
|
|
|
|
proc_temp->proc_name.jobid == item_ptr->peer.jobid
|
|
|
|
&& (strstr(item_ptr->sm_file.file_name,base_fname)) ){
|
|
|
|
|
|
|
|
/* record file data */
|
|
|
|
backing_files[i] = item_ptr;
|
|
|
|
n_files_mapped++;
|
|
|
|
/* found it - no need to continue looking */
|
|
|
|
break;
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
2014-02-03 21:01:46 +04:00
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* check to see if we are done - our own files are not in this list*/
|
|
|
|
if (n_files_mapped == (module->group_size-1) ) {
|
|
|
|
return OMPI_SUCCESS;
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* Phase One:
|
|
|
|
gather a list of processes that will participate in the allgather - I'm
|
|
|
|
preparing this list from the sbgp-ing module that was passed into the function */
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* fill in local file information */
|
|
|
|
local_file.vpid=my_id->proc_name.vpid;
|
|
|
|
local_file.jobid=my_id->proc_name.jobid;
|
|
|
|
local_file.file_size=input.size;
|
|
|
|
local_file.size_ctl_structure=input.size_ctl_structure;
|
|
|
|
local_file.data_seg_alignment=input.data_seg_alignment;
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
strcpy (local_file.file_name, input.file_name);
|
|
|
|
|
|
|
|
/* will exchange this data type as a string of characters -
|
|
|
|
* this routine is first called before MPI_init() completes
|
|
|
|
* and before error handling is setup, so can't use the
|
|
|
|
* MPI data types to send this data */
|
|
|
|
all_files = (struct file_info_t *) calloc(module->group_size,
|
|
|
|
sizeof (struct file_info_t));
|
|
|
|
if (!all_files) {
|
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* exchange data */
|
|
|
|
rc = comm_allgather_pml(&local_file,all_files,sizeof(struct file_info_t), MPI_CHAR,
|
|
|
|
sm_bcol_module->super.sbgp_partner_module->my_index,
|
|
|
|
sm_bcol_module->super.sbgp_partner_module->group_size,
|
|
|
|
sm_bcol_module->super.sbgp_partner_module->group_list,
|
|
|
|
sm_bcol_module->super.sbgp_partner_module->group_comm);
|
|
|
|
if( OMPI_SUCCESS != rc ) {
|
|
|
|
opal_output (0, "failed in comm_allgather_pml. Error code: %d\n", rc);
|
|
|
|
goto Error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Phase four:
|
|
|
|
loop through the receive buffer, unpack the data recieved from remote peers */
|
|
|
|
|
|
|
|
for (i = 0; i < module->group_size; i++) {
|
|
|
|
struct file_info_t *rem_file = all_files + i;
|
|
|
|
|
|
|
|
/* check if this is my index or if the file is already mapped (set above). ther
|
|
|
|
* is no reason to look through the peer list again because no two members of
|
|
|
|
* the group will have the same vpid/jobid pair. ignore this previously found
|
|
|
|
* mapping if map_all was requested (NTH: not sure why exactly since we re-map
|
|
|
|
* and already mapped file) */
|
|
|
|
if (sm_bcol_module->super.sbgp_partner_module->my_index == i || (!map_all && backing_files[i])) {
|
|
|
|
continue;
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
2014-02-03 21:01:46 +04:00
|
|
|
|
|
|
|
temp = OBJ_NEW(bcol_basesmuma_smcm_proc_item_t);
|
|
|
|
if (!temp) {
|
|
|
|
rc = OMPI_ERR_OUT_OF_RESOURCE;
|
2012-08-16 23:11:35 +04:00
|
|
|
goto Error;
|
|
|
|
}
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
temp->peer.vpid = rem_file->vpid;
|
|
|
|
temp->peer.jobid = rem_file->jobid;
|
|
|
|
|
|
|
|
temp->sm_file.file_name = strdup (rem_file->file_name);
|
|
|
|
if (!temp->sm_file.file_name) {
|
|
|
|
rc = OMPI_ERR_OUT_OF_RESOURCE;
|
|
|
|
OBJ_RELEASE(temp);
|
2012-08-16 23:11:35 +04:00
|
|
|
goto Error;
|
|
|
|
}
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
temp->sm_file.size = (size_t) rem_file->file_size;
|
|
|
|
temp->sm_file.mpool_size = (size_t) rem_file->file_size;
|
|
|
|
temp->sm_file.size_ctl_structure = (size_t) rem_file->size_ctl_structure;
|
|
|
|
temp->sm_file.data_seg_alignment = (size_t) rem_file->data_seg_alignment;
|
|
|
|
|
|
|
|
/* Phase Five:
|
|
|
|
If map_all == true, then we map every peer's file
|
|
|
|
else we check to see if I have already mapped this
|
|
|
|
vpid/jobid/filename combination and if I have, then
|
|
|
|
I do not mmap this peer's file.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
fd = open(temp->sm_file.file_name, O_RDWR, 0600);
|
|
|
|
if (0 > fd) {
|
|
|
|
opal_output (0, "SMCM Allgather failed to open sm backing file %s. errno = %d\n", temp->sm_file.file_name, errno);
|
|
|
|
assert (0);
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
goto Error;
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* map the file */
|
|
|
|
temp->sm_mmap = bcol_basesmuma_smcm_create_mmap(fd,temp->sm_file.size,
|
|
|
|
temp->sm_file.file_name,
|
|
|
|
temp->sm_file.size_ctl_structure,
|
|
|
|
getpagesize());
|
|
|
|
if (NULL == temp->sm_mmap) {
|
|
|
|
opal_output (0, "mmapping failed to map remote peer's file\n");
|
|
|
|
OBJ_RELEASE(temp);
|
|
|
|
rc = OMPI_ERROR;
|
|
|
|
goto Error;
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* compute memory offset */
|
|
|
|
mem_offset = (ptrdiff_t) temp->sm_mmap->data_addr -
|
|
|
|
(ptrdiff_t) temp->sm_mmap->map_seg;
|
|
|
|
temp->sm_mmap->map_seg->seg_offset = mem_offset;
|
|
|
|
temp->sm_mmap->map_seg->seg_size = temp->sm_file.size - mem_offset;
|
|
|
|
/* more stuff to follow */
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* append this peer's info, including shared memory map addr, onto the
|
|
|
|
peer_list */
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* record file data */
|
|
|
|
backing_files[i] = (bcol_basesmuma_smcm_proc_item_t *) temp;
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
opal_list_append(peer_list, (opal_list_item_t*) temp);
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
rc = OMPI_SUCCESS;
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
Error:
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* error clean-up and return */
|
|
|
|
if (NULL != all_files) {
|
|
|
|
free(all_files);
|
|
|
|
}
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
return rc;
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(
|
2014-02-03 21:01:46 +04:00
|
|
|
bcol_basesmuma_smcm_mmap_t,
|
|
|
|
opal_list_item_t,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
);
|
2012-08-16 23:11:35 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mmap the specified file as a shared file. No information exchange with other
|
|
|
|
* processes takes place within this routine.
|
|
|
|
* This function assumes that the memory has already been allocated, and only the
|
|
|
|
* mmap needs to be done.
|
|
|
|
*/
|
|
|
|
bcol_basesmuma_smcm_mmap_t *bcol_basesmuma_smcm_mem_reg(void *in_ptr,
|
2014-02-03 21:01:46 +04:00
|
|
|
size_t length,
|
|
|
|
size_t alignment,
|
|
|
|
char* file_name)
|
2012-08-16 23:11:35 +04:00
|
|
|
{
|
2014-02-03 21:01:46 +04:00
|
|
|
/* local variables */
|
|
|
|
int fd = -1;
|
|
|
|
bcol_basesmuma_smcm_mmap_t *map = NULL;
|
|
|
|
/* if pointer is not allocated - return error. We have no clue how the user will allocate or
|
|
|
|
* free this memory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* open the shared memory backing file */
|
|
|
|
|
|
|
|
fd = open(file_name, O_CREAT|O_RDWR,0600);
|
|
|
|
if (fd < 0) {
|
|
|
|
opal_output(0, "basesmuma shared memory allocation open failed with errno: %d\n",
|
|
|
|
errno);
|
|
|
|
} else if (0 != ftruncate(fd,length)) {
|
|
|
|
opal_output(0, "basesmuma shared memory allocation ftruncate failed with errno: %d\n",
|
|
|
|
errno);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
map = bcol_basesmuma_smcm_reg_mmap(in_ptr, fd, length, alignment, file_name);
|
|
|
|
if (NULL == map) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* takes us to the top of the control structure */
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
2012-08-16 23:11:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bcol_basesmuma_smcm_mmap_t * bcol_basesmuma_smcm_reg_mmap(void *in_ptr,
|
2014-02-03 21:01:46 +04:00
|
|
|
int fd,
|
|
|
|
size_t length,
|
|
|
|
size_t alignment,
|
|
|
|
char *file_name)
|
2012-08-16 23:11:35 +04:00
|
|
|
{
|
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* local variables */
|
|
|
|
bcol_basesmuma_smcm_mmap_t *map;
|
|
|
|
bcol_basesmuma_smcm_file_header_t *seg;
|
|
|
|
unsigned char* myaddr = NULL;
|
2012-08-16 23:11:35 +04:00
|
|
|
|
2014-02-03 21:01:46 +04:00
|
|
|
/* map the file and initialize the segment state */
|
|
|
|
seg = (bcol_basesmuma_smcm_file_header_t *)
|
|
|
|
mmap(in_ptr, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0);
|
|
|
|
if((void*)-1 == seg) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set up the map object */
|
|
|
|
|
|
|
|
/*map = OBJ_NEW(mca_common_sm_mmap_t); */
|
|
|
|
map=(bcol_basesmuma_smcm_mmap_t *)malloc(sizeof(bcol_basesmuma_smcm_mmap_t));
|
|
|
|
assert(map);
|
|
|
|
strncpy(map->map_path, file_name, OPAL_PATH_MAX);
|
|
|
|
|
|
|
|
/* the first entry in the file is the control structure. the first entry
|
|
|
|
in the control structure is an mca_common_sm_file_header_t element */
|
|
|
|
map->map_seg = seg;
|
|
|
|
|
|
|
|
myaddr = (unsigned char *) seg;
|
|
|
|
/* if we have a data segment (i.e. if 0 != data_seg_alignement) */
|
|
|
|
|
|
|
|
if ( 0 != alignment) {
|
|
|
|
myaddr = OPAL_ALIGN_PTR(myaddr, alignment, unsigned char*);
|
|
|
|
|
|
|
|
/* is addr past the end of the file? */
|
|
|
|
if ((unsigned char *) seg+length < myaddr) {
|
|
|
|
opal_output(0, "mca_bcol_basesmuma_sm_alloc_mmap: memory region too small len %lu add %p\n",
|
|
|
|
(unsigned long) length, myaddr);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
map->data_addr = (unsigned char*) myaddr;
|
|
|
|
map->map_addr = (unsigned char*) seg;
|
|
|
|
map->map_size = length;
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|