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