2004-11-22 03:37:56 +03:00
|
|
|
/*
|
2005-11-05 22:57:48 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-11-22 03:37:56 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
2004-10-20 05:03:09 +04:00
|
|
|
#include "ompi_config.h"
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <errno.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <unistd.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
2005-12-12 23:24:07 +03:00
|
|
|
#ifdef HAVE_STRING_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <string.h>
|
2005-12-12 23:24:07 +03:00
|
|
|
#endif /* HAVE_STRING_H */
|
|
|
|
#ifdef HAVE_FCNTL_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <fcntl.h>
|
2005-12-12 23:24:07 +03:00
|
|
|
#endif /* HAVE_FCNTL_H */
|
|
|
|
#ifdef HAVE_TIME_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <time.h>
|
2005-12-12 23:24:07 +03:00
|
|
|
#endif /* HAVE_TIME_H */
|
2004-10-22 20:06:05 +04:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <sys/types.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
2005-12-12 23:24:07 +03:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <sys/stat.h>
|
2005-12-12 23:24:07 +03:00
|
|
|
#endif /* HAVE_SYS_STAT_H */
|
2004-10-22 20:06:05 +04:00
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
2004-06-16 19:41:29 +04:00
|
|
|
#include <sys/mman.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "ompi/constants.h"
|
2005-06-21 21:10:28 +04:00
|
|
|
#include "common_sm_mmap.h"
|
2006-08-20 23:45:28 +04:00
|
|
|
#include "opal/util/basename.h"
|
2005-07-04 03:31:27 +04:00
|
|
|
#include "opal/util/output.h"
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "orte/util/sys_info.h"
|
|
|
|
#include "orte/util/proc_info.h"
|
2004-06-16 19:41:29 +04:00
|
|
|
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(
|
2004-08-06 23:35:57 +04:00
|
|
|
mca_common_sm_mmap_t,
|
2005-07-03 20:06:07 +04:00
|
|
|
opal_object_t,
|
2004-06-16 19:41:29 +04:00
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
2004-08-06 23:35:57 +04:00
|
|
|
/*
|
|
|
|
* Instance that is shared between components that use shared memory
|
|
|
|
*/
|
|
|
|
mca_common_sm_mmap_t *mca_common_sm_mmap = NULL;
|
|
|
|
|
2005-12-12 23:24:07 +03:00
|
|
|
#if !defined(__WINDOWS__)
|
2004-08-06 23:35:57 +04:00
|
|
|
static int mca_common_sm_mmap_open(char* path)
|
2004-06-16 19:41:29 +04:00
|
|
|
{
|
|
|
|
int fd = -1;
|
2005-08-09 01:29:05 +04:00
|
|
|
struct timespec ts;
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2005-12-09 08:10:51 +03:00
|
|
|
/* loop until file can be opened, or until an error, other than
|
2004-08-04 21:22:16 +04:00
|
|
|
* access error, occurs */
|
2005-08-09 01:29:05 +04:00
|
|
|
while (fd < 0) {
|
2004-06-16 19:41:29 +04:00
|
|
|
fd = open(path, O_CREAT|O_RDWR, 0000);
|
2005-08-09 01:29:05 +04:00
|
|
|
if (fd < 0 && errno != EACCES) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,
|
2006-05-16 18:33:41 +04:00
|
|
|
"mca_common_sm_mmap_open: open %s failed with errno=%d\n",
|
2005-08-09 01:29:05 +04:00
|
|
|
path, errno);
|
2004-08-04 21:22:16 +04:00
|
|
|
return -1;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
|
|
|
ts.tv_sec = 0;
|
|
|
|
ts.tv_nsec = 500000;
|
2005-08-09 01:29:05 +04:00
|
|
|
nanosleep(&ts, NULL);
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
|
|
|
|
2004-08-04 21:22:16 +04:00
|
|
|
return fd;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
2005-12-12 23:24:07 +03:00
|
|
|
#endif /* !defined(__WINDOWS__) */
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2004-08-06 23:35:57 +04:00
|
|
|
mca_common_sm_mmap_t* mca_common_sm_mmap_init(size_t size, char *file_name,
|
2004-08-04 21:22:16 +04:00
|
|
|
size_t size_ctl_structure, size_t data_seg_alignment)
|
2004-06-16 19:41:29 +04:00
|
|
|
{
|
2005-12-31 18:06:24 +03:00
|
|
|
int fd = -1, return_code = OMPI_SUCCESS;
|
2006-08-20 23:45:28 +04:00
|
|
|
bool file_previously_opened = false;
|
2006-01-05 02:01:50 +03:00
|
|
|
mca_common_sm_file_header_t* seg = NULL;
|
2005-12-31 18:06:24 +03:00
|
|
|
mca_common_sm_mmap_t* map = NULL;
|
2005-08-15 20:48:43 +04:00
|
|
|
unsigned char *addr = NULL;
|
2004-08-11 20:06:14 +04:00
|
|
|
size_t tmp,mem_offset;
|
2004-08-04 21:22:16 +04:00
|
|
|
|
2005-12-12 23:24:07 +03:00
|
|
|
#if !defined(__WINDOWS__)
|
2006-08-20 23:45:28 +04:00
|
|
|
struct stat s_stat;
|
|
|
|
|
2004-08-04 21:22:16 +04:00
|
|
|
/* input parameter error checks */
|
2004-08-18 19:02:21 +04:00
|
|
|
if( (size < sizeof(mca_common_sm_file_header_t) ) ||
|
2004-08-04 21:22:16 +04:00
|
|
|
( file_name == NULL ) ||
|
2004-08-18 19:02:21 +04:00
|
|
|
( size_ctl_structure <
|
2005-08-09 01:38:27 +04:00
|
|
|
sizeof(mca_common_sm_file_header_t ) )) {
|
2004-08-04 21:22:16 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2005-08-09 01:29:05 +04:00
|
|
|
/* open the backing file. The first process to succeed here will
|
|
|
|
effectively block the others until most of the rest of the
|
|
|
|
setup in this function is complete because the initial perms
|
|
|
|
are 000 (an fchmod() is executed below, enabling the other
|
|
|
|
processes to get in) */
|
2005-12-12 23:24:07 +03:00
|
|
|
fd = mca_common_sm_mmap_open(file_name);
|
2004-08-04 21:22:16 +04:00
|
|
|
if( -1 == fd ) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_common_sm_mmap_init: mca_common_sm_mmap_open failed \n");
|
2004-06-16 19:41:29 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-08-04 21:22:16 +04:00
|
|
|
/* figure out if I am first to attach to file */
|
|
|
|
file_previously_opened=false;
|
|
|
|
return_code=fstat(fd,&s_stat);
|
|
|
|
if( 0 > return_code ) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_common_sm_mmap_init: fstat failed with errno=%d\n", errno);
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
2005-12-31 18:06:24 +03:00
|
|
|
if( s_stat.st_size > 0 )
|
2004-08-04 21:22:16 +04:00
|
|
|
file_previously_opened=true;
|
|
|
|
|
2005-08-09 01:29:05 +04:00
|
|
|
/* first process to open the file, so needs to initialize it */
|
2004-08-04 21:22:16 +04:00
|
|
|
if( !file_previously_opened ) {
|
|
|
|
/* truncate the file to the requested size */
|
|
|
|
if(ftruncate(fd, size) != 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,
|
2004-08-06 23:35:57 +04:00
|
|
|
"mca_common_sm_mmap_init: ftruncate failed with errno=%d\n",
|
2004-08-04 21:22:16 +04:00
|
|
|
errno);
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2004-08-04 21:22:16 +04:00
|
|
|
}
|
|
|
|
}
|
2004-06-16 19:41:29 +04:00
|
|
|
|
|
|
|
/* map the file and initialize segment state */
|
2006-04-24 01:15:09 +04:00
|
|
|
seg = (mca_common_sm_file_header_t*)
|
|
|
|
mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
2004-08-04 21:22:16 +04:00
|
|
|
if( (void*)-1 == seg ) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_common_sm_mmap_init: mmap failed with errno=%d\n",
|
2004-08-04 21:22:16 +04:00
|
|
|
errno);
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
2005-12-12 23:24:07 +03:00
|
|
|
#else
|
2005-12-31 18:06:24 +03:00
|
|
|
HANDLE hMapObject = INVALID_HANDLE_VALUE;
|
2005-12-12 23:24:07 +03:00
|
|
|
LPVOID lpvMem = NULL;
|
2006-08-20 23:45:28 +04:00
|
|
|
char *temp1, *temp2;
|
|
|
|
int rc;
|
2005-12-12 23:24:07 +03:00
|
|
|
|
2006-08-20 23:45:28 +04:00
|
|
|
/**
|
|
|
|
* On Windows the shared file will be created by the OS directly on
|
|
|
|
* the system ressources. Therefore, no file get involved in the
|
|
|
|
* operation. However, a unique key should be used as name for the
|
|
|
|
* shared memory object in order to allow all processes to access
|
|
|
|
* the same unique shared memory region. The key will be obtained
|
|
|
|
* from the original file_name by replacing all path separator
|
|
|
|
* occurences by '/' (as '\' is not allowed on the object name).
|
|
|
|
*/
|
|
|
|
temp1 = strdup(file_name);
|
|
|
|
temp2 = temp1;
|
|
|
|
while( NULL != (temp2 = strchr(temp2, OPAL_PATH_SEP[0])) ) {
|
|
|
|
*temp2 = '/';
|
|
|
|
}
|
2005-12-12 23:24:07 +03:00
|
|
|
hMapObject = CreateFileMapping( INVALID_HANDLE_VALUE, /* use paging file */
|
|
|
|
NULL, /* no security attributes */
|
|
|
|
PAGE_READWRITE, /* read/write access */
|
|
|
|
0, /* size: high 32-bits */
|
|
|
|
size, /* size: low 32-bits */
|
2006-08-20 23:45:28 +04:00
|
|
|
temp1); /* name of map object */
|
|
|
|
if( NULL == hMapObject ) {
|
|
|
|
rc = GetLastError();
|
|
|
|
goto return_error;
|
|
|
|
}
|
2005-12-31 18:06:24 +03:00
|
|
|
if( ERROR_ALREADY_EXISTS == GetLastError() )
|
|
|
|
file_previously_opened=true;
|
2006-08-20 23:45:28 +04:00
|
|
|
free(temp1); /* relase the temporary file name */
|
2005-12-31 18:06:24 +03:00
|
|
|
|
2006-08-20 23:45:28 +04:00
|
|
|
/* Get a pointer to the file-mapped shared memory. */
|
|
|
|
lpvMem = MapViewOfFile( hMapObject, /* object to map view of */
|
|
|
|
FILE_MAP_WRITE, /* read/write access */
|
|
|
|
0, /* high offset: map from */
|
|
|
|
0, /* low offset: beginning */
|
|
|
|
0); /* default: map entire file */
|
2006-01-19 10:07:47 +03:00
|
|
|
if( NULL == lpvMem ) {
|
2006-08-20 23:45:28 +04:00
|
|
|
rc = GetLastError();
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2006-01-19 10:07:47 +03:00
|
|
|
}
|
2006-08-20 23:45:28 +04:00
|
|
|
seg = (mca_common_sm_file_header_t*)lpvMem;
|
2005-12-31 18:06:24 +03:00
|
|
|
#endif /* !defined(__WINDOWS__) */
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2004-08-04 21:22:16 +04:00
|
|
|
/* set up the map object */
|
2004-08-06 23:35:57 +04:00
|
|
|
map = OBJ_NEW(mca_common_sm_mmap_t);
|
2005-02-08 01:13:58 +03:00
|
|
|
strncpy(map->map_path, file_name, OMPI_PATH_MAX);
|
2005-12-31 18:06:24 +03:00
|
|
|
/* the first entry in the file is the control structure. The first
|
2004-08-18 19:02:21 +04:00
|
|
|
entry in the control structure is an mca_common_sm_file_header_t
|
2004-08-11 20:06:14 +04:00
|
|
|
element */
|
2004-06-16 19:41:29 +04:00
|
|
|
map->map_seg = seg;
|
2004-08-11 20:06:14 +04:00
|
|
|
|
2005-08-09 01:38:27 +04:00
|
|
|
/* 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 = ((unsigned char *) seg) + size_ctl_structure;
|
|
|
|
/* calculate how far off alignment we are */
|
|
|
|
tmp = ((size_t) addr) % data_seg_alignment;
|
|
|
|
/* if we're off alignment, then move up to the next alignment */
|
2005-12-31 18:06:24 +03:00
|
|
|
if( tmp > 0 )
|
2005-08-09 01:38:27 +04:00
|
|
|
addr += (data_seg_alignment - tmp);
|
2005-08-09 01:29:05 +04:00
|
|
|
|
2005-08-09 01:38:27 +04:00
|
|
|
/* is addr past end of file ? */
|
2005-12-31 18:06:24 +03:00
|
|
|
if( (unsigned char*)seg+size < addr ) {
|
2005-08-09 01:38:27 +04:00
|
|
|
opal_output(0, "mca_common_sm_mmap_init: memory region too small len %d addr %p\n",
|
|
|
|
size,addr);
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2005-08-09 01:38:27 +04:00
|
|
|
}
|
2005-12-31 18:18:58 +03:00
|
|
|
map->data_addr = addr;
|
|
|
|
} else {
|
|
|
|
map->data_addr = NULL;
|
2004-08-04 21:22:16 +04:00
|
|
|
}
|
2005-12-31 18:06:24 +03:00
|
|
|
mem_offset = addr-(unsigned char *)seg;
|
2004-08-13 20:01:51 +04:00
|
|
|
map->map_addr = (unsigned char *)seg;
|
2004-08-11 20:06:14 +04:00
|
|
|
map->map_size = size;
|
2004-08-04 21:22:16 +04:00
|
|
|
|
|
|
|
/* initialize the segment - only the first process to open the file */
|
|
|
|
if( !file_previously_opened ) {
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_unlock(&seg->seg_lock);
|
2004-08-04 21:22:16 +04:00
|
|
|
seg->seg_inited = false;
|
2004-08-11 20:06:14 +04:00
|
|
|
seg->seg_offset = mem_offset;
|
2004-08-04 21:22:16 +04:00
|
|
|
seg->seg_size = size;
|
|
|
|
}
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2005-12-31 18:06:24 +03:00
|
|
|
#if !defined(__WINDOWS__)
|
2004-06-16 19:41:29 +04:00
|
|
|
/* enable access by other processes on this host */
|
|
|
|
if(fchmod(fd, 0600) != 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_common_sm_mmap_init: fchmod failed with errno=%d :: fd %d\n",
|
2004-08-07 02:47:33 +04:00
|
|
|
errno,fd);
|
2004-06-16 19:41:29 +04:00
|
|
|
OBJ_RELEASE(map);
|
2005-12-31 18:06:24 +03:00
|
|
|
goto return_error;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
2004-08-07 02:47:33 +04:00
|
|
|
close(fd);
|
2006-08-21 08:05:19 +04:00
|
|
|
#else
|
|
|
|
map->hMappedObject = hMapObject;
|
2005-12-31 18:06:24 +03:00
|
|
|
#endif /* !defined(__WINDOWS__) */
|
2004-08-04 21:22:16 +04:00
|
|
|
|
2004-06-16 19:41:29 +04:00
|
|
|
return map;
|
2005-12-31 18:06:24 +03:00
|
|
|
|
|
|
|
return_error:
|
|
|
|
#if !defined(__WINDOWS__)
|
|
|
|
if( -1 != fd ) {
|
|
|
|
fchmod(fd, 0600);
|
|
|
|
close(fd);
|
|
|
|
}
|
2006-04-24 01:15:09 +04:00
|
|
|
if( NULL != seg ) munmap((void*) seg,size);
|
2005-12-31 18:06:24 +03:00
|
|
|
#else
|
2006-08-20 23:45:28 +04:00
|
|
|
{
|
|
|
|
char* localbuf = NULL;
|
|
|
|
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
|
|
NULL, rc, 0, (LPTSTR)&localbuf, 1024, NULL );
|
|
|
|
opal_output( 0, "%s\n", localbuf );
|
|
|
|
LocalFree( localbuf );
|
|
|
|
}
|
2005-12-31 18:06:24 +03:00
|
|
|
if( NULL != lpvMem ) UnmapViewOfFile( lpvMem );
|
|
|
|
if( NULL != hMapObject ) CloseHandle(hMapObject);
|
|
|
|
#endif /* !defined(__WINDOWS__) */
|
|
|
|
|
|
|
|
return NULL;
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
|
|
|
|
2005-12-31 18:06:24 +03:00
|
|
|
int mca_common_sm_mmap_fini( mca_common_sm_mmap_t* sm_mmap )
|
|
|
|
{
|
2005-12-31 19:11:58 +03:00
|
|
|
int rc = OMPI_SUCCESS;
|
|
|
|
|
2005-12-31 18:06:24 +03:00
|
|
|
if( NULL != sm_mmap->map_seg ) {
|
|
|
|
#if !defined(__WINDOWS__)
|
2006-04-24 01:15:09 +04:00
|
|
|
rc = munmap((void*) sm_mmap->map_addr, sm_mmap->map_size );
|
2005-12-31 19:11:58 +03:00
|
|
|
sm_mmap->map_addr = NULL;
|
|
|
|
sm_mmap->map_size = 0;
|
2005-12-31 18:06:24 +03:00
|
|
|
#else
|
2005-12-31 19:11:58 +03:00
|
|
|
BOOL return_error = UnmapViewOfFile( sm_mmap->map_addr );
|
2005-12-31 18:06:24 +03:00
|
|
|
if( false == return_error ) {
|
2005-12-31 19:11:58 +03:00
|
|
|
rc = GetLastError();
|
2005-12-31 18:06:24 +03:00
|
|
|
}
|
2006-08-20 23:45:28 +04:00
|
|
|
CloseHandle(sm_mmap->hMappedObject);
|
|
|
|
|
2005-12-31 18:06:24 +03:00
|
|
|
#endif /* !defined(__WINDOWS__) */
|
|
|
|
}
|
2005-12-31 19:11:58 +03:00
|
|
|
return rc;
|
2005-12-31 18:06:24 +03:00
|
|
|
}
|
2004-06-16 19:41:29 +04:00
|
|
|
|
2004-08-11 20:06:14 +04:00
|
|
|
/**
|
|
|
|
* allocate memory from a previously allocated shared memory
|
|
|
|
* block.
|
|
|
|
*
|
|
|
|
* @param size size of request, in bytes (IN)
|
|
|
|
*
|
|
|
|
* @retval addr virtual address
|
|
|
|
*/
|
2005-06-21 21:10:28 +04:00
|
|
|
|
|
|
|
void* mca_common_sm_mmap_seg_alloc(
|
|
|
|
struct mca_mpool_base_module_t* mpool,
|
|
|
|
size_t* size,
|
2005-06-25 01:12:38 +04:00
|
|
|
mca_mpool_base_registration_t** registration)
|
2004-06-16 19:41:29 +04:00
|
|
|
{
|
2004-08-06 23:35:57 +04:00
|
|
|
mca_common_sm_mmap_t* map = mca_common_sm_mmap;
|
2004-08-18 19:02:21 +04:00
|
|
|
mca_common_sm_file_header_t* seg = map->map_seg;
|
2004-06-16 19:41:29 +04:00
|
|
|
void* addr;
|
|
|
|
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_lock(&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 {
|
2006-04-24 01:14:03 +04:00
|
|
|
size_t fixup;
|
|
|
|
|
2004-08-11 20:06:14 +04:00
|
|
|
/* add base address to segment offset */
|
|
|
|
addr = map->data_addr + seg->seg_offset;
|
2004-06-16 19:41:29 +04:00
|
|
|
seg->seg_offset += *size;
|
2006-04-24 01:14:03 +04:00
|
|
|
|
|
|
|
/* fix up seg_offset so next allocation is aligned on a
|
|
|
|
sizeof(long) boundry. Do it here so that we don't have to
|
|
|
|
check before checking remaining size in buffer */
|
|
|
|
if ((fixup = (seg->seg_offset & (sizeof(long) - 1))) > 0) {
|
|
|
|
seg->seg_offset += sizeof(long) - fixup;
|
|
|
|
}
|
2004-06-16 19:41:29 +04:00
|
|
|
}
|
2005-08-09 01:29:05 +04:00
|
|
|
if (NULL != registration) {
|
2005-07-14 23:10:46 +04:00
|
|
|
*registration = NULL;
|
2005-08-09 01:29:05 +04:00
|
|
|
}
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_unlock(&seg->seg_lock);
|
2004-06-16 19:41:29 +04:00
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|