[Darshan-commits] [Darshan] branch, dev-modular, updated. 7496c279aeb8003a655ee581145ecec6b4d18ddc
Service Account
git at mcs.anl.gov
Wed Nov 12 16:01:45 CST 2014
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, dev-modular has been updated
via 7496c279aeb8003a655ee581145ecec6b4d18ddc (commit)
from 37d68c1ea108118df1dfd259e96b7c6d33f32110 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7496c279aeb8003a655ee581145ecec6b4d18ddc
Author: Shane Snyder <ssnyder at mcs.anl.gov>
Date: Wed Nov 12 15:57:35 2014 -0600
More updates to facilitate runtime core shutdown
-----------------------------------------------------------------------
Summary of changes:
darshan-runtime/darshan-core.h | 5 +-
darshan-runtime/darshan.h | 19 ++-
darshan-runtime/lib/darshan-core.c | 345 ++++++++++++------------
darshan-runtime/lib/darshan-posix.c | 1 +
darshan-runtime/utlist.h | 490 -----------------------------------
5 files changed, 194 insertions(+), 666 deletions(-)
delete mode 100644 darshan-runtime/utlist.h
Diff of changes:
diff --git a/darshan-runtime/darshan-core.h b/darshan-runtime/darshan-core.h
index c94ac9d..3729101 100644
--- a/darshan-runtime/darshan-core.h
+++ b/darshan-runtime/darshan-core.h
@@ -22,22 +22,21 @@
#define DARSHAN_MOD_NAME_LEN 31
/* flags to indicate properties of file records */
-#define CP_FLAG_CONDENSED 1<<0
#define CP_FLAG_NOTIMING 1<<1
struct darshan_core_module
{
+ darshan_module_id id;
char name[DARSHAN_MOD_NAME_LEN+1];
struct darshan_module_funcs mod_funcs;
- struct darshan_core_module *next;
};
/* in memory structure to keep up with job level data */
struct darshan_core_job_runtime
{
struct darshan_job log_job;
+ struct darshan_core_module* mod_array[DARSHAN_MAX_MODS];
char exe[CP_EXE_LEN+1];
- struct darshan_core_module *mod_list_head;
char comp_buf[CP_COMP_BUF_SIZE];
int flags;
double wtime_offset;
diff --git a/darshan-runtime/darshan.h b/darshan-runtime/darshan.h
index 34c0741..698616c 100644
--- a/darshan-runtime/darshan.h
+++ b/darshan-runtime/darshan.h
@@ -25,9 +25,25 @@
/* Environment variable to override __CP_MEM_ALIGNMENT */
#define CP_MEM_ALIGNMENT_OVERRIDE "DARSHAN_MEMALIGN"
-/* TODO these go where ? */
+/* TODO where do each of the following macros make most sense ? */
#define DARSHAN_MPI_CALL(func) func
+/* max length of module name string (not counting \0) */
+#define DARSHAN_MOD_NAME_LEN 31
+
+/* unique identifiers to distinguish between available darshan modules */
+/* NOTES: - valid ids range from [0...DARSHAN_MAX_MODS-1]
+ * - order of ids control module shutdown order (first module shuts down first)
+ */
+#define DARSHAN_MAX_MODS 16
+typedef enum
+{
+ DARSHAN_POSIX_MOD,
+ DARSHAN_MPIIO_MOD,
+ DARSHAN_HDF5_MOD,
+ DARSHAN_PNETCDF_MOD,
+} darshan_module_id;
+
typedef uint64_t darshan_file_id;
struct darshan_module_funcs
@@ -41,6 +57,7 @@ struct darshan_module_funcs
*********************************************/
void darshan_core_register_module(
+ darshan_module_id id,
char *name,
struct darshan_module_funcs *funcs,
int *runtime_mem_limit);
diff --git a/darshan-runtime/lib/darshan-core.c b/darshan-runtime/lib/darshan-core.c
index c20cee8..4076202 100644
--- a/darshan-runtime/lib/darshan-core.c
+++ b/darshan-runtime/lib/darshan-core.c
@@ -19,11 +19,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vfs.h>
-
#include <mpi.h>
#include "darshan-core.h"
-#include "utlist.h"
/* TODO is __progname_full needed here */
extern char* __progname;
@@ -36,19 +34,11 @@ static int my_rank = -1;
static void darshan_core_initialize(int *argc, char ***argv);
static void darshan_core_shutdown(void);
static void darshan_core_cleanup(struct darshan_core_job_runtime* job);
+static void darshan_get_logfile_name(char* logfile_name, int jobid, struct tm* start_tm);
#define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex)
#define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex)
-#define DARSHAN_MOD_REGISTER(__mod, __job) \
- LL_PREPEND(__job->mod_list_head, __mod)
-#define DARSHAN_MOD_SEARCH(__mod, __tmp, __job) \
- LL_SEARCH(__job->mod_list_head, __mod, __tmp, mod_cmp)
-#define DARSHAN_MOD_ITER(__mod, __tmp, __job) \
- LL_FOREACH_SAFE(__job->mod_list_head, __mod, __tmp)
-#define DARSHAN_MOD_DELETE(__mod, __job) \
- LL_DELETE(__job->mod_list_head, __mod)
-
/* intercept MPI initialize and finalize to manage darshan core runtime */
int MPI_Init(int *argc, char ***argv)
{
@@ -186,23 +176,17 @@ static void darshan_core_shutdown()
struct darshan_core_job_runtime* final_job;
struct darshan_core_module *mod, *tmp;
int internal_timing_flag = 0;
- int jobid;
- char* jobid_str;
char* envjobid;
- char* logpath;
+ char* jobid_str;
+ int jobid;
+ struct tm* start_tm;
+ time_t start_time_tmp;
int ret;
- int local_ret = 0;
- int all_ret = 0;
- uint64_t hlevel;
- char hname[HOST_NAME_MAX];
- uint64_t logmod;
- char* logpath_override = NULL;
-#ifdef __CP_LOG_ENV
- char env_check[256];
- char* env_tok;
-#endif
int64_t first_start_time;
int64_t last_end_time;
+ int local_mod_use[DARSHAN_MAX_MODS] = {0};
+ int global_mod_use_count[DARSHAN_MAX_MODS] = {0};
+ int i;
if(getenv("DARSHAN_INTERNAL_TIMING"))
internal_timing_flag = 1;
@@ -227,30 +211,16 @@ static void darshan_core_shutdown()
return;
}
- /* construct log file name */
+ /* set jobid and logfile name on rank 0 */
if(my_rank == 0)
{
- char cuser[L_cuserid] = {0};
- struct tm* my_tm;
- time_t start_time_tmp;
-
/* Use CP_JOBID_OVERRIDE for the env var or CP_JOBID */
envjobid = getenv(CP_JOBID_OVERRIDE);
- if (!envjobid)
+ if(!envjobid)
{
envjobid = CP_JOBID;
}
- /* Use CP_LOG_PATH_OVERRIDE for the value or __CP_LOG_PATH */
- logpath = getenv(CP_LOG_PATH_OVERRIDE);
- if (!logpath)
- {
-#ifdef __CP_LOG_PATH
- logpath = __CP_LOG_PATH;
-#endif
- }
-
- /* find a job id */
jobid_str = getenv(envjobid);
if(jobid_str)
{
@@ -263,121 +233,15 @@ static void darshan_core_shutdown()
jobid = getpid();
}
- /* break out time into something human readable */
- start_time_tmp = final_job->log_job.start_time;
- my_tm = localtime(&start_time_tmp);
-
- /* get the username for this job. In order we will try each of the
- * following until one of them succeeds:
- *
- * - cuserid()
- * - getenv("LOGNAME")
- * - snprintf(..., geteuid());
- *
- * Note that we do not use getpwuid() because it generally will not
- * work in statically compiled binaries.
- */
-
-#ifndef DARSHAN_DISABLE_CUSERID
- cuserid(cuser);
-#endif
-
- /* if cuserid() didn't work, then check the environment */
- if (strcmp(cuser, "") == 0)
- {
- char* logname_string;
- logname_string = getenv("LOGNAME");
- if(logname_string)
- {
- strncpy(cuser, logname_string, (L_cuserid-1));
- }
-
- }
-
- /* if cuserid() and environment both fail, then fall back to uid */
- if (strcmp(cuser, "") == 0)
- {
- uid_t uid = geteuid();
- snprintf(cuser, sizeof(cuser), "%u", uid);
- }
-
- /* generate a random number to help differentiate the log */
- hlevel=DARSHAN_MPI_CALL(PMPI_Wtime)() * 1000000;
- (void) gethostname(hname, sizeof(hname));
- logmod = darshan_hash((void*)hname,strlen(hname),hlevel);
-
- /* see if darshan was configured using the --with-logpath-by-env
- * argument, which allows the user to specify an absolute path to
- * place logs via an env variable.
- */
-#ifdef __CP_LOG_ENV
- /* just silently skip if the environment variable list is too big */
- if(strlen(__CP_LOG_ENV) < 256)
- {
- /* copy env variable list to a temporary buffer */
- strcpy(env_check, __CP_LOG_ENV);
- /* tokenize the comma-separated list */
- env_tok = strtok(env_check, ",");
- if(env_tok)
- {
- do
- {
- /* check each env variable in order */
- logpath_override = getenv(env_tok);
- if(logpath_override)
- {
- /* stop as soon as we find a match */
- break;
- }
- }while((env_tok = strtok(NULL, ",")));
- }
- }
-#endif
+ /* add to darshan core job */
+ final_job->log_job.jobid = (int64_t)jobid;
- if(logpath_override)
- {
- ret = snprintf(logfile_name, PATH_MAX,
- "%s/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
- logpath_override,
- cuser, __progname, jobid,
- (my_tm->tm_mon+1),
- my_tm->tm_mday,
- (my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec),
- logmod);
- if(ret == (PATH_MAX-1))
- {
- /* file name was too big; squish it down */
- snprintf(logfile_name, PATH_MAX,
- "%s/id%d.darshan_partial",
- logpath_override, jobid);
- }
- }
- else if(logpath)
- {
- ret = snprintf(logfile_name, PATH_MAX,
- "%s/%d/%d/%d/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
- logpath, (my_tm->tm_year+1900),
- (my_tm->tm_mon+1), my_tm->tm_mday,
- cuser, __progname, jobid,
- (my_tm->tm_mon+1),
- my_tm->tm_mday,
- (my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec),
- logmod);
- if(ret == (PATH_MAX-1))
- {
- /* file name was too big; squish it down */
- snprintf(logfile_name, PATH_MAX,
- "%s/id%d.darshan_partial",
- logpath, jobid);
- }
- }
- else
- {
- logfile_name[0] = '\0';
- }
+ /* use human readable start time format in log filename */
+ start_time_tmp = final_job->log_job.start_time;
+ start_tm = localtime(&start_time_tmp);
- /* add jobid */
- final_job->log_job.jobid = (int64_t)jobid;
+ /* construct log file name */
+ darshan_get_logfile_name(logfile_name, jobid, start_tm);
}
/* broadcast log file name */
@@ -404,8 +268,17 @@ static void darshan_core_shutdown()
final_job->log_job.end_time = last_end_time;
}
- /* TODO: coordinate shutdown accross all registered modules */
- DARSHAN_MOD_ITER(mod, tmp, final_job)
+ /* set which local modules were actually used */
+ for(i = 0; i < DARSHAN_MAX_MODS; i++)
+ {
+ if(final_job->mod_array[i])
+ local_mod_use[i] = 1;
+ }
+
+ /* reduce the number of times a module was opened globally and bcast to everyone */
+ DARSHAN_MPI_CALL(PMPI_Allreduce)(local_mod_use, global_mod_use_count, DARSHAN_MAX_MODS, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+
+ for(i = 0; i < DARSHAN_MAX_MODS; i++)
{
}
@@ -413,7 +286,7 @@ static void darshan_core_shutdown()
free(logfile_name);
darshan_core_cleanup(final_job);
- if (internal_timing_flag)
+ if(internal_timing_flag)
{
/* TODO: what do we want to time in new darshan version? */
}
@@ -423,12 +296,11 @@ static void darshan_core_shutdown()
static void darshan_core_cleanup(struct darshan_core_job_runtime* job)
{
- struct darshan_core_module *mod, *tmp;
+ int i;
- DARSHAN_MOD_ITER(mod, tmp, job)
+ for(i = 0; i < DARSHAN_MAX_MODS; i++)
{
- DARSHAN_MOD_DELETE(mod, job);
- free(mod);
+
}
free(job);
@@ -436,44 +308,170 @@ static void darshan_core_cleanup(struct darshan_core_job_runtime* job)
return;
}
-static int mod_cmp(struct darshan_core_module* a, struct darshan_core_module* b)
+static void darshan_get_logfile_name(char* logfile_name, int jobid, struct tm* start_tm)
{
- return strcmp(a->name, b->name);
+ char* logpath;
+ char* logname_string;
+ char* logpath_override = NULL;
+#ifdef __CP_LOG_ENV
+ char env_check[256];
+ char* env_tok;
+#endif
+ uint64_t hlevel;
+ char hname[HOST_NAME_MAX];
+ uint64_t logmod;
+ char cuser[L_cuserid] = {0};
+ int ret;
+
+ /* Use CP_LOG_PATH_OVERRIDE for the value or __CP_LOG_PATH */
+ logpath = getenv(CP_LOG_PATH_OVERRIDE);
+ if(!logpath)
+ {
+#ifdef __CP_LOG_PATH
+ logpath = __CP_LOG_PATH;
+#endif
+ }
+
+ /* get the username for this job. In order we will try each of the
+ * following until one of them succeeds:
+ *
+ * - cuserid()
+ * - getenv("LOGNAME")
+ * - snprintf(..., geteuid());
+ *
+ * Note that we do not use getpwuid() because it generally will not
+ * work in statically compiled binaries.
+ */
+
+#ifndef DARSHAN_DISABLE_CUSERID
+ cuserid(cuser);
+#endif
+
+ /* if cuserid() didn't work, then check the environment */
+ if(strcmp(cuser, "") == 0)
+ {
+ logname_string = getenv("LOGNAME");
+ if(logname_string)
+ {
+ strncpy(cuser, logname_string, (L_cuserid-1));
+ }
+
+ }
+
+ /* if cuserid() and environment both fail, then fall back to uid */
+ if(strcmp(cuser, "") == 0)
+ {
+ uid_t uid = geteuid();
+ snprintf(cuser, sizeof(cuser), "%u", uid);
+ }
+
+ /* generate a random number to help differentiate the log */
+ hlevel=DARSHAN_MPI_CALL(PMPI_Wtime)() * 1000000;
+ (void)gethostname(hname, sizeof(hname));
+ logmod = darshan_hash((void*)hname,strlen(hname),hlevel);
+
+ /* see if darshan was configured using the --with-logpath-by-env
+ * argument, which allows the user to specify an absolute path to
+ * place logs via an env variable.
+ */
+#ifdef __CP_LOG_ENV
+ /* just silently skip if the environment variable list is too big */
+ if(strlen(__CP_LOG_ENV) < 256)
+ {
+ /* copy env variable list to a temporary buffer */
+ strcpy(env_check, __CP_LOG_ENV);
+ /* tokenize the comma-separated list */
+ env_tok = strtok(env_check, ",");
+ if(env_tok)
+ {
+ do
+ {
+ /* check each env variable in order */
+ logpath_override = getenv(env_tok);
+ if(logpath_override)
+ {
+ /* stop as soon as we find a match */
+ break;
+ }
+ }while((env_tok = strtok(NULL, ",")));
+ }
+ }
+#endif
+
+ if(logpath_override)
+ {
+ ret = snprintf(logfile_name, PATH_MAX,
+ "%s/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
+ logpath_override,
+ cuser, __progname, jobid,
+ (start_tm->tm_mon+1),
+ start_tm->tm_mday,
+ (start_tm->tm_hour*60*60 + start_tm->tm_min*60 + start_tm->tm_sec),
+ logmod);
+ if(ret == (PATH_MAX-1))
+ {
+ /* file name was too big; squish it down */
+ snprintf(logfile_name, PATH_MAX,
+ "%s/id%d.darshan_partial",
+ logpath_override, jobid);
+ }
+ }
+ else if(logpath)
+ {
+ ret = snprintf(logfile_name, PATH_MAX,
+ "%s/%d/%d/%d/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
+ logpath, (start_tm->tm_year+1900),
+ (start_tm->tm_mon+1), start_tm->tm_mday,
+ cuser, __progname, jobid,
+ (start_tm->tm_mon+1),
+ start_tm->tm_mday,
+ (start_tm->tm_hour*60*60 + start_tm->tm_min*60 + start_tm->tm_sec),
+ logmod);
+ if(ret == (PATH_MAX-1))
+ {
+ /* file name was too big; squish it down */
+ snprintf(logfile_name, PATH_MAX,
+ "%s/id%d.darshan_partial",
+ logpath, jobid);
+ }
+ }
+ else
+ {
+ logfile_name[0] = '\0';
+ }
+
+ return;
}
/* ********************************************************* */
void darshan_core_register_module(
+ darshan_module_id id,
char *name,
struct darshan_module_funcs *funcs,
int *runtime_mem_limit)
{
- struct darshan_core_module tmp;
struct darshan_core_module* mod;
DARSHAN_LOCK();
*runtime_mem_limit = 0;
- if(!darshan_core_job)
+ if(!darshan_core_job || (id >= DARSHAN_MAX_MODS))
{
DARSHAN_UNLOCK();
return;
}
/* see if this module is already registered */
- strncpy(tmp.name, name, DARSHAN_MOD_NAME_LEN);
- DARSHAN_MOD_SEARCH(mod, &tmp, darshan_core_job);
- if(mod)
+ if(darshan_core_job->mod_array[id])
{
- /* if module is already registered, update module_funcs and return */
+ /* if module is already registered just return */
/* NOTE: we do not recalculate memory limit here, just set to 0 */
- mod->mod_funcs = *funcs;
-
DARSHAN_UNLOCK();
return;
}
- /* this module has not been registered yet, allocate and register it */
+ /* this module has not been registered yet, allocate and initialize it */
mod = malloc(sizeof(*mod));
if(!mod)
{
@@ -482,9 +480,12 @@ void darshan_core_register_module(
}
memset(mod, 0, sizeof(*mod));
+ mod->id = id;
strncpy(mod->name, name, DARSHAN_MOD_NAME_LEN);
mod->mod_funcs = *funcs;
- DARSHAN_MOD_REGISTER(mod, darshan_core_job);
+
+ /* register module with darshan */
+ darshan_core_job->mod_array[id] = mod;
/* TODO: something smarter than just 2 MiB per module */
*runtime_mem_limit = 2 * 1024 * 1024;
diff --git a/darshan-runtime/lib/darshan-posix.c b/darshan-runtime/lib/darshan-posix.c
index 06476fa..d35c2c2 100644
--- a/darshan-runtime/lib/darshan-posix.c
+++ b/darshan-runtime/lib/darshan-posix.c
@@ -362,6 +362,7 @@ static void posix_runtime_initialize()
/* register the posix module with darshan core */
darshan_core_register_module(
+ DARSHAN_POSIX_MOD,
POSIX_MOD_NAME,
&posix_mod_fns,
&mem_limit);
diff --git a/darshan-runtime/utlist.h b/darshan-runtime/utlist.h
deleted file mode 100644
index 35fc9db..0000000
--- a/darshan-runtime/utlist.h
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-Copyright (c) 2007-2010, Troy D. Hanson http://uthash.sourceforge.net
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef UTLIST_H
-#define UTLIST_H
-
-#define UTLIST_VERSION 1.9.1
-
-/*
- * This file contains macros to manipulate singly and doubly-linked lists.
- *
- * 1. LL_ macros: singly-linked lists.
- * 2. DL_ macros: doubly-linked lists.
- * 3. CDL_ macros: circular doubly-linked lists.
- *
- * To use singly-linked lists, your structure must have a "next" pointer.
- * To use doubly-linked lists, your structure must "prev" and "next" pointers.
- * Either way, the pointer to the head of the list must be initialized to NULL.
- *
- * ----------------.EXAMPLE -------------------------
- * struct item {
- * int id;
- * struct item *prev, *next;
- * }
- *
- * struct item *list = NULL:
- *
- * int main() {
- * struct item *item;
- * ... allocate and populate item ...
- * DL_APPEND(list, item);
- * }
- * --------------------------------------------------
- *
- * For doubly-linked lists, the append and delete macros are O(1)
- * For singly-linked lists, append and delete are O(n) but prepend is O(1)
- * The sort macro is O(n log(n)) for all types of single/double/circular lists.
- */
-
-/* These macros use decltype or the earlier __typeof GNU extension.
- As decltype is only available in newer compilers (VS2010 or gcc 4.3+
- when compiling c++ code), this code uses whatever method is needed
- or, for VS2008 where neither is available, uses casting workarounds. */
-#ifdef _MSC_VER /* MS compiler */
-#if _MSC_VER >= 1600 && __cplusplus /* VS2010 and newer in C++ mode */
-#define LDECLTYPE(x) decltype(x)
-#else /* VS2008 or older (or VS2010 in C mode) */
-#define NO_DECLTYPE
-#define LDECLTYPE(x) char*
-#endif
-#else /* GNU, Sun and other compilers */
-#define LDECLTYPE(x) __typeof(x)
-#endif
-
-/* for VS2008 we use some workarounds to get around the lack of decltype,
- * namely, we always reassign our tmp variable to the list head if we need
- * to dereference its prev/next pointers, and save/restore the real head.*/
-#ifdef NO_DECLTYPE
-#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
-#define _NEXT(elt,list) ((char*)((list)->next))
-#define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
-#define _PREV(elt,list) ((char*)((list)->prev))
-#define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
-#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
-#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
-#else
-#define _SV(elt,list)
-#define _NEXT(elt,list) ((elt)->next)
-#define _NEXTASGN(elt,list,to) ((elt)->next)=(to)
-#define _PREV(elt,list) ((elt)->prev)
-#define _PREVASGN(elt,list,to) ((elt)->prev)=(to)
-#define _RS(list)
-#define _CASTASGN(a,b) (a)=(b)
-#endif
-
-/******************************************************************************
- * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort *
- * Unwieldy variable names used here to avoid shadowing passed-in variables. *
- *****************************************************************************/
-#define LL_SORT(list, cmp) \
-do { \
- LDECLTYPE(list) _ls_p; \
- LDECLTYPE(list) _ls_q; \
- LDECLTYPE(list) _ls_e; \
- LDECLTYPE(list) _ls_tail; \
- LDECLTYPE(list) _ls_oldhead; \
- LDECLTYPE(list) _tmp; \
- int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
- if (list) { \
- _ls_insize = 1; \
- _ls_looping = 1; \
- while (_ls_looping) { \
- _CASTASGN(_ls_p,list); \
- _CASTASGN(_ls_oldhead,list); \
- list = NULL; \
- _ls_tail = NULL; \
- _ls_nmerges = 0; \
- while (_ls_p) { \
- _ls_nmerges++; \
- _ls_q = _ls_p; \
- _ls_psize = 0; \
- for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
- _ls_psize++; \
- _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
- if (!_ls_q) break; \
- } \
- _ls_qsize = _ls_insize; \
- while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
- if (_ls_psize == 0) { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- } else if (_ls_qsize == 0 || !_ls_q) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- } else if (cmp(_ls_p,_ls_q) <= 0) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- } else { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- } \
- if (_ls_tail) { \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
- } else { \
- _CASTASGN(list,_ls_e); \
- } \
- _ls_tail = _ls_e; \
- } \
- _ls_p = _ls_q; \
- } \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
- if (_ls_nmerges <= 1) { \
- _ls_looping=0; \
- } \
- _ls_insize *= 2; \
- } \
- } else _tmp=NULL; /* quiet gcc unused variable warning */ \
-} while (0)
-
-#define DL_SORT(list, cmp) \
-do { \
- LDECLTYPE(list) _ls_p; \
- LDECLTYPE(list) _ls_q; \
- LDECLTYPE(list) _ls_e; \
- LDECLTYPE(list) _ls_tail; \
- LDECLTYPE(list) _ls_oldhead; \
- LDECLTYPE(list) _tmp; \
- int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
- if (list) { \
- _ls_insize = 1; \
- _ls_looping = 1; \
- while (_ls_looping) { \
- _CASTASGN(_ls_p,list); \
- _CASTASGN(_ls_oldhead,list); \
- list = NULL; \
- _ls_tail = NULL; \
- _ls_nmerges = 0; \
- while (_ls_p) { \
- _ls_nmerges++; \
- _ls_q = _ls_p; \
- _ls_psize = 0; \
- for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
- _ls_psize++; \
- _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
- if (!_ls_q) break; \
- } \
- _ls_qsize = _ls_insize; \
- while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
- if (_ls_psize == 0) { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- } else if (_ls_qsize == 0 || !_ls_q) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- } else if (cmp(_ls_p,_ls_q) <= 0) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- } else { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- } \
- if (_ls_tail) { \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
- } else { \
- _CASTASGN(list,_ls_e); \
- } \
- _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
- _ls_tail = _ls_e; \
- } \
- _ls_p = _ls_q; \
- } \
- _CASTASGN(list->prev, _ls_tail); \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
- if (_ls_nmerges <= 1) { \
- _ls_looping=0; \
- } \
- _ls_insize *= 2; \
- } \
- } else _tmp=NULL; /* quiet gcc unused variable warning */ \
-} while (0)
-
-#define CDL_SORT(list, cmp) \
-do { \
- LDECLTYPE(list) _ls_p; \
- LDECLTYPE(list) _ls_q; \
- LDECLTYPE(list) _ls_e; \
- LDECLTYPE(list) _ls_tail; \
- LDECLTYPE(list) _ls_oldhead; \
- LDECLTYPE(list) _tmp; \
- LDECLTYPE(list) _tmp2; \
- int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
- if (list) { \
- _ls_insize = 1; \
- _ls_looping = 1; \
- while (_ls_looping) { \
- _CASTASGN(_ls_p,list); \
- _CASTASGN(_ls_oldhead,list); \
- list = NULL; \
- _ls_tail = NULL; \
- _ls_nmerges = 0; \
- while (_ls_p) { \
- _ls_nmerges++; \
- _ls_q = _ls_p; \
- _ls_psize = 0; \
- for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
- _ls_psize++; \
- _SV(_ls_q,list); \
- if (_NEXT(_ls_q,list) == _ls_oldhead) { \
- _ls_q = NULL; \
- } else { \
- _ls_q = _NEXT(_ls_q,list); \
- } \
- _RS(list); \
- if (!_ls_q) break; \
- } \
- _ls_qsize = _ls_insize; \
- while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
- if (_ls_psize == 0) { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
- } else if (_ls_qsize == 0 || !_ls_q) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
- } else if (cmp(_ls_p,_ls_q) <= 0) { \
- _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
- if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
- } else { \
- _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
- if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
- } \
- if (_ls_tail) { \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
- } else { \
- _CASTASGN(list,_ls_e); \
- } \
- _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
- _ls_tail = _ls_e; \
- } \
- _ls_p = _ls_q; \
- } \
- _CASTASGN(list->prev,_ls_tail); \
- _CASTASGN(_tmp2,list); \
- _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list); \
- if (_ls_nmerges <= 1) { \
- _ls_looping=0; \
- } \
- _ls_insize *= 2; \
- } \
- } else _tmp=NULL; /* quiet gcc unused variable warning */ \
-} while (0)
-
-/******************************************************************************
- * singly linked list macros (non-circular) *
- *****************************************************************************/
-#define LL_PREPEND(head,add) \
-do { \
- (add)->next = head; \
- head = add; \
-} while (0)
-
-#define LL_APPEND(head,add) \
-do { \
- LDECLTYPE(head) _tmp; \
- (add)->next=NULL; \
- if (head) { \
- _tmp = head; \
- while (_tmp->next) { _tmp = _tmp->next; } \
- _tmp->next=(add); \
- } else { \
- (head)=(add); \
- } \
-} while (0)
-
-#define LL_DELETE(head,del) \
-do { \
- LDECLTYPE(head) _tmp; \
- if ((head) == (del)) { \
- (head)=(head)->next; \
- } else { \
- _tmp = head; \
- while (_tmp->next && (_tmp->next != (del))) { \
- _tmp = _tmp->next; \
- } \
- if (_tmp->next) { \
- _tmp->next = ((del)->next); \
- } \
- } \
-} while (0)
-
-/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
-#define LL_APPEND_VS2008(head,add) \
-do { \
- if (head) { \
- (add)->next = head; /* use add->next as a temp variable */ \
- while ((add)->next->next) { (add)->next = (add)->next->next; } \
- (add)->next->next=(add); \
- } else { \
- (head)=(add); \
- } \
- (add)->next=NULL; \
-} while (0)
-
-#define LL_DELETE_VS2008(head,del) \
-do { \
- if ((head) == (del)) { \
- (head)=(head)->next; \
- } else { \
- char *_tmp = (char*)(head); \
- while (head->next && (head->next != (del))) { \
- head = head->next; \
- } \
- if (head->next) { \
- head->next = ((del)->next); \
- } \
- { \
- char **_head_alias = (char**)&(head); \
- *_head_alias = _tmp; \
- } \
- } \
-} while (0)
-#ifdef NO_DECLTYPE
-#undef LL_APPEND
-#define LL_APPEND LL_APPEND_VS2008
-#undef LL_DELETE
-#define LL_DELETE LL_DELETE_VS2008
-#endif
-/* end VS2008 replacements */
-
-#define LL_FOREACH(head,el) \
- for(el=head;el;el=el->next)
-
-#define LL_FOREACH_SAFE(head,el,tmp) \
- for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
-
-#define LL_SEARCH_SCALAR(head,out,field,val) \
-do { \
- LL_FOREACH(head,out) { \
- if ((out)->field == (val)) break; \
- } \
-} while(0)
-
-#define LL_SEARCH(head,out,elt,cmp) \
-do { \
- LL_FOREACH(head,out) { \
- if ((cmp(out,elt))==0) break; \
- } \
-} while(0)
-
-/******************************************************************************
- * doubly linked list macros (non-circular) *
- *****************************************************************************/
-#define DL_PREPEND(head,add) \
-do { \
- (add)->next = head; \
- if (head) { \
- (add)->prev = (head)->prev; \
- (head)->prev = (add); \
- } else { \
- (add)->prev = (add); \
- } \
- (head) = (add); \
-} while (0)
-
-#define DL_APPEND(head,add) \
-do { \
- if (head) { \
- (add)->prev = (head)->prev; \
- (head)->prev->next = (add); \
- (head)->prev = (add); \
- (add)->next = NULL; \
- } else { \
- (head)=(add); \
- (head)->prev = (head); \
- (head)->next = NULL; \
- } \
-} while (0);
-
-#define DL_DELETE(head,del) \
-do { \
- if ((del)->prev == (del)) { \
- (head)=NULL; \
- } else if ((del)==(head)) { \
- (del)->next->prev = (del)->prev; \
- (head) = (del)->next; \
- } else { \
- (del)->prev->next = (del)->next; \
- if ((del)->next) { \
- (del)->next->prev = (del)->prev; \
- } else { \
- (head)->prev = (del)->prev; \
- } \
- } \
-} while (0);
-
-
-#define DL_FOREACH(head,el) \
- for(el=head;el;el=el->next)
-
-/* this version is safe for deleting the elements during iteration */
-#define DL_FOREACH_SAFE(head,el,tmp) \
- for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
-
-/* these are identical to their singly-linked list counterparts */
-#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
-#define DL_SEARCH LL_SEARCH
-
-/******************************************************************************
- * circular doubly linked list macros *
- *****************************************************************************/
-#define CDL_PREPEND(head,add) \
-do { \
- if (head) { \
- (add)->prev = (head)->prev; \
- (add)->next = (head); \
- (head)->prev = (add); \
- (add)->prev->next = (add); \
- } else { \
- (add)->prev = (add); \
- (add)->next = (add); \
- } \
-(head)=(add); \
-} while (0)
-
-#define CDL_DELETE(head,del) \
-do { \
- if ( ((head)==(del)) && ((head)->next == (head))) { \
- (head) = 0L; \
- } else { \
- (del)->next->prev = (del)->prev; \
- (del)->prev->next = (del)->next; \
- if ((del) == (head)) (head)=(del)->next; \
- } \
-} while (0);
-
-#define CDL_FOREACH(head,el) \
- for(el=head;el;el=(el->next==head ? 0L : el->next))
-
-#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \
- for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \
- (el) && ((tmp2)=(el)->next, 1); \
- ((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
-
-#define CDL_SEARCH_SCALAR(head,out,field,val) \
-do { \
- CDL_FOREACH(head,out) { \
- if ((out)->field == (val)) break; \
- } \
-} while(0)
-
-#define CDL_SEARCH(head,out,elt,cmp) \
-do { \
- CDL_FOREACH(head,out) { \
- if ((cmp(out,elt))==0) break; \
- } \
-} while(0)
-
-#endif /* UTLIST_H */
-
hooks/post-receive
--
More information about the Darshan-commits
mailing list