Commit 0da31a58 authored by Shane Snyder's avatar Shane Snyder
Browse files

initial darshan core shutdown logic

-also, darshan core uses utlist to keep track of modules
parent 40c8ed2e
...@@ -29,7 +29,7 @@ struct darshan_core_module ...@@ -29,7 +29,7 @@ struct darshan_core_module
{ {
char name[DARSHAN_MOD_NAME_LEN+1]; char name[DARSHAN_MOD_NAME_LEN+1];
struct darshan_module_funcs mod_funcs; struct darshan_module_funcs mod_funcs;
struct darshan_core_module *next_mod; struct darshan_core_module *next;
}; };
/* in memory structure to keep up with job level data */ /* in memory structure to keep up with job level data */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <mpi.h> #include <mpi.h>
#include "darshan-core.h" #include "darshan-core.h"
#include "utlist.h"
extern char* __progname_full; extern char* __progname_full;
...@@ -26,12 +27,21 @@ static void darshan_core_initialize(int *argc, char ***argv); ...@@ -26,12 +27,21 @@ static void darshan_core_initialize(int *argc, char ***argv);
static void darshan_core_shutdown(void); static void darshan_core_shutdown(void);
/* internal variables */ /* internal variables */
static struct darshan_core_job_runtime *darshan_global_job = NULL; static struct darshan_core_job_runtime *darshan_core_job = NULL;
static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER;
#define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex) #define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex)
#define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex) #define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex)
#define DARSHAN_MOD_REGISTER(__mod) \
LL_PREPEND(darshan_core_job->mod_list_head, __mod)
#define DARSHAN_MOD_SEARCH(__mod, __tmp) \
LL_SEARCH(darshan_core_job->mod_list_head, __mod, __tmp, mod_cmp)
#define DARSHAN_MOD_ITER(__mod, __tmp) \
LL_FOREACH_SAFE(darshan_core_job->mod_list_head, __mod, __tmp)
#define DARSHAN_MOD_DELETE(__mod) \
LL_DELETE(darshan_core_job->mod_list_head, __mod)
/* intercept MPI initialize and finalize to initialize darshan */ /* intercept MPI initialize and finalize to initialize darshan */
int MPI_Init(int *argc, char ***argv) int MPI_Init(int *argc, char ***argv)
{ {
...@@ -53,7 +63,7 @@ int MPI_Init_thread(int *argc, char ***argv, int required, int *provided) ...@@ -53,7 +63,7 @@ int MPI_Init_thread(int *argc, char ***argv, int required, int *provided)
int ret; int ret;
ret = DARSHAN_MPI_CALL(PMPI_Init_thread)(argc, argv, required, provided); ret = DARSHAN_MPI_CALL(PMPI_Init_thread)(argc, argv, required, provided);
if (ret != MPI_SUCCESS) if(ret != MPI_SUCCESS)
{ {
return(ret); return(ret);
} }
...@@ -73,6 +83,8 @@ int MPI_Finalize(void) ...@@ -73,6 +83,8 @@ int MPI_Finalize(void)
return(ret); return(ret);
} }
/* *********************************** */
static void darshan_core_initialize(int *argc, char ***argv) static void darshan_core_initialize(int *argc, char ***argv)
{ {
int i; int i;
...@@ -90,40 +102,39 @@ static void darshan_core_initialize(int *argc, char ***argv) ...@@ -90,40 +102,39 @@ static void darshan_core_initialize(int *argc, char ***argv)
if(getenv("DARSHAN_INTERNAL_TIMING")) if(getenv("DARSHAN_INTERNAL_TIMING"))
internal_timing_flag = 1; internal_timing_flag = 1;
if (internal_timing_flag) if(internal_timing_flag)
init_start = DARSHAN_MPI_CALL(PMPI_Wtime)(); init_start = DARSHAN_MPI_CALL(PMPI_Wtime)();
/* setup darshan runtime if darshan is enabled and hasn't been initialized already */ /* setup darshan runtime if darshan is enabled and hasn't been initialized already */
if (!getenv("DARSHAN_DISABLE") && !darshan_global_job) if(!getenv("DARSHAN_DISABLE") && !darshan_core_job)
{ {
/* allocate structure to track darshan_global_job information */ /* allocate structure to track darshan_core_job information */
darshan_global_job = malloc(sizeof(*darshan_global_job)); darshan_core_job = malloc(sizeof(*darshan_core_job));
if (darshan_global_job) if(darshan_core_job)
{ {
memset(darshan_global_job, 0, sizeof(*darshan_global_job)); memset(darshan_core_job, 0, sizeof(*darshan_core_job));
if (getenv("DARSHAN_DISABLE_TIMING")) if(getenv("DARSHAN_DISABLE_TIMING"))
{ {
darshan_global_job->flags |= CP_FLAG_NOTIMING; darshan_core_job->flags |= CP_FLAG_NOTIMING;
} }
strcpy(darshan_global_job->log_job.version_string, CP_VERSION); strcpy(darshan_core_job->log_job.version_string, CP_VERSION);
darshan_global_job->log_job.magic_nr = CP_MAGIC_NR; darshan_core_job->log_job.magic_nr = CP_MAGIC_NR;
darshan_global_job->log_job.uid = getuid(); darshan_core_job->log_job.uid = getuid();
darshan_global_job->log_job.start_time = time(NULL); darshan_core_job->log_job.start_time = time(NULL);
darshan_global_job->log_job.nprocs = nprocs; darshan_core_job->log_job.nprocs = nprocs;
darshan_global_job->wtime_offset = DARSHAN_MPI_CALL(PMPI_Wtime)(); darshan_core_job->wtime_offset = DARSHAN_MPI_CALL(PMPI_Wtime)();
darshan_global_job->mod_list_head = NULL;
/* record exe and arguments */ /* record exe and arguments */
for(i=0; i<(*argc); i++) for(i=0; i<(*argc); i++)
{ {
chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe);
strncat(darshan_global_job->exe, *(argv[i]), chars_left); strncat(darshan_core_job->exe, *(argv[i]), chars_left);
if(i < ((*argc)-1)) if(i < ((*argc)-1))
{ {
chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe);
strncat(darshan_global_job->exe, " ", chars_left); strncat(darshan_core_job->exe, " ", chars_left);
} }
} }
...@@ -132,17 +143,17 @@ static void darshan_core_initialize(int *argc, char ***argv) ...@@ -132,17 +143,17 @@ static void darshan_core_initialize(int *argc, char ***argv)
*/ */
if(argc == 0) if(argc == 0)
{ {
chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe);
strncat(darshan_global_job->exe, __progname_full, chars_left); strncat(darshan_core_job->exe, __progname_full, chars_left);
chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe);
strncat(darshan_global_job->exe, " <unknown args>", chars_left); strncat(darshan_core_job->exe, " <unknown args>", chars_left);
} }
if(chars_left == 0) if(chars_left == 0)
{ {
/* we ran out of room; mark that string was truncated */ /* we ran out of room; mark that string was truncated */
truncate_offset = CP_EXE_LEN - strlen(truncate_string); truncate_offset = CP_EXE_LEN - strlen(truncate_string);
sprintf(&darshan_global_job->exe[truncate_offset], "%s", sprintf(&darshan_core_job->exe[truncate_offset], "%s",
truncate_string); truncate_string);
} }
} }
...@@ -165,16 +176,31 @@ static void darshan_core_initialize(int *argc, char ***argv) ...@@ -165,16 +176,31 @@ static void darshan_core_initialize(int *argc, char ***argv)
static void darshan_core_shutdown() static void darshan_core_shutdown()
{ {
struct darshan_core_module *mod, *tmp;
int internal_timing_flag = 0; int internal_timing_flag = 0;
if(getenv("DARSHAN_INTERNAL_TIMING")) if(getenv("DARSHAN_INTERNAL_TIMING"))
internal_timing_flag = 1; internal_timing_flag = 1;
printf("darshan SHUTDOWN\n"); /* TODO: coordinate shutdown accross all registered modules */
DARSHAN_MOD_ITER(mod, tmp)
{
printf("Shutting down %s module\n", mod->name);
DARSHAN_MOD_DELETE(mod);
free(mod);
};
free(darshan_core_job);
return; return;
} }
static int mod_cmp(struct darshan_core_module* a, struct darshan_core_module* b)
{
return strcmp(a->name, b->name);
}
/* ********************************************************* */ /* ********************************************************* */
void darshan_core_register_module( void darshan_core_register_module(
...@@ -182,44 +208,46 @@ void darshan_core_register_module( ...@@ -182,44 +208,46 @@ void darshan_core_register_module(
struct darshan_module_funcs *funcs, struct darshan_module_funcs *funcs,
int *runtime_mem_limit) int *runtime_mem_limit)
{ {
struct darshan_core_module *tmp; struct darshan_core_module tmp;
struct darshan_core_module *new_mod; struct darshan_core_module* mod;
*runtime_mem_limit = 0; *runtime_mem_limit = 0;
if (!darshan_global_job) if(!darshan_core_job)
return; return;
DARSHAN_LOCK(); DARSHAN_LOCK();
tmp = darshan_global_job->mod_list_head;
while(tmp) /* see if this module is already registered */
strncpy(tmp.name, name, DARSHAN_MOD_NAME_LEN);
DARSHAN_MOD_SEARCH(mod, &tmp);
if(mod)
{ {
/* silently return if this module is already registered */ /* if module is already registered, update module_funcs and return */
if (strcmp(tmp->name, name) == 0) /* NOTE: we do not recalculate memory limit here, just set to 0 */
{ mod->mod_funcs = *funcs;
DARSHAN_UNLOCK();
return; DARSHAN_UNLOCK();
} return;
tmp = tmp->next_mod;
} }
/* allocate new module and add to the head of the linked list of darshan modules */ /* this module has not been registered yet, allocate and register it */
new_mod = malloc(sizeof(*new_mod)); mod = malloc(sizeof(*mod));
if (!new_mod) if(!mod)
{ {
DARSHAN_UNLOCK(); DARSHAN_UNLOCK();
return; return;
} }
memset(mod, 0, sizeof(*mod));
memset(new_mod, 0, sizeof(*new_mod)); strncpy(mod->name, name, DARSHAN_MOD_NAME_LEN);
strncpy(new_mod->name, name, DARSHAN_MOD_NAME_LEN); mod->mod_funcs = *funcs;
new_mod->mod_funcs = *funcs; DARSHAN_MOD_REGISTER(mod);
new_mod->next_mod = darshan_global_job->mod_list_head;
darshan_global_job->mod_list_head = new_mod;
DARSHAN_UNLOCK();
/* TODO: something smarter than just 2 MiB per module */ /* TODO: something smarter than just 2 MiB per module */
*runtime_mem_limit = 2 * 1024 * 1024; *runtime_mem_limit = 2 * 1024 * 1024;
DARSHAN_UNLOCK();
return; return;
} }
...@@ -231,7 +259,7 @@ void darshan_core_lookup_id( ...@@ -231,7 +259,7 @@ void darshan_core_lookup_id(
{ {
darshan_file_id tmp_id; darshan_file_id tmp_id;
if (!darshan_global_job) if(!darshan_core_job)
return; return;
/* TODO: what do you do with printable flag? */ /* TODO: what do you do with printable flag? */
...@@ -247,7 +275,7 @@ void darshan_core_lookup_id( ...@@ -247,7 +275,7 @@ void darshan_core_lookup_id(
double darshan_core_wtime() double darshan_core_wtime()
{ {
if(!darshan_global_job || darshan_global_job->flags & CP_FLAG_NOTIMING) if(!darshan_core_job || darshan_core_job->flags & CP_FLAG_NOTIMING)
{ {
return(0); return(0);
} }
......
...@@ -360,6 +360,36 @@ static void posix_runtime_initialize() ...@@ -360,6 +360,36 @@ static void posix_runtime_initialize()
if(posix_runtime) if(posix_runtime)
return; return;
/* register the posix module with darshan core */
darshan_core_register_module(
POSIX_MOD_NAME,
&posix_mod_fns,
&mem_limit);
/* return if no memory assigned by darshan core */
if(mem_limit == 0)
return;
posix_runtime = malloc(sizeof(*posix_runtime));
if(!posix_runtime)
return;
memset(posix_runtime, 0, sizeof(*posix_runtime));
/* 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 = mem_limit / sizeof(struct darshan_posix_file);
/* allocate array of runtime file records */
posix_runtime->file_array = malloc(sizeof(struct posix_runtime_file) *
posix_runtime->file_array_size);
if(!posix_runtime->file_array)
{
posix_runtime->file_array_size = 0;
return;
}
memset(posix_runtime->file_array, 0, sizeof(struct posix_runtime_file) *
posix_runtime->file_array_size);
#if 0 #if 0
/* set the memory alignment according to config or environment variables */ /* set the memory alignment according to config or environment variables */
#if (__CP_MEM_ALIGNMENT < 1) #if (__CP_MEM_ALIGNMENT < 1)
...@@ -387,31 +417,11 @@ static void posix_runtime_initialize() ...@@ -387,31 +417,11 @@ static void posix_runtime_initialize()
} }
#endif #endif
posix_runtime = malloc(sizeof(*posix_runtime)); return;
if(!posix_runtime) }
return;
memset(posix_runtime, 0, sizeof(*posix_runtime));
/* register the posix module with darshan core */
darshan_core_register_module(
POSIX_MOD_NAME,
&posix_mod_fns,
&mem_limit);
/* 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 = mem_limit / sizeof(struct darshan_posix_file);
/* allocate array of runtime file records */ static void posix_runtime_finalize()
posix_runtime->file_array = malloc(sizeof(struct posix_runtime_file) * {
posix_runtime->file_array_size);
if(!posix_runtime->file_array)
{
posix_runtime->file_array_size = 0;
return;
}
memset(posix_runtime->file_array, 0, sizeof(struct posix_runtime_file) *
posix_runtime->file_array_size);
return; return;
} }
...@@ -529,6 +539,9 @@ static void posix_prepare_for_shutdown() ...@@ -529,6 +539,9 @@ static void posix_prepare_for_shutdown()
static void posix_get_output_data(void **buffer, int size) static void posix_get_output_data(void **buffer, int size)
{ {
/* shutdown the posix runtime module */
posix_runtime_finalize();
return; return;
} }
......
This diff is collapsed.
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