Commit d3fae782 authored by Shane Snyder's avatar Shane Snyder

update how module & record registration

- modules now receive a memory buffer after successfully
registering with darshan-core. modules can request a specific
memory amount, but may not be honored depending on the configured
darshan memory limit
- split the previous register_record function into 2 parts:
    * lookup() -> lookup darshan_record_id corresp. to path name
    * register() -> register record_id & name with darshan-core
- register_record now returns true if the record added; false
otherwise (if module was out of memory or darshan is out of memory
for storing id->name mappings)
parent 032f99b4
......@@ -55,14 +55,15 @@ struct darshan_core_runtime
struct darshan_core_record_ref *rec_hash;
int rec_hash_cnt;
struct darshan_core_module* mod_array[DARSHAN_MAX_MODS];
char comp_buf[DARSHAN_COMP_BUF_SIZE]; /* TODO: why is this allocated statically? only used in shutdown */
int mod_mem_used;
char comp_buf[DARSHAN_COMP_BUF_SIZE];
double wtime_offset;
};
struct darshan_core_module
{
darshan_module_id id;
struct darshan_module_funcs mod_funcs;
int mem_avail;
};
struct darshan_core_record_ref
......
......@@ -53,6 +53,9 @@
#endif
/* default number of records to attempt to store for each module */
#define DARSHAN_DEF_MOD_REC_COUNT 1024
/* module developers provide the following functions to darshan-core */
struct darshan_module_funcs
{
......@@ -98,8 +101,8 @@ struct darshan_module_funcs
void darshan_core_register_module(
darshan_module_id mod_id,
struct darshan_module_funcs *funcs,
int *inout_mod_size,
void **mod_buf,
int *mod_buf_size,
int *my_rank,
int *sys_mem_alignment);
......@@ -111,6 +114,15 @@ void darshan_core_register_module(
void darshan_core_unregister_module(
darshan_module_id mod_id);
/* darshan_core_lookup_record()
*
*
*/
void darshan_core_lookup_record(
void *name,
int name_len,
darshan_record_id *rec_id);
/* darshan_core_register_record()
*
* Register the Darshan record given by 'name' with the darshan-core
......@@ -125,13 +137,11 @@ void darshan_core_unregister_module(
* is an output pointer storing the file system alignment value for the
* given record.
*/
void darshan_core_register_record(
int darshan_core_register_record(
darshan_record_id rec_id,
void *name,
int name_len,
int rec_size,
darshan_module_id mod_id,
int printable_flag,
darshan_record_id *rec_id,
int rec_size,
int *file_alignment);
/* darshan_core_unregister_record()
......
......@@ -200,9 +200,8 @@ void darshan_core_initialize(int argc, char **argv)
sys_page_size = sysconf(_SC_PAGESIZE);
assert(sys_page_size > 0);
/* XXX: MMAP */
mmap_size = sizeof(struct darshan_header) + DARSHAN_JOB_RECORD_SIZE +
DARSHAN_MOD_MEM_MAX;
+ DARSHAN_RECORD_BUF_SIZE + DARSHAN_MOD_MEM_MAX;
if(mmap_size % sys_page_size)
mmap_size = ((mmap_size / sys_page_size) + 1) * sys_page_size;
......@@ -262,7 +261,6 @@ void darshan_core_initialize(int argc, char **argv)
((char *)init_core->log_exemnt_p + DARSHAN_EXE_LEN + 1);
init_core->log_mod_p = (void *)
((char *)init_core->log_rec_p + DARSHAN_RECORD_BUF_SIZE);
/* XXX: MMAP */
/* set known header fields for the log file */
strcpy(init_core->log_hdr_p->version_string, DARSHAN_LOG_VERSION);
......@@ -1562,29 +1560,21 @@ static void darshan_core_cleanup(struct darshan_core_runtime* core)
void darshan_core_register_module(
darshan_module_id mod_id,
struct darshan_module_funcs *funcs,
int *inout_mod_size,
void **mod_buf,
int *mod_buf_size,
int *my_rank,
int *sys_mem_alignment)
{
int ret;
int tmpval;
struct darshan_core_module* mod;
char *mod_mem_str = NULL;
int mod_mem_req = *inout_mod_size;
int mod_mem_avail;
*mod_buf_size = 0;
*mod_buf = NULL;
*inout_mod_size = 0;
if(!darshan_core || (mod_id >= DARSHAN_MAX_MODS))
return;
if(sys_mem_alignment)
*sys_mem_alignment = darshan_mem_alignment;
/* get the calling process's rank */
DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, my_rank);
/* see if this module is already registered */
DARSHAN_CORE_LOCK();
if(darshan_core->mod_array[mod_id])
{
......@@ -1593,13 +1583,20 @@ void darshan_core_register_module(
return;
}
/* XXX MMAP: how do we assign size and address */
*mod_buf = darshan_core->log_mod_p;
*mod_buf_size = DARSHAN_MOD_MEM_MAX;
/* assign a buffer from Darshan's contiguous module memory range for
* this module to use for storing record data
*/
mod_mem_avail = DARSHAN_MOD_MEM_MAX - darshan_core->mod_mem_used;
if(mod_mem_avail >= mod_mem_req)
*inout_mod_size = mod_mem_req;
else
*inout_mod_size = mod_mem_avail;
*mod_buf = darshan_core->log_mod_p + darshan_core->mod_mem_used;
darshan_core->mod_mem_used += *inout_mod_size;
darshan_core->log_hdr_p->mod_map[mod_id].off =
((char *)darshan_core->log_mod_p - (char *)darshan_core->log_hdr_p);
((char *)*mod_buf - (char *)darshan_core->log_hdr_p);
/* this module has not been registered yet, allocate and initialize it */
mod = malloc(sizeof(*mod));
if(!mod)
{
......@@ -1607,16 +1604,19 @@ void darshan_core_register_module(
return;
}
memset(mod, 0, sizeof(*mod));
mod->id = mod_id;
mod->mod_funcs = *funcs;
mod->mem_avail = *inout_mod_size;
/* register module with darshan */
darshan_core->mod_array[mod_id] = mod;
/* get the calling process's rank */
DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, my_rank);
DARSHAN_CORE_UNLOCK();
/* set the memory alignment and calling process's rank, if desired */
if(sys_mem_alignment)
*sys_mem_alignment = darshan_mem_alignment;
if(my_rank)
DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, my_rank);
return;
}
......@@ -1645,60 +1645,78 @@ void darshan_core_unregister_module(
return;
}
/* TODO: maybe a return code to distinguish between id 0 and a failure */
void darshan_core_register_record(
void darshan_core_lookup_record(
void *name,
int name_len,
int rec_size,
darshan_record_id *rec_id)
{
darshan_record_id tmp_rec_id;
/* TODO: how do we handle potentially non-ascii record names? */
/* hash the input name to get a unique id for this record */
tmp_rec_id = darshan_hash(name, name_len, 0);
*rec_id = tmp_rec_id;
return;
}
int darshan_core_register_record(
darshan_record_id rec_id,
void *name,
darshan_module_id mod_id,
int printable_flag,
darshan_record_id *rec_id,
int rec_size,
int *file_alignment)
{
darshan_record_id tmp_rec_id;
struct darshan_core_record_ref *ref;
*rec_id = 0;
*file_alignment = 0;
int mod_oom = 0;
if(!darshan_core)
return;
return 0;
/* TODO: what do you do with printable flag? */
/* TODO: what about partial flag? */
DARSHAN_CORE_LOCK();
/* hash the input name to get a unique id for this record */
tmp_rec_id = darshan_hash(name, name_len, 0);
/* check to see if this module has enough space to store a new record */
if(darshan_core->mod_array[mod_id]->mem_avail < rec_size)
mod_oom = 1;
/* check to see if we've already stored the id->name mapping for this record */
DARSHAN_CORE_LOCK();
HASH_FIND(hlink, darshan_core->rec_hash, &tmp_rec_id, sizeof(darshan_record_id), ref);
HASH_FIND(hlink, darshan_core->rec_hash, &rec_id, sizeof(darshan_record_id), ref);
if(!ref && !mod_oom)
{
/* no mapping already exists, but this module has memory available for
* storing the record being registered, so we create a new id->name
* mapping to correspond to the record
*/
darshan_add_record_hashref(darshan_core, name, rec_id, &ref);
}
if(!ref)
{
/* record not found -- add it to the hash if this module has not already used
* all of its memory
/* if there still is no mapping for this record, either the
* module is out of memory or there is no more memory available for
* id->name mappings. just back out and indicate the record was
* not registered
*/
darshan_add_record_hashref(darshan_core, name, tmp_rec_id, &ref);
if(!ref)
{
/* just give up and return if adding this record failed */
DARSHAN_CORE_UNLOCK();
return;
}
if(mod_oom)
DARSHAN_MOD_FLAG_SET(darshan_core->log_hdr_p->partial_flag, mod_id);
DARSHAN_CORE_UNLOCK();
return 0;
}
if(!DARSHAN_MOD_FLAG_ISSET(ref->mod_flags, mod_id))
{
DARSHAN_MOD_FLAG_SET(ref->mod_flags, mod_id);
darshan_core->log_hdr_p->mod_map[mod_id].len += rec_size;
darshan_core->mod_array[mod_id]->mem_avail -= rec_size;
}
DARSHAN_CORE_UNLOCK();
if(file_alignment)
darshan_block_size_from_path(name, file_alignment);
*rec_id = tmp_rec_id;
return;
return 1;
}
/* TODO: test */
......
......@@ -173,7 +173,6 @@ struct posix_runtime
{
struct posix_file_runtime* file_runtime_array;
struct darshan_posix_file* file_record_array;
int file_array_size;
int file_array_ndx;
struct posix_file_runtime* file_hash;
struct posix_file_runtime_ref* fd_hash;
......@@ -1625,22 +1624,26 @@ static void posix_runtime_initialize()
};
void *psx_buf;
int psx_buf_size;
int file_array_size;
/* don't do anything if already initialized or instrumenation is disabled */
if(posix_runtime || instrumentation_disabled)
return;
/* try and store the default number of records for this module */
psx_buf_size = DARSHAN_DEF_MOD_REC_COUNT * sizeof(struct darshan_posix_file);
/* register the posix module with darshan core */
darshan_core_register_module(
DARSHAN_POSIX_MOD,
&posix_mod_fns,
&psx_buf,
&psx_buf_size,
&psx_buf,
&my_rank,
&darshan_mem_alignment);
/* return if no memory assigned by darshan-core */
if(psx_buf_size == 0)
/* return if darshan-core does not provide enough module memory */
if(psx_buf_size < sizeof(struct darshan_posix_file))
return;
posix_runtime = malloc(sizeof(*posix_runtime));
......@@ -1650,22 +1653,26 @@ static void posix_runtime_initialize()
/* set maximum number of file records according to max memory limit */
/* NOTE: maximum number of records is based on the size of a posix file record */
posix_runtime->file_array_size = psx_buf_size / sizeof(struct darshan_posix_file);
file_array_size = psx_buf_size / sizeof(struct darshan_posix_file);
posix_runtime->file_array_ndx = 0;
/* store pointer to POSIX record buffer given by darshan-core */
posix_runtime->file_record_array = (struct darshan_posix_file *)psx_buf;
/* allocate array of runtime file records */
posix_runtime->file_runtime_array = malloc(posix_runtime->file_array_size *
posix_runtime->file_runtime_array = malloc(file_array_size *
sizeof(struct posix_file_runtime));
if(!posix_runtime->file_runtime_array)
{
posix_runtime->file_array_size = 0;
free(posix_runtime);
posix_runtime = NULL;
darshan_core_unregister_module(DARSHAN_POSIX_MOD);
return;
}
memset(posix_runtime->file_runtime_array, 0, posix_runtime->file_array_size *
memset(posix_runtime->file_runtime_array, 0, file_array_size *
sizeof(struct posix_file_runtime));
/* store pointer to POSIX record buffer given by darshan-core */
posix_runtime->file_record_array = (struct darshan_posix_file *)psx_buf;
memset(posix_runtime->file_record_array, 0, file_array_size *
sizeof(struct darshan_posix_file));
return;
}
......@@ -1674,9 +1681,11 @@ static void posix_runtime_initialize()
static struct posix_file_runtime* posix_file_by_name(const char *name)
{
struct posix_file_runtime *file = NULL;
struct darshan_posix_file *file_rec;
char *newname = NULL;
darshan_record_id file_id;
int file_alignment;
int ret;
if(!posix_runtime || instrumentation_disabled)
return(NULL);
......@@ -1685,50 +1694,39 @@ static struct posix_file_runtime* posix_file_by_name(const char *name)
if(!newname)
newname = (char*)name;
/* get a unique id for this file from darshan core */
darshan_core_register_record(
/* lookup the unique id for this file */
darshan_core_lookup_record(
(void*)newname,
strlen(newname),
sizeof(struct darshan_posix_file),
DARSHAN_POSIX_MOD,
1,
&file_id,
&file_alignment);
/* the file record id is set to 0 if no memory is available for tracking
* new records -- just fall through and ignore this record
*/
if(file_id == 0)
{
if(newname != name)
free(newname);
return(NULL);
}
&file_id);
/* search the hash table for this file record, and return if found */
HASH_FIND(hlink, posix_runtime->file_hash, &file_id, sizeof(darshan_record_id), file);
if(file)
if(!file)
{
if(newname != name)
free(newname);
return(file);
/* register the record with the darshan core component */
ret = darshan_core_register_record(file_id, (void *)newname, DARSHAN_POSIX_MOD,
sizeof(struct darshan_posix_file), &file_alignment);
if(ret == 1)
{
/* register was successful */
file = &(posix_runtime->file_runtime_array[posix_runtime->file_array_ndx]);
file->file_record =
&(posix_runtime->file_record_array[posix_runtime->file_array_ndx]);
file_rec = file->file_record;
file_rec->base_rec.id = file_id;
file_rec->base_rec.rank = my_rank;
file_rec->counters[POSIX_MEM_ALIGNMENT] = darshan_mem_alignment;
file_rec->counters[POSIX_FILE_ALIGNMENT] = file_alignment;
/* add new record to file hash table */
HASH_ADD(hlink, posix_runtime->file_hash, file_record->base_rec.id,
sizeof(darshan_record_id), file);
posix_runtime->file_array_ndx++;
}
}
/* TODO: what happens when there are no more records? */
/* no existing record, assign a new file record from the global array */
file = &(posix_runtime->file_runtime_array[posix_runtime->file_array_ndx]);
file->file_record = &(posix_runtime->file_record_array[posix_runtime->file_array_ndx]);
file->file_record->base_rec.id = file_id;
file->file_record->base_rec.rank = my_rank;
file->file_record->counters[POSIX_MEM_ALIGNMENT] = darshan_mem_alignment;
file->file_record->counters[POSIX_FILE_ALIGNMENT] = file_alignment;
/* add new record to file hash table */
HASH_ADD(hlink, posix_runtime->file_hash, file_record->base_rec.id,
sizeof(darshan_record_id), file);
posix_runtime->file_array_ndx++;
if(newname != name)
free(newname);
return(file);
......@@ -2364,7 +2362,6 @@ static void posix_shutdown()
HASH_CLEAR(hlink, posix_runtime->file_hash); /* these entries are freed all at once below */
free(posix_runtime->file_runtime_array);
/* XXX: MMAP free(posix_runtime->file_record_array); */
free(posix_runtime);
posix_runtime = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment