| 1 | /* -*- Mode: C; c-basic-offset:4 ; -*- */ |
|---|
| 2 | /* |
|---|
| 3 | * (C) 2008 by Argonne National Laboratory. |
|---|
| 4 | * See COPYRIGHT in top-level directory. |
|---|
| 5 | */ |
|---|
| 6 | |
|---|
| 7 | #ifndef HYDRA_UTILS_H_INCLUDED |
|---|
| 8 | #define HYDRA_UTILS_H_INCLUDED |
|---|
| 9 | |
|---|
| 10 | #include "hydra_base.h" |
|---|
| 11 | #include "mpl.h" |
|---|
| 12 | |
|---|
| 13 | int HYDU_Error_printf_simple(const char *str, ...); |
|---|
| 14 | |
|---|
| 15 | #if !defined COMPILER_ACCEPTS_VA_ARGS |
|---|
| 16 | #define HYDU_Error_printf HYDU_Error_printf_simple |
|---|
| 17 | #elif defined HAVE__FUNC__ && defined __LINE__ |
|---|
| 18 | #define HYDU_Error_printf(...) \ |
|---|
| 19 | { \ |
|---|
| 20 | fprintf(stderr, "%s (%d): ", __func__, __LINE__); \ |
|---|
| 21 | HYDU_Error_printf_simple(__VA_ARGS__); \ |
|---|
| 22 | } |
|---|
| 23 | #elif defined HAVE_CAP__FUNC__ && defined __LINE__ |
|---|
| 24 | #define HYDU_Error_printf(...) \ |
|---|
| 25 | { \ |
|---|
| 26 | fprintf(stderr, "%s (%d): ", __FUNC__, __LINE__); \ |
|---|
| 27 | HYDU_Error_printf_simple(__VA_ARGS__); \ |
|---|
| 28 | } |
|---|
| 29 | #elif defined HAVE__FUNCTION__ && defined __LINE__ |
|---|
| 30 | #define HYDU_Error_printf(...) \ |
|---|
| 31 | { \ |
|---|
| 32 | fprintf(stderr, "%s (%d): ", __FUNCTION__, __LINE__); \ |
|---|
| 33 | HYDU_Error_printf_simple(__VA_ARGS__); \ |
|---|
| 34 | } |
|---|
| 35 | #elif defined __FILE__ && defined __LINE__ |
|---|
| 36 | #define HYDU_Error_printf(...) \ |
|---|
| 37 | { \ |
|---|
| 38 | fprintf(stderr, "%s (%d): ", __FILE__, __LINE__); \ |
|---|
| 39 | HYDU_Error_printf_simple(__VA_ARGS__); \ |
|---|
| 40 | } |
|---|
| 41 | #else |
|---|
| 42 | #define HYDU_Error_printf(...) \ |
|---|
| 43 | { \ |
|---|
| 44 | HYDU_Error_printf_simple(__VA_ARGS__); \ |
|---|
| 45 | } |
|---|
| 46 | #endif |
|---|
| 47 | |
|---|
| 48 | #define HYDU_ERR_POP(status, message) \ |
|---|
| 49 | { \ |
|---|
| 50 | if (status != HYD_SUCCESS && status != HYD_GRACEFUL_ABORT) { \ |
|---|
| 51 | if (strlen(message)) \ |
|---|
| 52 | HYDU_Error_printf(message); \ |
|---|
| 53 | goto fn_fail; \ |
|---|
| 54 | } \ |
|---|
| 55 | else if (status == HYD_GRACEFUL_ABORT) { \ |
|---|
| 56 | goto fn_exit; \ |
|---|
| 57 | } \ |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | #define HYDU_ERR_SETANDJUMP(status, error, message) \ |
|---|
| 61 | { \ |
|---|
| 62 | status = error; \ |
|---|
| 63 | if (status != HYD_SUCCESS && status != HYD_GRACEFUL_ABORT) { \ |
|---|
| 64 | if (strlen(message)) \ |
|---|
| 65 | HYDU_Error_printf(message); \ |
|---|
| 66 | goto fn_fail; \ |
|---|
| 67 | } \ |
|---|
| 68 | else if (status == HYD_GRACEFUL_ABORT) { \ |
|---|
| 69 | goto fn_exit; \ |
|---|
| 70 | } \ |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | #define HYDU_ERR_CHKANDJUMP(status, chk, error, message) \ |
|---|
| 74 | { \ |
|---|
| 75 | if ((chk)) \ |
|---|
| 76 | HYDU_ERR_SETANDJUMP(status, error, message); \ |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | #define HYDU_ERR_CHKANDJUMP1(status, chk, error, message, arg1) \ |
|---|
| 80 | { \ |
|---|
| 81 | if ((chk)) \ |
|---|
| 82 | HYDU_ERR_SETANDJUMP1(status, error, message, arg1); \ |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | #define HYDU_ERR_SETANDJUMP1(status, error, message, arg1) \ |
|---|
| 86 | { \ |
|---|
| 87 | status = error; \ |
|---|
| 88 | if (status != HYD_SUCCESS && status != HYD_GRACEFUL_ABORT) { \ |
|---|
| 89 | if (strlen(message)) \ |
|---|
| 90 | HYDU_Error_printf(message, arg1); \ |
|---|
| 91 | goto fn_fail; \ |
|---|
| 92 | } \ |
|---|
| 93 | else if (status == HYD_GRACEFUL_ABORT) { \ |
|---|
| 94 | goto fn_exit; \ |
|---|
| 95 | } \ |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | #define HYDU_ERR_SETANDJUMP2(status, error, message, arg1, arg2) \ |
|---|
| 99 | { \ |
|---|
| 100 | status = error; \ |
|---|
| 101 | if (status != HYD_SUCCESS && status != HYD_GRACEFUL_ABORT) { \ |
|---|
| 102 | if (strlen(message)) \ |
|---|
| 103 | HYDU_Error_printf(message, arg1, arg2); \ |
|---|
| 104 | goto fn_fail; \ |
|---|
| 105 | } \ |
|---|
| 106 | else if (status == HYD_GRACEFUL_ABORT) { \ |
|---|
| 107 | goto fn_exit; \ |
|---|
| 108 | } \ |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | #if defined ENABLE_WARNINGS |
|---|
| 112 | #define HYDU_Warn_printf HYDU_Error_printf |
|---|
| 113 | #else |
|---|
| 114 | #define HYDU_Warn_printf(...) {} |
|---|
| 115 | #endif /* ENABLE_WARNINGS */ |
|---|
| 116 | |
|---|
| 117 | #define HYDU_Dump printf |
|---|
| 118 | #if defined COMPILER_ACCEPTS_VA_ARGS |
|---|
| 119 | #define HYDU_Debug(debug, ...) \ |
|---|
| 120 | { \ |
|---|
| 121 | if ((debug)) \ |
|---|
| 122 | HYDU_Dump(__VA_ARGS__); \ |
|---|
| 123 | } |
|---|
| 124 | #else |
|---|
| 125 | #define HYDU_Debug(...) {} |
|---|
| 126 | #endif |
|---|
| 127 | |
|---|
| 128 | /* We need to add more information in here later */ |
|---|
| 129 | #if !defined ENABLE_DEBUG |
|---|
| 130 | #define HYDU_FUNC_ENTER() {} |
|---|
| 131 | #define HYDU_FUNC_EXIT() {} |
|---|
| 132 | #else |
|---|
| 133 | #define HYDU_FUNC_ENTER() {} |
|---|
| 134 | #define HYDU_FUNC_EXIT() {} |
|---|
| 135 | #endif |
|---|
| 136 | |
|---|
| 137 | |
|---|
| 138 | /* args */ |
|---|
| 139 | HYD_Status HYDU_find_in_path(const char *execname, char **path); |
|---|
| 140 | HYD_Status HYDU_get_base_path(const char *execname, char *wdir, char **path); |
|---|
| 141 | |
|---|
| 142 | |
|---|
| 143 | /* bind */ |
|---|
| 144 | #if defined HAVE_PROC_BINDING |
|---|
| 145 | HYD_Status HYDU_bind_init(char *user_bind_map); |
|---|
| 146 | HYD_Status HYDU_bind_process(int core); |
|---|
| 147 | int HYDU_bind_get_core_id(int id, HYD_Binding binding); |
|---|
| 148 | #endif /* HAVE_PROC_BINDING */ |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | /* env */ |
|---|
| 152 | HYD_Env_t *HYDU_str_to_env(char *str); |
|---|
| 153 | HYD_Status HYDU_list_append_env_to_str(HYD_Env_t * env_list, char **str_list); |
|---|
| 154 | HYD_Status HYDU_list_inherited_env(HYD_Env_t ** env_list); |
|---|
| 155 | HYD_Env_t *HYDU_env_list_dup(HYD_Env_t * env); |
|---|
| 156 | HYD_Status HYDU_env_create(HYD_Env_t ** env, const char *env_name, char *env_value); |
|---|
| 157 | HYD_Status HYDU_env_free(HYD_Env_t * env); |
|---|
| 158 | HYD_Status HYDU_env_free_list(HYD_Env_t * env); |
|---|
| 159 | HYD_Env_t *HYDU_env_lookup(HYD_Env_t env, HYD_Env_t * env_list); |
|---|
| 160 | HYD_Status HYDU_append_env_to_list(HYD_Env_t env, HYD_Env_t ** env_list); |
|---|
| 161 | HYD_Status HYDU_putenv(HYD_Env_t * env, HYD_Env_overwrite_t overwrite); |
|---|
| 162 | HYD_Status HYDU_putenv_list(HYD_Env_t * env_list, HYD_Env_overwrite_t overwrite); |
|---|
| 163 | HYD_Status HYDU_comma_list_to_env_list(char *str, HYD_Env_t ** env_list); |
|---|
| 164 | |
|---|
| 165 | |
|---|
| 166 | /* launch */ |
|---|
| 167 | #if defined HAVE_THREAD_SUPPORT |
|---|
| 168 | struct HYD_Thread_context { |
|---|
| 169 | pthread_t thread; |
|---|
| 170 | }; |
|---|
| 171 | #endif /* HAVE_THREAD_SUPPORT */ |
|---|
| 172 | |
|---|
| 173 | HYD_Status HYDU_alloc_partition(struct HYD_Partition **partition); |
|---|
| 174 | void HYDU_free_partition_list(struct HYD_Partition *partition); |
|---|
| 175 | HYD_Status HYDU_alloc_exec_info(struct HYD_Exec_info **exec_info); |
|---|
| 176 | void HYDU_free_exec_info_list(struct HYD_Exec_info *exec_info_list); |
|---|
| 177 | HYD_Status HYDU_alloc_partition_segment(struct HYD_Partition_segment **segment); |
|---|
| 178 | HYD_Status HYDU_merge_partition_segment(char *name, struct HYD_Partition_segment *segment, |
|---|
| 179 | struct HYD_Partition **partition_list); |
|---|
| 180 | HYD_Status HYDU_merge_partition_mapping(char *name, char *map, int num_procs, |
|---|
| 181 | struct HYD_Partition **partition_list); |
|---|
| 182 | HYD_Status HYDU_alloc_partition_exec(struct HYD_Partition_exec **exec); |
|---|
| 183 | HYD_Status HYDU_create_node_list_from_file(char *host_file, |
|---|
| 184 | struct HYD_Partition **partition_list); |
|---|
| 185 | HYD_Status HYDU_create_process(char **client_arg, HYD_Env_t * env_list, |
|---|
| 186 | int *in, int *out, int *err, int *pid, int core); |
|---|
| 187 | HYD_Status HYDU_fork_and_exit(int core); |
|---|
| 188 | #if defined HAVE_THREAD_SUPPORT |
|---|
| 189 | HYD_Status HYDU_create_thread(void *(*func) (void *), void *args, |
|---|
| 190 | struct HYD_Thread_context *ctxt); |
|---|
| 191 | HYD_Status HYDU_join_thread(struct HYD_Thread_context ctxt); |
|---|
| 192 | #endif /* HAVE_THREAD_SUPPORT */ |
|---|
| 193 | int HYDU_local_to_global_id(int local_id, int partition_core_count, |
|---|
| 194 | struct HYD_Partition_segment *segment_list, int global_core_count); |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | /* signals */ |
|---|
| 198 | #ifdef NEEDS_POSIX_FOR_SIGACTION |
|---|
| 199 | #define _POSIX_SOURCE |
|---|
| 200 | #endif |
|---|
| 201 | |
|---|
| 202 | #include <sys/wait.h> |
|---|
| 203 | #if defined(USE_SIGNAL) || defined(USE_SIGACTION) |
|---|
| 204 | #include <signal.h> |
|---|
| 205 | #else |
|---|
| 206 | #error no signal choice |
|---|
| 207 | #endif |
|---|
| 208 | #ifdef NEEDS_STRSIGNAL_DECL |
|---|
| 209 | extern char *strsignal(int); |
|---|
| 210 | #endif |
|---|
| 211 | |
|---|
| 212 | HYD_Status HYDU_set_signal(int signum, void (*handler) (int)); |
|---|
| 213 | HYD_Status HYDU_set_common_signals(void (*handler) (int)); |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | /* Sock utilities */ |
|---|
| 217 | enum HYDU_sock_comm_flag { |
|---|
| 218 | HYDU_SOCK_COMM_MSGWAIT = 0x01 |
|---|
| 219 | }; |
|---|
| 220 | |
|---|
| 221 | HYD_Status HYDU_sock_listen(int *listen_fd, char *port_range, uint16_t * port); |
|---|
| 222 | HYD_Status HYDU_sock_connect(const char *host, uint16_t port, int *fd); |
|---|
| 223 | HYD_Status HYDU_sock_accept(int listen_fd, int *fd); |
|---|
| 224 | HYD_Status HYDU_sock_readline(int fd, char *buf, int maxlen, int *linelen); |
|---|
| 225 | HYD_Status HYDU_sock_writeline(int fd, const char *buf, int maxsize); |
|---|
| 226 | HYD_Status HYDU_sock_read(int fd, void *buf, int maxlen, int *count, |
|---|
| 227 | enum HYDU_sock_comm_flag flag); |
|---|
| 228 | HYD_Status HYDU_sock_write(int fd, const void *buf, int maxsize); |
|---|
| 229 | HYD_Status HYDU_sock_trywrite(int fd, const void *buf, int maxsize); |
|---|
| 230 | HYD_Status HYDU_sock_set_nonblock(int fd); |
|---|
| 231 | HYD_Status HYDU_sock_set_cloexec(int fd); |
|---|
| 232 | HYD_Status HYDU_sock_stdout_cb(int fd, HYD_Event_t events, int stdout_fd, int *closed); |
|---|
| 233 | HYD_Status HYDU_sock_stdin_cb(int fd, HYD_Event_t events, int stdin_fd, char *buf, |
|---|
| 234 | int *buf_count, int *buf_offset, int *closed); |
|---|
| 235 | |
|---|
| 236 | |
|---|
| 237 | /* Memory utilities */ |
|---|
| 238 | #include <ctype.h> |
|---|
| 239 | |
|---|
| 240 | /* FIXME: This should eventually become MPL_malloc and friends */ |
|---|
| 241 | #define HYDU_malloc malloc |
|---|
| 242 | #define HYDU_calloc calloc |
|---|
| 243 | #define HYDU_free free |
|---|
| 244 | |
|---|
| 245 | #define HYDU_snprintf MPL_snprintf |
|---|
| 246 | #define HYDU_strdup MPL_strdup |
|---|
| 247 | |
|---|
| 248 | #define HYDU_MALLOC(p, type, size, status) \ |
|---|
| 249 | { \ |
|---|
| 250 | (p) = (type) HYDU_malloc((size)); \ |
|---|
| 251 | if ((p) == NULL) \ |
|---|
| 252 | HYDU_ERR_SETANDJUMP1((status), HYD_NO_MEM, \ |
|---|
| 253 | "failed to allocate %d bytes\n", \ |
|---|
| 254 | (size)); \ |
|---|
| 255 | } |
|---|
| 256 | |
|---|
| 257 | #define HYDU_CALLOC(p, type, num, size, status) \ |
|---|
| 258 | { \ |
|---|
| 259 | (p) = (type) HYDU_calloc((num), (size)); \ |
|---|
| 260 | if ((p) == NULL) \ |
|---|
| 261 | HYDU_ERR_SETANDJUMP1((status), HYD_NO_MEM, \ |
|---|
| 262 | "failed to allocate %d bytes\n", \ |
|---|
| 263 | (size)); \ |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | #define HYDU_FREE(p) \ |
|---|
| 267 | { \ |
|---|
| 268 | HYDU_free(p); \ |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | #define HYDU_STRLIST_CONSOLIDATE(strlist, i, status) \ |
|---|
| 272 | { \ |
|---|
| 273 | char *out; \ |
|---|
| 274 | if ((i) >= (HYD_NUM_TMP_STRINGS / 2)) { \ |
|---|
| 275 | (strlist)[(i)] = NULL; \ |
|---|
| 276 | (status) = HYDU_str_alloc_and_join((strlist), &out); \ |
|---|
| 277 | HYDU_ERR_POP((status), "unable to join strings\n"); \ |
|---|
| 278 | HYDU_free_strlist((strlist)); \ |
|---|
| 279 | strlist[0] = out; \ |
|---|
| 280 | (i) = 1; \ |
|---|
| 281 | } \ |
|---|
| 282 | } |
|---|
| 283 | |
|---|
| 284 | HYD_Status HYDU_list_append_strlist(char **exec, char **client_arg); |
|---|
| 285 | HYD_Status HYDU_print_strlist(char **args); |
|---|
| 286 | void HYDU_free_strlist(char **args); |
|---|
| 287 | HYD_Status HYDU_str_alloc_and_join(char **strlist, char **strjoin); |
|---|
| 288 | HYD_Status HYDU_strsplit(char *str, char **str1, char **str2, char sep); |
|---|
| 289 | HYD_Status HYDU_strdup_list(char *src[], char **dest[]); |
|---|
| 290 | char *HYDU_int_to_str(int x); |
|---|
| 291 | char *HYDU_strerror(int error); |
|---|
| 292 | int HYDU_strlist_lastidx(char **strlist); |
|---|
| 293 | char **HYDU_str_to_strlist(char *str); |
|---|
| 294 | |
|---|
| 295 | |
|---|
| 296 | /* Timer utilities */ |
|---|
| 297 | /* FIXME: HYD_Time should be OS specific */ |
|---|
| 298 | #ifdef HAVE_TIME |
|---|
| 299 | #include <time.h> |
|---|
| 300 | #endif /* HAVE_TIME */ |
|---|
| 301 | typedef struct timeval HYD_Time; |
|---|
| 302 | void HYDU_time_set(HYD_Time * time, int *val); |
|---|
| 303 | int HYDU_time_left(HYD_Time start, HYD_Time timeout); |
|---|
| 304 | |
|---|
| 305 | #endif /* HYDRA_UTILS_H_INCLUDED */ |
|---|