brooks@maddog.llnl.gov (09/16/89)
Here are patches to 6 files in release 1.35 of GCC that implement
"shared" and "private" as storage class modifiers. I have checked
these for the sequent port and it appears to work, although we will
do a lot more testing. For the sequent port the sequence
.shdata
.comm
is used to get at the shared .comm segment. This work was done by
a student of mine, Joe Hoag (hoag@maddog.llnl.gov), and he will be
putting in some missing error checking for things such as an
occurence of shared or private for an auto variable next week.
We are grateful to schmidt@paris.ics.uci.edu for helping us out
with the perfect hash keyword additions and to ham@neon.stanford.edu
for giving us access to related work.
If anyone who uses a Sequent Balance or Symmetry for parallel
programming could try these patches out I would appreciate the
feedback.
*** /tmp/,RCSt1a28610 Fri Sep 15 16:18:40 1989
--- c-decl.c Fri Sep 15 15:25:49 1989
***************
*** 2599,2604
if ((specbits & (1 << (int) RID_EXTERN)) && initialized)
error ("`%s' has both `extern' and initializer", name);
}
}
/* Record `register' declaration for warnings on &
--- 2599,2614 -----
if ((specbits & (1 << (int) RID_EXTERN)) && initialized)
error ("`%s' has both `extern' and initializer", name);
}
+ TREE_SHARED (decl) = 0;
+ if( (specbits & (1 << (int) RID_SHARED)) && TREE_STATIC (decl))
+ TREE_SHARED (decl) = 1;
+
+ TREE_PRIVATELOC (decl) = 0;
+ if( (specbits & (1 << (int) RID_PRIVATE)) && TREE_STATIC (decl))
+ TREE_PRIVATELOC (decl) = 1;
+
+ if( TREE_SHARED (decl) && TREE_PRIVATELOC (decl) )
+ warning(" 'shared' and 'private' on same variable\n will default to 'shared'");
}
/* Record `register' declaration for warnings on &
***************
*** 2606,2611
if (specbits & (1 << (int) RID_REGISTER))
TREE_REGDECL (decl) = 1;
/* Record constancy and volatility. */
--- 2616,2625 -----
if (specbits & (1 << (int) RID_REGISTER))
TREE_REGDECL (decl) = 1;
+ if( TREE_REGDECL (decl) && TREE_SHARED (decl) ) {
+ warning(" 'register' variable cannot be shared");
+ TREE_SHARED (decl) = 0;
+ }
/* Record constancy and volatility. */
*** /tmp/,RCSt1a28610 Fri Sep 15 16:18:47 1989
--- c-parse.h Fri Sep 15 08:10:37 1989
***************
*** 42,47
RID_VOLATILE,
RID_INLINE,
RID_NOALIAS,
RID_MAX,
};
--- 42,49 -----
RID_VOLATILE,
RID_INLINE,
RID_NOALIAS,
+ RID_PRIVATE,
+ RID_SHARED,
RID_MAX,
};
*** /tmp/,RCSt1a28610 Fri Sep 15 16:18:50 1989
--- c-parse.y Fri Sep 15 08:10:21 1989
***************
*** 1318,1327
/* Data type that represents the GNU C reserved words. */
struct resword { char *name; short token; enum rid rid; };
- #define MIN_WORD_LENGTH 2 /* minimum size for C keyword */
- #define MAX_WORD_LENGTH 9 /* maximum size for C keyword */
- #define MIN_HASH_VALUE 4 /* range of the hash keys values */
- #define MAX_HASH_VALUE 52 /* for the perfect hash generator */
#define NORID RID_UNUSED
/* This function performs the minimum-perfect hash mapping from input
--- 1318,1323 -----
/* Data type that represents the GNU C reserved words. */
struct resword { char *name; short token; enum rid rid; };
#define NORID RID_UNUSED
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 10
***************
*** 1323,1329
#define MIN_HASH_VALUE 4 /* range of the hash keys values */
#define MAX_HASH_VALUE 52 /* for the perfect hash generator */
#define NORID RID_UNUSED
!
/* This function performs the minimum-perfect hash mapping from input
string to reswords table index. It only looks at the first and
last characters in the string, thus assuring the O(1) lookup time
--- 1319,1332 -----
struct resword { char *name; short token; enum rid rid; };
#define NORID RID_UNUSED
! #define MIN_WORD_LENGTH 2
! #define MAX_WORD_LENGTH 10
! #define MIN_HASH_VALUE 6
! #define MAX_HASH_VALUE 63
! /*
! 43 keywords
! 58 is the maximum key range
! */
/* This function performs the minimum-perfect hash mapping from input
string to reswords table index. It only looks at the first and
last characters in the string, thus assuring the O(1) lookup time
***************
*** 1351,1369
static int hash_table[] =
{
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
! 52, 52, 52, 52, 52, 7, 52, 12, 0, 18,
! 5, 0, 13, 2, 2, 29, 52, 0, 7, 37,
! 25, 0, 52, 52, 17, 19, 0, 21, 1, 3,
! 52, 52, 52, 52, 52, 52, 52, 52,
};
/* The hash function is very simple: add the length of STR
--- 1354,1372 -----
static int hash_table[] =
{
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
! 63, 63, 63, 63, 63, 0, 63, 31, 23, 10,
! 30, 0, 3, 16, 4, 15, 63, 0, 18, 29,
! 10, 0, 3, 63, 11, 0, 0, 0, 25, 4,
! 3, 32, 63, 63, 63, 63, 63, 63,
};
/* The hash function is very simple: add the length of STR
***************
*** 1371,1377
Putting LEN near LEN - 1 generates slightly better
code... */
! return len + hash_table[str[len - 1]] + hash_table[str[0]];
}
/* This routine attempts to match the string found in the reswords table
--- 1374,1380 -----
Putting LEN near LEN - 1 generates slightly better
code... */
! return len + hash_table[str[1]] + hash_table[str[0]] + hash_table[str[len - 1]];
}
/* This routine attempts to match the string found in the reswords table
***************
*** 1397,1449
static struct resword reswords[] =
{
! { "",},{ "",},{ "",},{ "",},
! { "else", ELSE, NORID },
! { "break", BREAK, NORID },
! { "goto", GOTO, NORID },
! { "do", DO, NORID },
! { "while", WHILE, NORID },
! { "volatile", TYPE_QUAL, RID_VOLATILE },
! { "void", TYPESPEC, RID_VOID },
! { "double", TYPESPEC, RID_DOUBLE },
! { "default", DEFAULT, NORID },
! { "long", TYPESPEC, RID_LONG },
! { "__const", TYPE_QUAL, RID_CONST },
! { "__inline", SCSPEC, RID_INLINE },
! { "auto", SCSPEC, RID_AUTO },
! { "__volatile", TYPE_QUAL, RID_VOLATILE },
! { "float", TYPESPEC, RID_FLOAT },
! { "typeof", TYPEOF, NORID },
! { "typedef", SCSPEC, RID_TYPEDEF },
! { "",},
! { "case", CASE, NORID },
! { "const", TYPE_QUAL, RID_CONST },
! { "short", TYPESPEC, RID_SHORT },
! { "struct", STRUCT, NORID },
! { "continue", CONTINUE, NORID },
! { "switch", SWITCH, NORID },
! { "__typeof", TYPEOF, NORID },
! { "__alignof", ALIGNOF, NORID },
! { "signed", TYPESPEC, RID_SIGNED },
! { "extern", SCSPEC, RID_EXTERN },
! { "int", TYPESPEC, RID_INT },
! { "for", FOR, NORID },
! { "unsigned", TYPESPEC, RID_UNSIGNED },
! { "inline", SCSPEC, RID_INLINE },
! { "",},{ "",},
! { "sizeof", SIZEOF, NORID },
! { "char", TYPESPEC, RID_CHAR },
! { "",},
! { "enum", ENUM, NORID },
! { "register", SCSPEC, RID_REGISTER },
! { "static", SCSPEC, RID_STATIC },
! { "if", IF, NORID },
! { "",},{ "",},{ "",},
! { "return", RETURN, NORID },
! { "__asm", ASM, NORID },
! { "",},
! { "union", UNION, NORID },
! { "asm", ASM, NORID },
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
--- 1400,1454 -----
static struct resword reswords[] =
{
! {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
! {"struct", STRUCT, NORID ,},
! {"__const", TYPE_QUAL, RID_CONST ,},
! {"__inline", SCSPEC, RID_INLINE ,},
! {"short", TYPESPEC, RID_SHORT ,},
! {"__volatile", TYPE_QUAL, RID_VOLATILE ,},
! {"__typeof", TYPEOF, NORID ,},
! {"__alignof", ALIGNOF, NORID ,},
! {"while", WHILE, NORID ,},
! {"switch", SWITCH, NORID ,},
! {"const", TYPE_QUAL, RID_CONST ,},
! {"static", SCSPEC, RID_STATIC ,},
! {"for", FOR, NORID ,},
! {"continue", CONTINUE, NORID ,},
! {"extern", SCSPEC, RID_EXTERN ,},
! {"goto", GOTO, NORID ,},
! {"private", SCSPEC, RID_PRIVATE,},
! {"else", ELSE, NORID ,},
! {"if", IF, NORID ,},
! {"sizeof", SIZEOF, NORID ,},
! {"union", UNION, NORID ,},
! {"float", TYPESPEC, RID_FLOAT ,},
! {"return", RETURN, NORID ,},
! {"int", TYPESPEC, RID_INT ,},
! {"char", TYPESPEC, RID_CHAR ,},
! {"register", SCSPEC, RID_REGISTER ,},
! {"inline", SCSPEC, RID_INLINE ,},
! {"do", DO, NORID ,},
! {"volatile", TYPE_QUAL, RID_VOLATILE ,},
! {"__asm", ASM, NORID ,},
! {"auto", SCSPEC, RID_AUTO ,},
! {"double", TYPESPEC, RID_DOUBLE ,},
! {"default", DEFAULT, NORID ,},
! {"long", TYPESPEC, RID_LONG ,},
! {"break", BREAK, NORID ,},
! {"shared", SCSPEC, RID_SHARED,},
! {"typeof", TYPEOF, NORID ,},
! {"typedef", SCSPEC, RID_TYPEDEF ,},
! {"enum", ENUM, NORID ,},
! {"",},
! {"case", CASE, NORID ,},
! {"",}, {"",},
! {"unsigned", TYPESPEC, RID_UNSIGNED ,},
! {"",}, {"",},
! {"signed", TYPESPEC, RID_SIGNED ,},
! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
! {"void", TYPESPEC, RID_VOID ,},
! {"",}, {"",}, {"",},
! {"asm", ASM, NORID ,},
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
***************
*** 1498,1503
ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
ridpointers[(int) RID_REGISTER] = get_identifier ("register");
}
static void
--- 1503,1510 -----
ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
ridpointers[(int) RID_REGISTER] = get_identifier ("register");
+ ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
+ ridpointers[(int) RID_SHARED] = get_identifier ("shared");
}
static void
*** /tmp/,RCSt1a28610 Fri Sep 15 16:18:57 1989
--- print-tree.c Fri Sep 15 08:17:01 1989
***************
*** 258,264
fputs ("lang_flag_2", outfile);
first = 0;
}
! if (TREE_LANG_FLAG_3 (node))
{
if (!first) putc (' ', outfile);
fputs ("lang_flag_3", outfile);
--- 258,264 -----
fputs ("lang_flag_2", outfile);
first = 0;
}
! if (TREE_PRIVATELOC (node))
{
if (!first) putc (' ', outfile);
fputs ("private", outfile);
***************
*** 261,267
if (TREE_LANG_FLAG_3 (node))
{
if (!first) putc (' ', outfile);
! fputs ("lang_flag_3", outfile);
first = 0;
}
if (TREE_LANG_FLAG_4 (node))
--- 261,267 -----
if (TREE_PRIVATELOC (node))
{
if (!first) putc (' ', outfile);
! fputs ("private", outfile);
first = 0;
}
if (TREE_SHARED (node))
***************
*** 264,270
fputs ("lang_flag_3", outfile);
first = 0;
}
! if (TREE_LANG_FLAG_4 (node))
{
if (!first) putc (' ', outfile);
fputs ("lang_flag_4", outfile);
--- 264,270 -----
fputs ("private", outfile);
first = 0;
}
! if (TREE_SHARED (node))
{
if (!first) putc (' ', outfile);
fputs ("shared", outfile);
***************
*** 267,273
if (TREE_LANG_FLAG_4 (node))
{
if (!first) putc (' ', outfile);
! fputs ("lang_flag_4", outfile);
first = 0;
}
fputs ("] ", outfile);
--- 267,273 -----
if (TREE_SHARED (node))
{
if (!first) putc (' ', outfile);
! fputs ("shared", outfile);
first = 0;
}
fputs ("] ", outfile);
*** /tmp/,RCSt1a28610 Fri Sep 15 16:19:00 1989
--- tree.h Fri Sep 15 08:16:42 1989
***************
*** 146,151
unsigned asm_written_attr: 1;
unsigned inline_attr : 1;
unsigned used_attr : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
unsigned lang_flag_3 : 1;
--- 146,153 -----
unsigned asm_written_attr: 1;
unsigned inline_attr : 1;
unsigned used_attr : 1;
+ unsigned shared_attr : 1;
+ unsigned private_attr : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
/* There is room for two more attributes. */
***************
*** 148,156
unsigned used_attr : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
! unsigned lang_flag_3 : 1;
! unsigned lang_flag_4 : 1;
! /* There is room for four more attributes. */
};
/* Define accessors for the fields that all tree nodes have
--- 150,156 -----
unsigned private_attr : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
! /* There is room for two more attributes. */
};
/* Define accessors for the fields that all tree nodes have
***************
*** 273,278
/* Nonzero in a _DECL if the name is used in its scope. */
#define TREE_USED(NODE) ((NODE)->common.used_attr)
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)
#define TREE_LANG_FLAG_2(NODE) ((NODE)->common.lang_flag_2)
#define TREE_LANG_FLAG_3(NODE) ((NODE)->common.lang_flag_3)
--- 273,284 -----
/* Nonzero in a _DECL if the name is used in its scope. */
#define TREE_USED(NODE) ((NODE)->common.used_attr)
+ /* Nonzero in a _DECL if it is to be SHARED data. */
+ #define TREE_SHARED(NODE) ((NODE)->common.shared_attr)
+
+ /* Nonzero in a _DECL if it is to be PRIVATE data. */
+ #define TREE_PRIVATELOC(NODE) ((NODE)->common.private_attr)
+
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)
#define TREE_LANG_FLAG_2(NODE) ((NODE)->common.lang_flag_2)
***************
*** 275,282
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)
#define TREE_LANG_FLAG_2(NODE) ((NODE)->common.lang_flag_2)
- #define TREE_LANG_FLAG_3(NODE) ((NODE)->common.lang_flag_3)
- #define TREE_LANG_FLAG_4(NODE) ((NODE)->common.lang_flag_4)
/* Define additional fields and accessors for nodes representing constants. */
--- 281,286 -----
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)
#define TREE_LANG_FLAG_2(NODE) ((NODE)->common.lang_flag_2)
/* Define additional fields and accessors for nodes representing constants. */
*** /tmp/,RCSt1a28610 Fri Sep 15 16:19:05 1989
--- varasm.c Fri Sep 15 15:10:50 1989
***************
*** 38,43
#define MIN(a, b) ((a) < (b) ? (a) : (b))
/* File in which assembler code is being written. */
extern FILE *asm_out_file;
--- 38,46 -----
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+ #define SHARE_IT(NODE) ( (flag_shared_data && !TREE_PRIVATELOC (NODE)) \
+ || TREE_SHARED (NODE))
+
/* File in which assembler code is being written. */
extern FILE *asm_out_file;
***************
*** 70,76
void output_constant ();
void output_constructor ();
! static enum in_section {no_section, in_text, in_data} in_section = no_section;
/* Tell assembler to switch to text section. */
--- 73,79 -----
void output_constant ();
void output_constructor ();
! static enum in_section {no_section, in_text, in_data, in_shared_data} in_section = no_section;
/* Tell assembler to switch to text section. */
***************
*** 87,93
/* Tell assembler to switch to data section. */
void
! data_section ()
{
if (in_section != in_data)
{
--- 90,96 -----
/* Tell assembler to switch to data section. */
void
! shared_data_section()
{
if(in_section != in_shared_data) {
#ifdef SHARED_SECTION_ASM_OP
***************
*** 89,98
void
data_section ()
{
! if (in_section != in_data)
! {
! if (flag_shared_data)
! {
#ifdef SHARED_SECTION_ASM_OP
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
--- 92,98 -----
void
shared_data_section()
{
! if(in_section != in_shared_data) {
#ifdef SHARED_SECTION_ASM_OP
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
***************
*** 94,100
if (flag_shared_data)
{
#ifdef SHARED_SECTION_ASM_OP
! fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
--- 94,100 -----
{
if(in_section != in_shared_data) {
#ifdef SHARED_SECTION_ASM_OP
! fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
***************
*** 96,102
#ifdef SHARED_SECTION_ASM_OP
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
! fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
}
else
--- 96,102 -----
#ifdef SHARED_SECTION_ASM_OP
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
! fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
in_section = in_shared_data;
}
***************
*** 98,106
#else
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
! }
! else
! fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
in_section = in_data;
}
--- 98,106 -----
#else
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
! in_section = in_shared_data;
! }
! }
void
data_section ()
***************
*** 102,107
else
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
in_section = in_data;
}
}
--- 102,113 -----
}
}
+ void
+ data_section ()
+ {
+ if (in_section != in_data)
+ {
+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
in_section = in_data;
}
}
***************
*** 472,483
rounded = ((rounded + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
! if (flag_shared_data)
! data_section ();
! if (TREE_PUBLIC (decl))
! ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
! else
! ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
return;
}
--- 478,507 -----
rounded = ((rounded + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
! if (TREE_PUBLIC (decl)) {
! if (SHARE_IT (decl)) {
! #ifdef SHARED_ASM_OUTPUT_COMMON
! SHARED_ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
! #else
! ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
! #endif
! }
! else {
! ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
! }
! }
! else {
! if (SHARE_IT (decl)) {
! #ifdef SHARED_ASM_OUTPUT_LOCAL
! SHARED_ASM_OUTPUT_LOCAL(asm_out_file, name, size, rounded);
! #else
! ASM_OUTPUT_LOCAL(asm_out_file, name, size, rounded);
! #endif
! }
! else {
! ASM_OUTPUT_LOCAL(asm_out_file, name, size, rounded);
! }
! }
return;
}
***************
*** 503,510
/* Switch to the proper section for this data. */
if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
text_section ();
! else
! data_section ();
/* Output the alignment of this data. */
for (i = 0; DECL_ALIGN (decl) >= BITS_PER_UNIT << (i + 1); i++);
--- 527,536 -----
/* Switch to the proper section for this data. */
if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
text_section ();
! else {
! if (SHARE_IT (decl)) shared_data_section();
! else data_section ();
! }
/* Output the alignment of this data. */
for (i = 0; DECL_ALIGN (decl) >= BITS_PER_UNIT << (i + 1); i++);
***************
*** 579,586
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
! if (flag_shared_data)
! data_section ();
ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
++const_labelno;
--- 605,612 -----
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
! /* if (flag_shared_data)
! data_section (); */
ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
++const_labelno;
brooks@maddog.llnl.gov, brooks@maddog.uucp