1 /*****************************************************************************\
2  *  $Id: pstdout.h,v 1.7 2010-02-10 01:27:44 chu11 Exp $
3  *****************************************************************************
4  *  Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
5  *  Copyright (C) 2007 The Regents of the University of California.
6  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
7  *  Written by Albert Chu <chu11@llnl.gov>
8  *  UCRL-CODE-227589
9  *
10  *  This file is part of pstdout, a library used to launch and manage
11  *  the standard output of multiple threads. For details, see
12  *  http://www.llnl.gov/linux/.
13  *
14  *  Pstdout is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by the
16  *  Free Software Foundation; either version 3 of the License, or (at your
17  *  option) any later version.
18  *
19  *  Pstdout is distributed in the hope that it will be useful, but
20  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21  *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22  *  for more details.
23  *
24  *  You should have received a copy of the GNU General Public License along
25  *  with Pstdout.  If not, see <http://www.gnu.org/licenses/>.
26 \*****************************************************************************/
27 
28 #ifndef PSTDOUT_H
29 #define PSTDOUT_H
30 
31 /*
32  * Pstdout is a library/tool to launch and manage multiple threads,
33  * each dealing with a different host.  It will also manage the
34  * "parallel" standard output from the launched threads.
35  *
36  * The idea for pstdout came from the pdsh and dshbak.  (See
37  * http://sourceforge.net/projects/pdsh/ or
38  * http://www.llnl.gov/linux/pdsh/).  The tool (or code in pdsh) could
39  * not be directly used for all projects, thus this library was
40  * developed to emulate its functionality. Some of the same basic
41  * code/algorithms from pdsh have been re-used here.
42  *
43  * The general code structure using this library is as follows:
44  *
45  * call pstdout_init()
46  * call pstdout_set_output_flags() if non-defaults needed
47  * call pstdout_set_fanout() if non-defaults needed
48  * call pstdout_lauch() to launch parallel threads
49  * - within callback functions replace printf/fprintf/perror calls
50  *   with pstdout equivalent calls.
51  */
52 
53 #include <stdio.h>
54 #include <stdarg.h>
55 
56 /*
57  * Error Codes
58  */
59 #define PSTDOUT_ERR_SUCCESS               0
60 #define PSTDOUT_ERR_UNINITIALIZED         1
61 #define PSTDOUT_ERR_PARAMETERS            2
62 #define PSTDOUT_ERR_OUTMEM                3
63 #define PSTDOUT_ERR_INTERNAL              4
64 #define PSTDOUT_ERR_ERRNUMRANGE           5
65 
66 /*
67  * Debug Flags
68  *
69  * PSTDOUT_DEBUG_NONE - No debug output
70  *
71  * PSTDOUT_DEBUG_STANDARD - Output occasional debug info to stderr.
72  */
73 #define PSTDOUT_DEBUG_NONE                0x00000001
74 #define PSTDOUT_DEBUG_STANDARD            0x00000002
75 #define PSTDOUT_DEBUG_MASK                0x00000003
76 
77 /*
78  * Output Flags
79  *
80  * PSTDOUT_OUTPUT_STDOUT_DEFAULT/PSTDOUT_OUTPUT_STDERR_DEFAULT -
81  * Output stdout/stderr like normal
82  *
83  * PSTDOUT_OUTPUT_STDOUT_PREPEND_HOSTNAME/PSTDOUT_OUTPUT_STDERR_PREPEND_HOSTNAME
84  * - Prepend the hostname to each line of output.  For example,
85  * "host1: foo output".  Conflicts with PSTDOUT_OUTPUT_STDOUT/STDERR_DEFAULT.
86  *
87  * One of PSTDOUT_OUTPUT_STDOUT_DEFAULT and
88  * PSTDOUT_OUTPUT_STDOUT_PREPEND_HOSTNAME must always be set.  One of
89  * PSTDOUT_OUTPUT_STDERR_DEFAULT and
90  * PSTDOUT_OUTPUT_STDERR_PREPEND_HOSTNAME must always be set.
91  *
92  * PSTDOUT_OUTPUT_BUFFER_STDOUT/PSTDOUT_OUTPUT_BUFFER_STDERR - Do not
93  * output stdout/stderr as each line is output.  Buffer the output and
94  * output it all at once right before the thread terminates.  Can work
95  * in conjunction with PSTDOUT_OUTPUT_STDOUT/STDERR_PREPEND_HOSTNAME.
96  *
97  * PSTDOUT_OUTPUT_STDOUT_CONSOLIDATE/PSTDOUT_OUTPUT_STDERR_CONSOLIDATE
98  * - Do not output stdout/stderr until all threads have been executed.
99  * Consolidate output so that matching output from different nodes are
100  * not output twice.  Conflicts with
101  * PSTDOUT_OUTPUT_STDOUT/STDERR_PREPEND_HOSTNAME and
102  * PSTDOUT_OUTPUT_BUFFER_STDOUT/STDERR.
103  *
104  */
105 #define PSTDOUT_OUTPUT_STDOUT_DEFAULT          0x00000001
106 #define PSTDOUT_OUTPUT_STDERR_DEFAULT          0x00000002
107 #define PSTDOUT_OUTPUT_STDOUT_PREPEND_HOSTNAME 0x00000004
108 #define PSTDOUT_OUTPUT_STDERR_PREPEND_HOSTNAME 0x00000008
109 #define PSTDOUT_OUTPUT_BUFFER_STDOUT           0x00000010
110 #define PSTDOUT_OUTPUT_BUFFER_STDERR           0x00000020
111 #define PSTDOUT_OUTPUT_STDOUT_CONSOLIDATE      0x00000040
112 #define PSTDOUT_OUTPUT_STDERR_CONSOLIDATE      0x00000080
113 #define PSTDOUT_OUTPUT_MASK                    0x000000FF
114 
115 /*
116  * Fanout default, min, and max
117  */
118 #define PSTDOUT_FANOUT_DEFAULT    64
119 #define PSTDOUT_FANOUT_MIN        1
120 #define PSTDOUT_FANOUT_MAX        1024
121 
122 /* pstdout_errnum
123  *
124  * Will be set to the most recently set pstdout error
125  */
126 extern int pstdout_errnum;
127 
128 /* pstdout_state_t
129  *
130  * Maintains parallel stdout information.  Will be passed to each
131  * thread that is launched via 'pstdout_launch' and must be passed to
132  * each call of 'pstdout_printf', 'pstdout_fprintf' or
133  * 'pstdout_perror'.
134  */
135 typedef struct pstdout_state *pstdout_state_t;
136 
137 /* Pstdout_Thread
138  *
139  * Function prototype of the function that pstdout will launch.
140  * Passed to 'pstdout_launch'.
141  *
142  * Returns the exit code for this thread.
143  */
144 typedef int (*Pstdout_Thread)(pstdout_state_t pstate, const char *hostname, void *arg);
145 
146 /* pstdout_init
147  *
148  * Must be called before most pstdout API functions can be called.
149  */
150 int pstdout_init(void);
151 
152 /* pstdout_strerror
153  *
154  * Returns statically defined string describing the error code.
155  */
156 char *pstdout_strerror(int errnum);
157 
158 /* pstdout_set_debug_flags
159  *
160  * Set the current debug flags.
161  *
162  * Returns 0 on success, -1 on error
163  */
164 int pstdout_set_debug_flags(unsigned int flags);
165 
166 /* pstdout_get_debug_flags
167  *
168  * Returns current debug flags.
169  */
170 int pstdout_get_debug_flags(void);
171 
172 /* pstdout_set_output_flags
173  *
174  * Set the current output flags.
175  *
176  * Returns 0 on success, -1 on error
177  */
178 int pstdout_set_output_flags(unsigned int flags);
179 
180 /* pstdout_get_output_flags
181  *
182  * Returns current output flags.
183  */
184 int pstdout_get_output_flags(void);
185 
186 /* pstdout_set_fanout
187  *
188  * Set the current fanout.  The fanout is the largest number of
189  * threads that can be launched simultaneously by 'pstdout_launch'.
190  *
191  * Returns 0 on success, -1 on error
192  */
193 int pstdout_set_fanout(unsigned int fanout);
194 
195 /* pstdout_get_fanout
196  *
197  * Returns current fanout.
198  */
199 int pstdout_get_fanout(void);
200 
201 /* pstdout_hostnames_count
202  *
203  * Count the number of hosts specified by hostnames.  Primarily a
204  * utility function to allow client writers to determine what output
205  * flags they wish to set.
206  *
207  * Returns number of hostnames on success, -1 on error.
208  */
209 int pstdout_hostnames_count(const char *hostnames);
210 
211 /* pstdout_printf
212  *
213  * Parallel standard output.  Should only be called by a thread
214  * executed by 'pstdout_launch'.
215  *
216  * Returns number of characters printed, -1 on error.
217  *
218  * Note that the return value of number of characters printed may be
219  * 0, because data is being buffered for output on a later
220  * pstdout_printf call.
221  */
222 int pstdout_printf(pstdout_state_t pstate, const char *format, ...);
223 
224 /* pstdout_vprintf
225  *
226  * Parallel standard output.  Should only be called by a thread
227  * executed by 'pstdout_launch'.
228  *
229  * Returns number of characters printed, -1 on error.
230  *
231  * Note that the return value of number of characters printed may be
232  * 0, because data is being buffered for output on a later
233  * pstdout_printf call.
234  */
235 int pstdout_vprintf(pstdout_state_t pstate, const char *format, va_list ap);
236 
237 /* pstdout_fprintf
238  *
239  * Parallel file stream output.  Should only be called by a thread
240  * executed by 'pstdout_launch'.  Currently will only work with stdout
241  * and stderr.
242  *
243  * Returns number of characters printed, -1 on error.
244  *
245  * Note that the return value of number of characters printed may be
246  * 0, because data is being buffered for output on a later
247  * pstdout_fprintf call.
248  */
249 int pstdout_fprintf(pstdout_state_t pstate, FILE *stream, const char *format, ...);
250 
251 /* pstdout_vfprintf
252  *
253  * Parallel file stream output.  Should only be called by a thread
254  * executed by 'pstdout_launch'.  Currently will only work with stdout
255  * and stderr.
256  *
257  * Returns number of characters printed, -1 on error.
258  *
259  * Note that the return value of number of characters printed may be
260  * 0, because data is being buffered for output on a later
261  * pstdout_fprintf call.
262  */
263 int pstdout_vfprintf(pstdout_state_t pstate, FILE *stream, const char *format,
264                      va_list ap);
265 
266 /* pstdout_perror
267  *
268  * Parallel perror.  Should only be called by a thread executed by
269  * 'pstdout_launch'.
270  */
271 void pstdout_perror(pstdout_state_t pstate, const char *s);
272 
273 /* pstdout_launch
274  *
275  * Primary thread launching function of the library.  It will launch
276  * no more than 'fanout' threads at the same time, launching new
277  * threads after old ones have completed.  Will handle all standard output
278  * buffering or consolidation that is required.
279  *
280  * Returns: Largest exit code returned from all threads launched.
281  */
282 int pstdout_launch(const char *hostnames, Pstdout_Thread pstdout_func, void *arg);
283 
284 /* PSTDOUT_PRINTF
285  *
286  * Identical to 'pstdout_printf', but will call standard printf() if an invalid
287  * pstate is passed in (e.g. a NULL pstate) or the library is not initialized.
288  */
289 int PSTDOUT_PRINTF(pstdout_state_t pstate, const char *format, ...);
290 
291 /* PSTDOUT_FPRINTF
292  *
293  * Identical to 'pstdout_fprintf', but will call standard fprintf() if
294  * an invalid pstate or stream is passed in (e.g. a NULL pstate) or
295  * the library is not initialized.
296  */
297 int PSTDOUT_FPRINTF(pstdout_state_t pstate, FILE *stream, const char *format, ...);
298 
299 /* PSTDOUT_PERROR
300  *
301  * Identical to 'pstdout_perror', but will call standard perror() if
302  * an invalid pstate is passed in (e.g. a NULL pstate) or the library
303  * is not initialized.
304  */
305 void PSTDOUT_PERROR(pstdout_state_t pstate, const char *s);
306 
307 #endif /* PSTDOUT_H */
308