AMPI #952: update ROMIO to MPICH2-1.4.1p1
[charm.git] / src / libs / ck-libs / ampi / romio / adio / common / system_hints.c
blobbd01d3b0054afa2a61ba1beadb456660f6858f32
1 /* -*- Mode: C; c-basic-offset:4 ; -*-
2 * vim: ts=8 sts=4 sw=4 noexpandtab
4 * Copyright (C) 2007 UChicago/Argonne LLC.
5 * See COPYRIGHT notice in top-level directory.
6 */
8 #include <adio.h>
10 #include <stdio.h>
12 #ifdef HAVE_FCNTL_H
13 #include <fcntl.h>
14 #endif
15 #ifdef HAVE_SYS_TYPES_H
16 #include <sys/types.h>
17 #endif
18 #ifdef HAVE_STDLIB_H
19 #include <stdlib.h>
20 #endif
21 #ifdef HAVE_STRING_H
22 #include <string.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 #include <sys/stat.h>
26 #endif
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30 #ifdef HAVE_IO_H
31 #include <io.h>
32 #endif
34 #ifndef PATH_MAX
35 #define PATH_MAX 65535
36 #endif
38 /*#define SYSHINT_DEBUG 1 */
40 #define ROMIO_HINT_DEFAULT_CFG "/etc/romio-hints"
41 #define ROMIO_HINT_ENV_VAR "ROMIO_HINTS"
43 /* should suppress unused warnings on GCC */
44 static void dump_keys(MPI_Info info) ATTRIBUTE((unused, used));
46 /* debug function: a routine I want in the library to make my life easier when
47 * using a source debugger. please ignore any "defined but not used" warnings
49 static void dump_keys(MPI_Info info)
51 int i, nkeys, flag;
52 char key[MPI_MAX_INFO_KEY];
53 char value[MPI_MAX_INFO_VAL];
55 MPI_Info_get_nkeys(info, &nkeys);
57 for (i=0; i<nkeys; i++) {
58 MPI_Info_get_nthkey(info, i, key);
59 ADIOI_Info_get(info, key, MPI_MAX_INFO_VAL-1, value, &flag);
60 printf("key = %s, value = %s\n", key, value);
62 return;
65 /* if user set the environment variable, use its value to find the
66 * file-of-hints. Otherwise, we'll look for the default config file. i.e. let
67 * the user override systemwide hint processing */
69 static int find_file(void)
71 int fd=-1;
72 char * hintfile;
74 hintfile = getenv(ROMIO_HINT_ENV_VAR);
75 if(hintfile)
76 fd = open(hintfile, O_RDONLY);
77 if (fd < 0 )
78 fd = open(ROMIO_HINT_DEFAULT_CFG, O_RDONLY);
80 return fd;
83 /* parse the file-of-hints. Format is zero or more lines of "<key> <value>\n".
84 * A # in collumn zero is a comment and the line will be ignored. Do our best
85 * to ignore badly formed lines too.
87 * The caller provides an 'info' object. Each key-value pair found by the
88 * parser will get added to the info object. any keys already set will be left
89 * alone on the assumption that the caller knows best.
91 * because MPI-IO hints are optional, we can get away with limited error
92 * reporting. */
93 static int file_to_info(int fd, MPI_Info info)
95 char *buffer, *token, *key, *val, *garbage;
96 char *pos1=NULL, *pos2=NULL;
97 int flag, ret;
98 char dummy;
99 struct stat statbuf;
101 /* assumption: config files will be small (less than 1MB) */
102 fstat(fd, &statbuf);
103 /* add 1 to size to make room for NULL termination */
104 buffer = (char *)ADIOI_Calloc(statbuf.st_size + 1, sizeof (char));
105 if (buffer == NULL) return -1;
107 ret = read(fd, buffer, statbuf.st_size);
108 if (ret < 0) return -1;
109 token = strtok_r(buffer, "\n", &pos1);
110 do {
111 if ( (key = strtok_r(token, " \t", &pos2)) == NULL)
112 /* malformed line: found no items */
113 continue;
114 if (token[0] == '#')
115 /* ignore '#'-delimited comments */
116 continue;
117 if ( (val = strtok_r(NULL, " \t", &pos2)) == NULL)
118 /* malformed line: found key without value */
119 continue;
120 if ( (garbage = strtok_r(NULL, " \t", &pos2)) != NULL)
121 /* malformed line: more than two items */
122 continue;
124 #ifdef SYSHINT_DEBUG
125 printf("found: key=%s val=%s\n", key, val);
126 #endif
127 /* don't actually care what the value is. only want to know if key
128 * exists: we leave it alone if so*/
129 ADIOI_Info_get(info, key, 1, &dummy, &flag);
130 if (flag == 1) continue;
131 ADIOI_Info_set(info, key, val);
132 } while ((token = strtok_r(NULL, "\n", &pos1)) != NULL);
133 ADIOI_Free(buffer);
134 return 0;
137 void ADIOI_process_system_hints(MPI_Info info)
139 int hintfd;
141 hintfd = find_file();
142 if (hintfd < 0) {
143 #ifdef SYSHINT_DEBUG
144 perror("ADIOI_process_system_hints");
145 #endif
146 return;
148 file_to_info(hintfd, info);
149 close(hintfd);
152 /* given 'info', incorporate any hints in 'sysinfo' that are not already set
153 * into 'new_info'. Caller must free 'new_info' later. */
154 void ADIOI_incorporate_system_hints(MPI_Info info,
155 MPI_Info sysinfo,
156 MPI_Info *new_info)
158 int i, nkeys_sysinfo, flag;
159 char val[MPI_MAX_INFO_VAL], key[MPI_MAX_INFO_KEY];
161 if (sysinfo == MPI_INFO_NULL)
162 nkeys_sysinfo = 0;
163 else
164 MPI_Info_get_nkeys(sysinfo, &nkeys_sysinfo);
166 /* short-circuit: return immediately if no hints to process */
167 if (info == MPI_INFO_NULL && nkeys_sysinfo == 0) {
168 *new_info = MPI_INFO_NULL;
169 return;
172 if (info == MPI_INFO_NULL)
173 MPI_Info_create(new_info);
174 else
175 MPI_Info_dup(info, new_info);
177 for (i=0; i<nkeys_sysinfo; i++) {
178 MPI_Info_get_nthkey(sysinfo, i, key);
179 /* don't care about the value, just want to know if hint set already*/
180 if (info != MPI_INFO_NULL) ADIOI_Info_get(info, key, 1, val, &flag);
181 if (flag == 1) continue; /* skip any hints already set by user */
182 ADIOI_Info_get(sysinfo, key, MPI_MAX_INFO_VAL-1, val, &flag);
183 ADIOI_Info_set(*new_info, key, val);
184 flag = 0;
187 return;