Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Jakob Luettgau
darshan
Commits
5ecf4013
Commit
5ecf4013
authored
Apr 08, 2015
by
Shane Snyder
Browse files
more docs + "NULL" example module implementation
parent
233f1607
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
darshan-log-format.h
View file @
5ecf4013
/*
* (C) 2009 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_LOG_FORMAT_H
...
...
@@ -39,7 +40,8 @@ typedef uint64_t darshan_record_id;
#define DARSHAN_MAX_MODS 16
typedef
enum
{
DARSHAN_POSIX_MOD
=
0
,
DARSHAN_NULL_MOD
=
0
,
DARSHAN_POSIX_MOD
,
DARSHAN_MPIIO_MOD
,
DARSHAN_HDF5_MOD
,
DARSHAN_PNETCDF_MOD
,
...
...
@@ -47,6 +49,7 @@ typedef enum
static
char
*
const
darshan_module_names
[]
=
{
"NULL"
,
"POSIX"
,
"MPI-IO"
,
"HDF5"
,
...
...
darshan-mpiio-log-format.h
View file @
5ecf4013
/*
* (C) 2015 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_MPIIO_LOG_FORMAT_H
...
...
darshan-null-log-format.h
0 → 100644
View file @
5ecf4013
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_NULL_LOG_FORMAT_H
#define __DARSHAN_NULL_LOG_FORMAT_H
#include
"darshan-log-format.h"
/* integer counters for the "NULL" example module */
enum
darshan_null_indices
{
NULL_BARS
,
/* count of number of 'bar' function calls */
NULL_BAR_DAT
,
/* arbitrary data value set by last call to 'bar' */
NULL_NUM_INDICES
,
};
/* floating point counters for the "NULL" example module */
enum
darshan_null_f_indices
{
NULL_F_BAR_TIMESTAMP
,
/* timestamp of the first call to function 'bar' */
NULL_F_BAR_DURATION
,
/* timer indicating duration of last call to 'bar' */
NULL_F_NUM_INDICES
,
};
/* the darshan_null_record structure encompasses the high-level data/counters
* which would actually be logged to file by Darshan for the "NULL" example
* module. This example implementation logs the following data for each
* record:
* - a corresponding Darshan record identifier
* - the rank of the process responsible for the record
* - integer I/O counters (operation counts, I/O sizes, etc.)
* - floating point I/O counters (timestamps, cumulative timers, etc.)
*/
struct
darshan_null_record
{
darshan_record_id
f_id
;
int64_t
rank
;
int64_t
counters
[
NULL_NUM_INDICES
];
double
fcounters
[
NULL_F_NUM_INDICES
];
};
#endif
/* __DARSHAN_NULL_LOG_FORMAT_H */
darshan-runtime/Makefile.in
View file @
5ecf4013
all
:
lib/libdarshan.a
all
:
lib/libdarshan.a
lib/darshan-null.o
DESTDIR
=
srcdir
=
@srcdir@
...
...
@@ -19,7 +19,7 @@ DARSHAN_LOG_FORMAT = $(srcdir)/../darshan-log-format.h
DARSHAN_VERSION
=
@DARSHAN_VERSION@
ifndef
DISABLE_LDPRELOAD
all
:
lib/libdarshan.so
all
:
lib/libdarshan.so
lib/darshan-null.po
endif
VPATH
=
$(srcdir)
...
...
@@ -51,16 +51,22 @@ lib/darshan-common.o: lib/darshan-common.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-common.po
:
lib/darshan-common.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
$(CC)
$(CFLAGS_SHARED)
-c
$<
-o
$@
lib/darshan-
posix
.o
:
lib/darshan-
posix
.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-
null
.o
:
lib/darshan-
null
.c darshan.h $(DARSHAN_LOG_FORMAT)
$(srcdir)/../darshan-null-log-format.h
| lib
$(CC)
$(CFLAGS)
-c
$<
-o
$@
lib/darshan-
posix
.po
:
lib/darshan-
posix
.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-
null
.po
:
lib/darshan-
null
.c darshan.h $(DARSHAN_LOG_FORMAT)
$(srcdir)/../darshan-null-log-format.h
| lib
$(CC)
$(CFLAGS_SHARED)
-c
$<
-o
$@
lib/darshan-
mpiio
.o
:
lib/darshan-
mpiio
.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-
posix
.o
:
lib/darshan-
posix
.c darshan.h $(DARSHAN_LOG_FORMAT)
$(srcdir)/../darshan-posix-log-format.h
| lib
$(CC)
$(CFLAGS)
-c
$<
-o
$@
lib/darshan-mpiio.po
:
lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-posix.po
:
lib/darshan-posix.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
$(CC)
$(CFLAGS_SHARED)
-c
$<
-o
$@
lib/darshan-mpiio.o
:
lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC)
$(CFLAGS)
-c
$<
-o
$@
lib/darshan-mpiio.po
:
lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC)
$(CFLAGS_SHARED)
-c
$<
-o
$@
lib/lookup3.o
:
lib/lookup3.c
...
...
darshan-runtime/darshan.h
View file @
5ecf4013
...
...
@@ -34,38 +34,43 @@
#include
<dlfcn.h>
#include
<stdlib.h>
#define DARSHAN_FORWARD_DECL(
name,
ret,args) \
ret (*__real_ ##
name)
args = NULL
#define DARSHAN_FORWARD_DECL(
__func,__
ret,
__
args) \
__
ret (*__real_ ##
__func)__
args = NULL
#define DARSHAN_DECL(__
name) __name
#define DARSHAN_DECL(__
func) __func
#define DARSHAN_MPI_CALL(func) __real_ ## func
#define DARSHAN_MPI_CALL(
__
func) __real_ ##
__
func
#define MAP_OR_FAIL(func) \
if (!(__real_ ## func)) \
#define MAP_OR_FAIL(
__
func) \
if (!(__real_ ##
__
func)) \
{ \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
__real_ ##
__
func = dlsym(RTLD_NEXT, #
__
func); \
if(!(__real_ ##
__
func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #
__
func); \
exit(1); \
} \
}
#else
#define DARSHAN_FORWARD_DECL(name,ret,args) \
extern ret __real_ ## name args;
#define DARSHAN_FORWARD_DECL(
__
name,
__
ret,
__
args) \
extern
__
ret __real_ ##
__
name
__
args;
#define DARSHAN_DECL(__name) __wrap_ ## __name
#define DARSHAN_MPI_CALL(func) func
#define DARSHAN_MPI_CALL(
__
func)
__
func
#define MAP_OR_FAIL(func)
#define MAP_OR_FAIL(
__
func)
#endif
/* macros for manipulating module's counter variables */
/* NOTE: */
/* macros for manipulating a module's counter variables */
/* NOTE: These macros assume a module's record stores integer
* and floating point counters in arrays, named counters and
* fcounters, respectively. __rec_p is the a pointer to the
* data record, __counter is the counter in question, and
* __value is the corresponding data value.
*/
#define DARSHAN_COUNTER_SET(__rec_p, __counter, __value) do{ \
(__rec_p)->counters[__counter] = __value; \
} while(0)
...
...
@@ -102,6 +107,11 @@
(__rec_p)->counters[__counter] = __value; \
} while(0)
/* NOTE: This macro is for storing histogram counters with 10
* distinct buckets. For an example of how it is used, consult
* the POSIX module implementation, which stores histograms of
* access sizes for POSIX I/O functions.
*/
#define DARSHAN_BUCKET_INC(__rec_p, __counter_base, __value) do {\
if(__value < 101) \
(__rec_p)->counters[__counter_base] += 1; \
...
...
@@ -128,10 +138,10 @@
/* module developers provide the following functions to darshan-core */
struct
darshan_module_funcs
{
/*
disable futher instrumentation within a module
*/
void
(
*
disable_instrumentatio
n
)(
void
);
/*
perform any necessary pre-shutdown steps
*/
void
(
*
begin_shutdow
n
)(
void
);
/* perform any necessary steps prior to reducing */
void
(
*
prepare_for
_reduction
)(
void
(
*
setup
_reduction
)(
darshan_record_id
*
shared_recs
,
/* input list of shared records */
int
*
shared_rec_count
,
/* in/out shared record count */
void
**
send_buf
,
/* send buffer for shared file reduction */
...
...
darshan-runtime/lib/darshan-core.c
View file @
5ecf4013
...
...
@@ -258,14 +258,15 @@ void darshan_core_shutdown()
darshan_core
=
NULL
;
/* we also need to set which modules were registered on this process and
* disable tracing within those modules while we shutdown
* call into those modules and give them a chance to perform any necessary
* pre-shutdown steps.
*/
for
(
i
=
0
;
i
<
DARSHAN_MAX_MODS
;
i
++
)
{
if
(
final_core
->
mod_array
[
i
])
{
local_mod_use
[
i
]
=
1
;
final_core
->
mod_array
[
i
]
->
mod_funcs
.
disable_instrumentatio
n
();
final_core
->
mod_array
[
i
]
->
mod_funcs
.
begin_shutdow
n
();
}
}
DARSHAN_CORE_UNLOCK
();
...
...
@@ -492,10 +493,10 @@ void darshan_core_shutdown()
}
/* if there are globally shared files, do a shared file reduction */
if
(
shared_rec_count
&&
this_mod
->
mod_funcs
.
prepare_for
_reduction
&&
if
(
shared_rec_count
&&
this_mod
->
mod_funcs
.
setup
_reduction
&&
this_mod
->
mod_funcs
.
record_reduction_op
)
{
this_mod
->
mod_funcs
.
prepare_for
_reduction
(
mod_shared_recs
,
&
shared_rec_count
,
this_mod
->
mod_funcs
.
setup
_reduction
(
mod_shared_recs
,
&
shared_rec_count
,
&
red_send_buf
,
&
red_recv_buf
,
&
rec_sz
);
if
(
shared_rec_count
)
...
...
darshan-runtime/lib/darshan-mpiio.c
View file @
5ecf4013
...
...
@@ -114,7 +114,7 @@ static int my_rank = -1;
#define MPIIO_UNLOCK() pthread_mutex_unlock(&mpiio_runtime_mutex)
static
void
mpiio_runtime_initialize
(
void
);
static
void
mpiio_
disable_instrumentatio
n
(
void
);
static
void
mpiio_
begin_shutdow
n
(
void
);
static
void
mpiio_shutdown
(
void
);
static
void
mpiio_get_output_data
(
void
**
buffer
,
...
...
@@ -123,7 +123,7 @@ static struct mpiio_file_runtime* mpiio_file_by_name_setfh(const char* name, MPI
static
struct
mpiio_file_runtime
*
mpiio_file_by_name
(
const
char
*
name
);
static
void
mpiio_record_reduction_op
(
void
*
infile_v
,
void
*
inoutfile_v
,
int
*
len
,
MPI_Datatype
*
datatype
);
static
void
mpiio_
prepare_for
_reduction
(
darshan_record_id
*
shared_recs
,
static
void
mpiio_
setup
_reduction
(
darshan_record_id
*
shared_recs
,
int
*
shared_rec_count
,
void
**
send_buf
,
void
**
recv_buf
,
int
*
rec_size
);
static
int
mpiio_file_compare
(
const
void
*
a
,
const
void
*
b
);
...
...
@@ -192,8 +192,8 @@ static void mpiio_runtime_initialize()
int
mem_limit
;
struct
darshan_module_funcs
mpiio_mod_fns
=
{
.
disable_instrumentation
=
&
mpiio_disable_instrumentatio
n
,
.
prepare_for
_reduction
=
&
mpiio_
prepare_for
_reduction
,
.
begin_shutdown
=
&
mpiio_begin_shutdow
n
,
.
setup
_reduction
=
&
mpiio_
setup
_reduction
,
.
record_reduction_op
=
&
mpiio_record_reduction_op
,
.
get_output_data
=
&
mpiio_get_output_data
,
.
shutdown
=
&
mpiio_shutdown
...
...
@@ -245,7 +245,7 @@ static void mpiio_runtime_initialize()
return
;
}
static
void
mpiio_
disable_instrumentatio
n
()
static
void
mpiio_
begin_shutdow
n
()
{
assert
(
mpiio_runtime
);
...
...
@@ -444,7 +444,7 @@ static void mpiio_record_reduction_op(
return
;
}
static
void
mpiio_
prepare_for
_reduction
(
static
void
mpiio_
setup
_reduction
(
darshan_record_id
*
shared_recs
,
int
*
shared_rec_count
,
void
**
send_buf
,
...
...
darshan-runtime/lib/darshan-null.c
0 → 100644
View file @
5ecf4013
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#include
"darshan-runtime-config.h"
#include
<stdio.h>
#include
<unistd.h>
#include
<stdlib.h>
#include
<pthread.h>
#include
<assert.h>
#include
"uthash.h"
#include
"darshan.h"
#include
"darshan-null-log-format.h"
/* The "NULL" module is an example instrumentation module implementation provided
* with Darshan, primarily to indicate how arbitrary modules may be integrated
* into Darshan. In particular, this module demonstrates how to develop wrapper
* functions for intercepting functions of interest, how to best manage necessary
* runtime data structures, and how to coordinate with the darshan-core component,
* among other things. This module is not linked with the darshan-runtime library;
* it is intended mainly to serve as a basic stubbed out module implementation
* that may be reused and expanded on by developers adding new instrumentation modules.
*/
/* TODO: this probably shouldn't be here -- LD_PRELOADing POSIX wrappers will cause MPI linker dependency */
#ifdef DARSHAN_PRELOAD
extern
double
(
*
__real_PMPI_Comm_rank
)(
MPI_Comm
comm
,
int
*
rank
);
#endif
/* The DARSHAN_FORWARD_DECL macro (defined in darshan.h) is used to provide forward
* declarations for wrapped funcions, regardless if Darshan is used with statically
* or dynamically linked executables.
*/
DARSHAN_FORWARD_DECL
(
foo
,
int
,
(
const
char
*
name
,
int
arg1
,
int
arg2
));
/* The null_record_runtime structure maintains necessary runtime metadata
* for a "NULL" module data record (darshan_null_record structure, defined
* in darshan-null-log-format.h). This metadata assists with the instrumenting
* of specific statistics in the file record.
*
* RATIONALE: In general, a module may need to track some stateful, volatile
* information regarding specific I/O statistics to aid in the instrumentation
* process. However, this information should not be stored in the darshan_null_record
* struct because we don't want it to appear in the final darshan log file.
* We therefore associate a null_record_runtime structure with each darshan_null_record
* structure in order to track this information.
*
* NOTE: The null_record_runtime struct contains a pointer to a darshan_null_record
* struct (see the *record_p member) rather than simply embedding an entire
* darshan_null_record struct. This is done so that all of the darshan_null_record
* structs can be kept contiguous in memory as a single array to simplify
* reduction, compression, and storage.
*/
struct
null_record_runtime
{
/* Darshan record for the "NULL" example module */
struct
darshan_null_record
*
record_p
;
/* ... other runtime data ... */
/* hash table link for this record */
/* NOTE: it is entirely up to the module developer how to persist module
* records in memory as the instrumented application runs. These records
* could just as easily be stored in an array or linked list. That said,
* the data structure selection should be mindful of the resulting memory
* footprint and search time complexity to attempt minimize Darshan overheads.
* hash table and linked list implementations are available in uthash.h and
* utlist.h, respectively.
*/
UT_hash_handle
hlink
;
};
/* The null_runtime structure simply encapsulates global data structures needed
* by the module for instrumenting functions of interest and providing the output
* I/O data for this module to the darshan-core component at shutdown time.
*/
struct
null_runtime
{
/* runtime_record_array is the array of runtime records for the "NULL" module. */
struct
null_record_runtime
*
runtime_record_array
;
/* record_array is the array of high-level Darshan records for the "NULL" module,
* each corresponding to the the runtime record structure stored at the same array
* index in runtime_record_array.
*/
struct
darshan_null_record
*
record_array
;
/* file_array_size is the maximum amount of records that can be stored in
* record_array (and consequentially, runtime_record_array).
*/
int
rec_array_size
;
/* file_array_ndx is the current index into both runtime_record_array and
* record_array.
*/
int
rec_array_ndx
;
/* record_hash is a pointer to a hash table of null_record_runtime structures
* currently maintained by the "NULL" module.
*/
struct
null_record_runtime
*
record_hash
;
};
/* null_runtime is the global data structure encapsulating "NULL" module state */
static
struct
null_runtime
*
null_runtime
=
NULL
;
/* The null_runtime_mutex is a lock used when updating the null_runtime global
* structure (or any other global data structures). This is necessary to avoid race
* conditions as multiple threads execute function wrappers and update module state.
* NOTE: Recursive mutexes are used in case functions wrapped by this module call
* other wrapped functions that would result in deadlock, otherwise. This mechanism
* may not be necessary for all instrumentation modules.
*/
static
pthread_mutex_t
null_runtime_mutex
=
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
;
/* the instrumentation_disabled flag is used to toggle wrapper functions on/off */
static
int
instrumentation_disabled
=
0
;
/* my_rank indicates the MPI rank of this process */
static
int
my_rank
=
-
1
;
/* internal helper functions for the "NULL" module */
static
void
null_runtime_initialize
(
void
);
static
struct
null_record_runtime
*
null_record_by_name
(
const
char
*
name
);
/* forward declaration for module functions needed to interface with darshan-core */
static
void
null_begin_shutdown
(
void
);
static
void
null_get_output_data
(
void
**
buffer
,
int
*
size
);
static
void
null_shutdown
(
void
);
/* macros for obtaining/releasing the "NULL" module lock */
#define NULL_LOCK() pthread_mutex_lock(&null_runtime_mutex)
#define NULL_UNLOCK() pthread_mutex_unlock(&null_runtime_mutex)
/* macro for instrumenting the "NULL" module's foo function */
/* NOTE: this macro makes use of the DARSHAN_COUNTER_* macros defined
* and documented in darshan.h.
*/
#define NULL_RECORD_FOO(__ret, __name, __dat, __tm1, __tm2) do{ \
struct null_record_runtime* rec; \
double elapsed = __tm2 - __tm1; \
/* if foo returns error (return code < 0), don't instrument anything */
\
if(__ret < 0) break; \
/* use '__name' to lookup a corresponding "NULL" record */
\
rec = null_record_by_name(__name); \
if(!rec) break; \
/* increment counter indicating number of calls to 'bar' */
\
DARSHAN_COUNTER_INC(rec->record_p, NULL_BARS, 1); \
/* store data value for most recent call to 'bar' */
\
DARSHAN_COUNTER_SET(rec->record_p, NULL_BAR_DAT, __dat); \
/* store timestamp of most recent call to 'bar' */
\
DARSHAN_COUNTER_F_SET(rec->record_p, NULL_F_BAR_TIMESTAMP, __tm1); \
/* store duration of most recent call to 'bar' */
\
DARSHAN_COUNTER_F_SET(rec->record_p, NULL_F_BAR_DURATION, elapsed); \
} while(0)
/**********************************************************
* Wrappers for "NULL" module functions of interest *
**********************************************************/
/* The DARSHAN_DECL macro provides the appropriate wrapper function names,
* depending on whether the Darshan library is statically or dynamically linked.
*/
int
DARSHAN_DECL
(
foo
)(
const
char
*
name
,
int
arg1
,
int
arg2
)
{
ssize_t
ret
;
double
tm1
,
tm2
;
/* The MAP_OR_FAIL macro attempts to obtain the address of the actual
* underlying foo function call (__real_foo), in the case of LD_PRELOADing
* the Darshan library. For statically linked executables, this macro is
* just a NOP.
*/
MAP_OR_FAIL
(
foo
);
/* In general, Darshan wrappers begin by calling the real version of the
* given wrapper function. Timers are used to record the duration of this
* operation. */
tm1
=
darshan_core_wtime
();
ret
=
__real_foo
(
name
,
arg1
,
arg2
);
tm2
=
darshan_core_wtime
();
NULL_LOCK
();
/* Before attempting to instrument I/O statistics for function foo, make
* sure the "NULL" module runtime environment has been initialized.
* NOTE: this runtime environment is initialized only once -- if the
* appropriate structures have already been initialized, this function simply
* returns.
*/
null_runtime_initialize
();
/* Call macro for instrumenting data for foo function calls. */
NULL_RECORD_FOO
(
ret
,
name
,
arg1
+
arg2
,
tm1
,
tm2
);
NULL_UNLOCK
();
return
(
ret
);
}
/**********************************************************
* Internal functions for manipulating POSIX module state *
**********************************************************/
/* Initialize internal POSIX module data structures and register with darshan-core. */
static
void
null_runtime_initialize
()
{
/* struct of function pointers for interfacing with darshan-core */
struct
darshan_module_funcs
null_mod_fns
=
{
.
begin_shutdown
=
&
null_begin_shutdown
,
.
setup_reduction
=
NULL
,
/* "NULL" module does not do reductions */
.
record_reduction_op
=
NULL
,
/* "NULL" module does not do reductions */
.
get_output_data
=
&
null_get_output_data
,
.
shutdown
=
&
null_shutdown
};
int
mem_limit
;
/* max. memory this module can consume, dictated by darshan-core */
/* don't do anything if already initialized or instrumenation is disabled */
if
(
null_runtime
||
instrumentation_disabled
)
return
;
/* register the "NULL" module with the darshan-core component */
darshan_core_register_module
(
DARSHAN_NULL_MOD
,
/* Darshan module identifier, defined in darshan-log-format.h */
&
null_mod_fns
,
&
mem_limit
,
NULL
);
/* return if no memory assigned by darshan-core */
if
(
mem_limit
==
0
)
return
;
/* initialize module's global state */
null_runtime
=
malloc
(
sizeof
(
*
null_runtime
));
if
(
!
null_runtime
)
return
;
memset
(
null_runtime
,
0
,
sizeof
(
*
null_runtime
));
/* Set the maximum number of data records this module may track, as indicated
* by mem_limit (set by darshan-core).
* NOTE: We interpret the maximum memory limit to be related to the maximum
* amount of data which may be written to log by a single process for a given
* module. We therefore use this maximum memory limit to determine how many
* darshan_null_record structures we can track per process.
*/
null_runtime
->
rec_array_size
=
mem_limit
/
sizeof
(
struct
darshan_null_record
);
null_runtime
->
rec_array_ndx
=
0
;
/* allocate both record arrays (runtime and high-level records) */
null_runtime
->
runtime_record_array
=
malloc
(
null_runtime
->
rec_array_size
*
sizeof
(
struct
null_record_runtime
));
null_runtime
->
record_array
=
malloc
(
null_runtime
->
rec_array_size
*
sizeof
(
struct
darshan_null_record
));
if
(
!
null_runtime
->
runtime_record_array
||
!
null_runtime
->
record_array
)
{
null_runtime
->
rec_array_size
=
0
;
return
;
}
memset
(
null_runtime
->
runtime_record_array
,
0
,
null_runtime
->
rec_array_size
*
sizeof
(
struct
null_record_runtime
));
memset
(
null_runtime
->
record_array
,
0
,
null_runtime
->
rec_array_size
*
sizeof
(
struct
darshan_null_record
));
/* TODO: we should move this out of here.. perhaps register_module returns rank? */
DARSHAN_MPI_CALL
(
PMPI_Comm_rank
)(
MPI_COMM_WORLD
,
&
my_rank
);
return
;
}
/* Search for and return a "NULL" module record corresponding to name parameter. */
static
struct
null_record_runtime
*
null_record_by_name
(
const
char
*
name
)
{
struct
null_record_runtime
*
rec
=
NULL
;
darshan_record_id
rec_id
;
/* Don't search for a record if the "NULL" module is not initialized or
* if instrumentation has been toggled off.
*/
if
(
!
null_runtime
||
instrumentation_disabled
)
return
(
NULL
);
/* get a unique record identifier for this record from darshan-core */
darshan_core_register_record
(
(
void
*
)
name
,
strlen
(
name
),
1
,
DARSHAN_NULL_MOD
,
&
rec_id
,
NULL
);
/* search the hash table for this file record, and return if found */
HASH_FIND
(
hlink
,
null_runtime
->
record_hash
,
&
rec_id
,
sizeof
(
darshan_record_id
),
rec
);
if
(
rec
)
{
return
(
rec
);
}
if
(
null_runtime
->
rec_array_ndx
<
null_runtime
->
rec_array_size
);
{
/* no existing record, assign a new one from the global array */
rec
=
&
(
null_runtime
->
runtime_record_array
[
null_runtime
->
rec_array_ndx
]);
rec
->
record_p
=
&
(
null_runtime
->
record_array
[
null_runtime
->
rec_array_ndx
]);
/* set the darshan record id and corresponding process rank for this record */
rec
->
record_p
->
f_id
=
rec_id
;
rec
->
record_p
->
rank
=
my_rank
;
/* add new record to file hash table */
HASH_ADD
(
hlink
,
null_runtime
->
record_hash
,
record_p
->
f_id
,
sizeof
(
darshan_record_id
),
rec
);
null_runtime
->
rec_array_ndx
++
;
}
return
(
rec
);
}
/******************************************************************************
* Functions exported by the "NULL" module for coordinating with darshan-core *
******************************************************************************/
/* Perform any necessary steps prior to shutting down for the "NULL" module. */
static
void
null_begin_shutdown
()
{
assert
(
null_runtime
);
NULL_LOCK
();
/* In general, we want to disable all wrappers while Darshan shuts down.
* This is to avoid race conditions and ensure data consistency, as
* executing wrappers could potentially modify module state while Darshan
* is in the process of shutting down.
*/
instrumentation_disabled
=
1
;
/* ... any other code which needs to be executed before beginning shutdown process ... */
NULL_UNLOCK
();