1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2011 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
13 * Copyright (c) 2014-2016 Research Organization for Information Science
14 * and Technology (RIST). All rights reserved.
15 * Copyright (c) 2016 Intel, Inc. All rights reserved.
16 * $COPYRIGHT$
17 *
18 * Additional copyrights may follow
19 *
20 * $HEADER$
21 */
22 #include "orte_config.h"
23 #include "orte/types.h"
24 #include "orte/constants.h"
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "opal/util/printf.h"
30 #include "opal/threads/tsd.h"
31
32 #include "orte/mca/errmgr/errmgr.h"
33
34 #include "orte/util/name_fns.h"
35
36 #define ORTE_PRINT_NAME_ARGS_MAX_SIZE 50
37 #define ORTE_PRINT_NAME_ARG_NUM_BUFS 16
38
39 #define ORTE_SCHEMA_DELIMITER_CHAR '.'
40 #define ORTE_SCHEMA_WILDCARD_CHAR '*'
41 #define ORTE_SCHEMA_WILDCARD_STRING "*"
42 #define ORTE_SCHEMA_INVALID_CHAR '$'
43 #define ORTE_SCHEMA_INVALID_STRING "$"
44
45 /* constructor - used to initialize namelist instance */
orte_namelist_construct(orte_namelist_t * list)46 static void orte_namelist_construct(orte_namelist_t* list)
47 {
48 list->name.jobid = ORTE_JOBID_INVALID;
49 list->name.vpid = ORTE_VPID_INVALID;
50 }
51
52 /* destructor - used to free any resources held by instance */
orte_namelist_destructor(orte_namelist_t * list)53 static void orte_namelist_destructor(orte_namelist_t* list)
54 {
55 }
56
57 /* define instance of opal_class_t */
58 OBJ_CLASS_INSTANCE(orte_namelist_t, /* type name */
59 opal_list_item_t, /* parent "class" name */
60 orte_namelist_construct, /* constructor */
61 orte_namelist_destructor); /* destructor */
62
63 static bool fns_init=false;
64
65 static opal_tsd_key_t print_args_tsd_key;
66 char* orte_print_args_null = "NULL";
67 typedef struct {
68 char *buffers[ORTE_PRINT_NAME_ARG_NUM_BUFS];
69 int cntr;
70 } orte_print_args_buffers_t;
71
72 static void
buffer_cleanup(void * value)73 buffer_cleanup(void *value)
74 {
75 int i;
76 orte_print_args_buffers_t *ptr;
77
78 if (NULL != value) {
79 ptr = (orte_print_args_buffers_t*)value;
80 for (i=0; i < ORTE_PRINT_NAME_ARG_NUM_BUFS; i++) {
81 free(ptr->buffers[i]);
82 }
83 free (ptr);
84 }
85 }
86
87 static orte_print_args_buffers_t*
get_print_name_buffer(void)88 get_print_name_buffer(void)
89 {
90 orte_print_args_buffers_t *ptr;
91 int ret, i;
92
93 if (!fns_init) {
94 /* setup the print_args function */
95 if (ORTE_SUCCESS != (ret = opal_tsd_key_create(&print_args_tsd_key, buffer_cleanup))) {
96 ORTE_ERROR_LOG(ret);
97 return NULL;
98 }
99 fns_init = true;
100 }
101
102 ret = opal_tsd_getspecific(print_args_tsd_key, (void**)&ptr);
103 if (OPAL_SUCCESS != ret) return NULL;
104
105 if (NULL == ptr) {
106 ptr = (orte_print_args_buffers_t*)malloc(sizeof(orte_print_args_buffers_t));
107 for (i=0; i < ORTE_PRINT_NAME_ARG_NUM_BUFS; i++) {
108 ptr->buffers[i] = (char *) malloc((ORTE_PRINT_NAME_ARGS_MAX_SIZE+1) * sizeof(char));
109 }
110 ptr->cntr = 0;
111 ret = opal_tsd_setspecific(print_args_tsd_key, (void*)ptr);
112 }
113
114 return (orte_print_args_buffers_t*) ptr;
115 }
116
orte_util_print_name_args(const orte_process_name_t * name)117 char* orte_util_print_name_args(const orte_process_name_t *name)
118 {
119 orte_print_args_buffers_t *ptr;
120 char *job, *vpid;
121
122 /* protect against NULL names */
123 if (NULL == name) {
124 /* get the next buffer */
125 ptr = get_print_name_buffer();
126 if (NULL == ptr) {
127 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
128 return orte_print_args_null;
129 }
130 /* cycle around the ring */
131 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
132 ptr->cntr = 0;
133 }
134 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "[NO-NAME]");
135 return ptr->buffers[ptr->cntr-1];
136 }
137
138 /* get the jobid, vpid strings first - this will protect us from
139 * stepping on each other's buffer. This also guarantees
140 * that the print_args function has been initialized, so
141 * we don't need to duplicate that here
142 */
143 job = orte_util_print_jobids(name->jobid);
144 vpid = orte_util_print_vpids(name->vpid);
145
146 /* get the next buffer */
147 ptr = get_print_name_buffer();
148
149 if (NULL == ptr) {
150 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
151 return orte_print_args_null;
152 }
153
154 /* cycle around the ring */
155 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
156 ptr->cntr = 0;
157 }
158
159 snprintf(ptr->buffers[ptr->cntr++],
160 ORTE_PRINT_NAME_ARGS_MAX_SIZE,
161 "[%s,%s]", job, vpid);
162
163 return ptr->buffers[ptr->cntr-1];
164 }
165
orte_util_print_jobids(const orte_jobid_t job)166 char* orte_util_print_jobids(const orte_jobid_t job)
167 {
168 orte_print_args_buffers_t *ptr;
169 unsigned long tmp1, tmp2;
170
171 ptr = get_print_name_buffer();
172
173 if (NULL == ptr) {
174 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
175 return orte_print_args_null;
176 }
177
178 /* cycle around the ring */
179 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
180 ptr->cntr = 0;
181 }
182
183 if (ORTE_JOBID_INVALID == job) {
184 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "[INVALID]");
185 } else if (ORTE_JOBID_WILDCARD == job) {
186 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "[WILDCARD]");
187 } else {
188 tmp1 = ORTE_JOB_FAMILY((unsigned long)job);
189 tmp2 = ORTE_LOCAL_JOBID((unsigned long)job);
190 snprintf(ptr->buffers[ptr->cntr++],
191 ORTE_PRINT_NAME_ARGS_MAX_SIZE,
192 "[%lu,%lu]", tmp1, tmp2);
193 }
194 return ptr->buffers[ptr->cntr-1];
195 }
196
orte_util_print_job_family(const orte_jobid_t job)197 char* orte_util_print_job_family(const orte_jobid_t job)
198 {
199 orte_print_args_buffers_t *ptr;
200 unsigned long tmp1;
201
202 ptr = get_print_name_buffer();
203
204 if (NULL == ptr) {
205 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
206 return orte_print_args_null;
207 }
208
209 /* cycle around the ring */
210 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
211 ptr->cntr = 0;
212 }
213
214 if (ORTE_JOBID_INVALID == job) {
215 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "INVALID");
216 } else if (ORTE_JOBID_WILDCARD == job) {
217 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "WILDCARD");
218 } else {
219 tmp1 = ORTE_JOB_FAMILY((unsigned long)job);
220 snprintf(ptr->buffers[ptr->cntr++],
221 ORTE_PRINT_NAME_ARGS_MAX_SIZE,
222 "%lu", tmp1);
223 }
224 return ptr->buffers[ptr->cntr-1];
225 }
226
orte_util_print_local_jobid(const orte_jobid_t job)227 char* orte_util_print_local_jobid(const orte_jobid_t job)
228 {
229 orte_print_args_buffers_t *ptr;
230 unsigned long tmp1;
231
232 ptr = get_print_name_buffer();
233
234 if (NULL == ptr) {
235 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
236 return orte_print_args_null;
237 }
238
239 /* cycle around the ring */
240 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
241 ptr->cntr = 0;
242 }
243
244 if (ORTE_JOBID_INVALID == job) {
245 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "INVALID");
246 } else if (ORTE_JOBID_WILDCARD == job) {
247 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "WILDCARD");
248 } else {
249 tmp1 = (unsigned long)job & 0x0000ffff;
250 snprintf(ptr->buffers[ptr->cntr++],
251 ORTE_PRINT_NAME_ARGS_MAX_SIZE,
252 "%lu", tmp1);
253 }
254 return ptr->buffers[ptr->cntr-1];
255 }
256
orte_util_print_vpids(const orte_vpid_t vpid)257 char* orte_util_print_vpids(const orte_vpid_t vpid)
258 {
259 orte_print_args_buffers_t *ptr;
260
261 ptr = get_print_name_buffer();
262
263 if (NULL == ptr) {
264 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
265 return orte_print_args_null;
266 }
267
268 /* cycle around the ring */
269 if (ORTE_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
270 ptr->cntr = 0;
271 }
272
273 if (ORTE_VPID_INVALID == vpid) {
274 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "INVALID");
275 } else if (ORTE_VPID_WILDCARD == vpid) {
276 snprintf(ptr->buffers[ptr->cntr++], ORTE_PRINT_NAME_ARGS_MAX_SIZE, "WILDCARD");
277 } else {
278 snprintf(ptr->buffers[ptr->cntr++],
279 ORTE_PRINT_NAME_ARGS_MAX_SIZE,
280 "%ld", (long)vpid);
281 }
282 return ptr->buffers[ptr->cntr-1];
283 }
284
285
286
287 /*** STRING FUNCTIONS ***/
288
orte_util_snprintf_jobid(char * jobid_string,size_t size,const orte_jobid_t jobid)289 int orte_util_snprintf_jobid(char *jobid_string, size_t size, const orte_jobid_t jobid)
290 {
291 int rc;
292
293 /* check for wildcard value - handle appropriately */
294 if (ORTE_JOBID_WILDCARD == jobid) {
295 (void)strncpy(jobid_string, ORTE_SCHEMA_WILDCARD_STRING, size);
296 } else {
297 rc = snprintf(jobid_string, size, "%ld", (long) jobid);
298 if (0 > rc) {
299 return ORTE_ERROR;
300 }
301 }
302
303 return ORTE_SUCCESS;
304 }
305
orte_util_convert_jobid_to_string(char ** jobid_string,const orte_jobid_t jobid)306 int orte_util_convert_jobid_to_string(char **jobid_string, const orte_jobid_t jobid)
307 {
308 int rc;
309 char str[256];
310 rc = orte_util_snprintf_jobid(str, 255, jobid);
311 if (0 > rc) {
312 *jobid_string = NULL;
313 return rc;
314 }
315 *jobid_string = strdup(str);
316 if (NULL == *jobid_string) {
317 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
318 return ORTE_ERR_OUT_OF_RESOURCE;
319 }
320 return ORTE_SUCCESS;
321 }
322
323
orte_util_convert_string_to_jobid(orte_jobid_t * jobid,const char * jobidstring)324 int orte_util_convert_string_to_jobid(orte_jobid_t *jobid, const char* jobidstring)
325 {
326 if (NULL == jobidstring) { /* got an error */
327 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
328 *jobid = ORTE_JOBID_INVALID;
329 return ORTE_ERR_BAD_PARAM;
330 }
331
332 /** check for wildcard character - handle appropriately */
333 if (0 == strcmp(ORTE_SCHEMA_WILDCARD_STRING, jobidstring)) {
334 *jobid = ORTE_JOBID_WILDCARD;
335 return ORTE_SUCCESS;
336 }
337
338 /* check for invalid value */
339 if (0 == strcmp(ORTE_SCHEMA_INVALID_STRING, jobidstring)) {
340 *jobid = ORTE_JOBID_INVALID;
341 return ORTE_SUCCESS;
342 }
343
344 *jobid = strtoul(jobidstring, NULL, 10);
345
346 return ORTE_SUCCESS;
347 }
348
orte_util_convert_vpid_to_string(char ** vpid_string,const orte_vpid_t vpid)349 int orte_util_convert_vpid_to_string(char **vpid_string, const orte_vpid_t vpid)
350 {
351 /* check for wildcard value - handle appropriately */
352 if (ORTE_VPID_WILDCARD == vpid) {
353 *vpid_string = strdup(ORTE_SCHEMA_WILDCARD_STRING);
354 return ORTE_SUCCESS;
355 }
356
357 /* check for invalid value - handle appropriately */
358 if (ORTE_VPID_INVALID == vpid) {
359 *vpid_string = strdup(ORTE_SCHEMA_INVALID_STRING);
360 return ORTE_SUCCESS;
361 }
362
363 if (0 > asprintf(vpid_string, "%ld", (long) vpid)) {
364 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
365 return ORTE_ERR_OUT_OF_RESOURCE;
366 }
367
368 return ORTE_SUCCESS;
369 }
370
371
orte_util_convert_string_to_vpid(orte_vpid_t * vpid,const char * vpidstring)372 int orte_util_convert_string_to_vpid(orte_vpid_t *vpid, const char* vpidstring)
373 {
374 if (NULL == vpidstring) { /* got an error */
375 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
376 *vpid = ORTE_VPID_INVALID;
377 return ORTE_ERR_BAD_PARAM;
378 }
379
380 /** check for wildcard character - handle appropriately */
381 if (0 == strcmp(ORTE_SCHEMA_WILDCARD_STRING, vpidstring)) {
382 *vpid = ORTE_VPID_WILDCARD;
383 return ORTE_SUCCESS;
384 }
385
386 /* check for invalid value */
387 if (0 == strcmp(ORTE_SCHEMA_INVALID_STRING, vpidstring)) {
388 *vpid = ORTE_VPID_INVALID;
389 return ORTE_SUCCESS;
390 }
391
392 *vpid = strtol(vpidstring, NULL, 10);
393
394 return ORTE_SUCCESS;
395 }
396
orte_util_convert_string_to_process_name(orte_process_name_t * name,const char * name_string)397 int orte_util_convert_string_to_process_name(orte_process_name_t *name,
398 const char* name_string)
399 {
400 char *temp, *token;
401 orte_jobid_t job;
402 orte_vpid_t vpid;
403 int return_code=ORTE_SUCCESS;
404
405 /* set default */
406 name->jobid = ORTE_JOBID_INVALID;
407 name->vpid = ORTE_VPID_INVALID;
408
409 /* check for NULL string - error */
410 if (NULL == name_string) {
411 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
412 return ORTE_ERR_BAD_PARAM;
413 }
414
415 temp = strdup(name_string); /** copy input string as the strtok process is destructive */
416 token = strchr(temp, ORTE_SCHEMA_DELIMITER_CHAR); /** get first field -> jobid */
417
418 /* check for error */
419 if (NULL == token) {
420 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
421 free(temp);
422 return ORTE_ERR_BAD_PARAM;
423 }
424 *token = '\0';
425 token++;
426
427 /* check for WILDCARD character - assign
428 * value accordingly, if found
429 */
430 if (0 == strcmp(temp, ORTE_SCHEMA_WILDCARD_STRING)) {
431 job = ORTE_JOBID_WILDCARD;
432 } else if (0 == strcmp(temp, ORTE_SCHEMA_INVALID_STRING)) {
433 job = ORTE_JOBID_INVALID;
434 } else {
435 job = strtoul(temp, NULL, 10);
436 }
437
438 /* check for WILDCARD character - assign
439 * value accordingly, if found
440 */
441 if (0 == strcmp(token, ORTE_SCHEMA_WILDCARD_STRING)) {
442 vpid = ORTE_VPID_WILDCARD;
443 } else if (0 == strcmp(token, ORTE_SCHEMA_INVALID_STRING)) {
444 vpid = ORTE_VPID_INVALID;
445 } else {
446 vpid = strtoul(token, NULL, 10);
447 }
448
449 name->jobid = job;
450 name->vpid = vpid;
451
452 free(temp);
453
454 return return_code;
455 }
456
orte_util_convert_process_name_to_string(char ** name_string,const orte_process_name_t * name)457 int orte_util_convert_process_name_to_string(char **name_string,
458 const orte_process_name_t* name)
459 {
460 char *tmp, *tmp2;
461
462 if (NULL == name) { /* got an error */
463 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
464 return ORTE_ERR_BAD_PARAM;
465 }
466
467 /* check for wildcard and invalid values - where encountered, insert the
468 * corresponding string so we can correctly parse the name string when
469 * it is passed back to us later
470 */
471 if (ORTE_JOBID_WILDCARD == name->jobid) {
472 asprintf(&tmp, "%s", ORTE_SCHEMA_WILDCARD_STRING);
473 } else if (ORTE_JOBID_INVALID == name->jobid) {
474 asprintf(&tmp, "%s", ORTE_SCHEMA_INVALID_STRING);
475 } else {
476 asprintf(&tmp, "%lu", (unsigned long)name->jobid);
477 }
478
479 if (ORTE_VPID_WILDCARD == name->vpid) {
480 asprintf(&tmp2, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, ORTE_SCHEMA_WILDCARD_STRING);
481 } else if (ORTE_VPID_INVALID == name->vpid) {
482 asprintf(&tmp2, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, ORTE_SCHEMA_INVALID_STRING);
483 } else {
484 asprintf(&tmp2, "%s%c%lu", tmp, ORTE_SCHEMA_DELIMITER_CHAR, (unsigned long)name->vpid);
485 }
486
487 asprintf(name_string, "%s", tmp2);
488
489 free(tmp);
490 free(tmp2);
491
492 return ORTE_SUCCESS;
493 }
494
495
496 /**** CREATE PROCESS NAME ****/
orte_util_create_process_name(orte_process_name_t ** name,orte_jobid_t job,orte_vpid_t vpid)497 int orte_util_create_process_name(orte_process_name_t **name,
498 orte_jobid_t job,
499 orte_vpid_t vpid
500 )
501 {
502 *name = NULL;
503
504 *name = (orte_process_name_t*)malloc(sizeof(orte_process_name_t));
505 if (NULL == *name) { /* got an error */
506 ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
507 return ORTE_ERR_OUT_OF_RESOURCE;
508 }
509
510 (*name)->jobid = job;
511 (*name)->vpid = vpid;
512
513 return ORTE_SUCCESS;
514 }
515
516 /**** COMPARE NAME FIELDS ****/
orte_util_compare_name_fields(orte_ns_cmp_bitmask_t fields,const orte_process_name_t * name1,const orte_process_name_t * name2)517 int orte_util_compare_name_fields(orte_ns_cmp_bitmask_t fields,
518 const orte_process_name_t* name1,
519 const orte_process_name_t* name2)
520 {
521 /* handle the NULL pointer case */
522 if (NULL == name1 && NULL == name2) {
523 return OPAL_EQUAL;
524 } else if (NULL == name1) {
525 return OPAL_VALUE2_GREATER;
526 } else if (NULL == name2) {
527 return OPAL_VALUE1_GREATER;
528 }
529
530 /* in this comparison function, we check for exact equalities.
531 * In the case of wildcards, we check to ensure that the fields
532 * actually match those values - thus, a "wildcard" in this
533 * function does not actually stand for a wildcard value, but
534 * rather a specific value - UNLESS the CMP_WILD bitmask value
535 * is set
536 */
537
538 /* check job id */
539 if (ORTE_NS_CMP_JOBID & fields) {
540 if (ORTE_NS_CMP_WILD & fields &&
541 (ORTE_JOBID_WILDCARD == name1->jobid ||
542 ORTE_JOBID_WILDCARD == name2->jobid)) {
543 goto check_vpid;
544 }
545 if (name1->jobid < name2->jobid) {
546 return OPAL_VALUE2_GREATER;
547 } else if (name1->jobid > name2->jobid) {
548 return OPAL_VALUE1_GREATER;
549 }
550 }
551
552 /* get here if jobid's are equal, or not being checked
553 * now check vpid
554 */
555 check_vpid:
556 if (ORTE_NS_CMP_VPID & fields) {
557 if (ORTE_NS_CMP_WILD & fields &&
558 (ORTE_VPID_WILDCARD == name1->vpid ||
559 ORTE_VPID_WILDCARD == name2->vpid)) {
560 return OPAL_EQUAL;
561 }
562 if (name1->vpid < name2->vpid) {
563 return OPAL_VALUE2_GREATER;
564 } else if (name1->vpid > name2->vpid) {
565 return OPAL_VALUE1_GREATER;
566 }
567 }
568
569 /* only way to get here is if all fields are being checked and are equal,
570 * or jobid not checked, but vpid equal,
571 * only vpid being checked, and equal
572 * return that fact
573 */
574 return OPAL_EQUAL;
575 }
576
577 /* hash a vpid based on Robert Jenkin's algorithm - note
578 * that the precise values of the constants in the algo are
579 * irrelevant.
580 */
orte_util_hash_vpid(orte_vpid_t vpid)581 uint32_t orte_util_hash_vpid(orte_vpid_t vpid) {
582 uint32_t hash;
583
584 hash = vpid;
585 hash = (hash + 0x7ed55d16) + (hash<<12);
586 hash = (hash ^ 0xc761c23c) ^ (hash>>19);
587 hash = (hash + 0x165667b1) + (hash<<5);
588 hash = (hash + 0xd3a2646c) ^ (hash<<9);
589 hash = (hash + 0xfd7046c5) + (hash<<3);
590 hash = (hash ^ 0xb55a4f09) ^ (hash>>16);
591 return hash;
592 }
593
594 /* sysinfo conversion to and from string */
orte_util_convert_string_to_sysinfo(char ** cpu_type,char ** cpu_model,const char * sysinfo_string)595 int orte_util_convert_string_to_sysinfo(char **cpu_type, char **cpu_model,
596 const char* sysinfo_string)
597 {
598 char *temp, *token;
599 int return_code=ORTE_SUCCESS;
600
601 /* check for NULL string - error */
602 if (NULL == sysinfo_string) {
603 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
604 return ORTE_ERR_BAD_PARAM;
605 }
606
607 temp = strdup(sysinfo_string); /** copy input string as the strtok process is destructive */
608 token = strchr(temp, ORTE_SCHEMA_DELIMITER_CHAR); /** get first field -> cpu_type */
609
610 /* check for error */
611 if (NULL == token) {
612 free(temp);
613 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
614 return ORTE_ERR_BAD_PARAM;
615 }
616 *token = '\0';
617 token++;
618
619 /* If type is a valid string get the value otherwise leave cpu_type untouched.
620 */
621 if (0 != strcmp(temp, ORTE_SCHEMA_INVALID_STRING)) {
622 *cpu_type = strdup(temp);
623 }
624
625 /* If type is a valid string get the value otherwise leave cpu_type untouched.
626 */
627 if (0 != strcmp(token, ORTE_SCHEMA_INVALID_STRING)) {
628 *cpu_model = strdup(token);
629 }
630
631 free(temp);
632
633 return return_code;
634 }
635
orte_util_convert_sysinfo_to_string(char ** sysinfo_string,const char * cpu_type,const char * cpu_model)636 int orte_util_convert_sysinfo_to_string(char **sysinfo_string,
637 const char *cpu_type, const char *cpu_model)
638 {
639 char *tmp;
640
641 /* check for no sysinfo values (like empty cpu_type) - where encountered, insert the
642 * invalid string so we can correctly parse the name string when
643 * it is passed back to us later
644 */
645 if (NULL == cpu_type) {
646 asprintf(&tmp, "%s", ORTE_SCHEMA_INVALID_STRING);
647 } else {
648 asprintf(&tmp, "%s", cpu_type);
649 }
650
651 if (NULL == cpu_model) {
652 asprintf(sysinfo_string, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, ORTE_SCHEMA_INVALID_STRING);
653 } else {
654 asprintf(sysinfo_string, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, cpu_model);
655 }
656 free(tmp);
657 return ORTE_SUCCESS;
658 }
659
orte_pretty_print_timing(int64_t secs,int64_t usecs)660 char *orte_pretty_print_timing(int64_t secs, int64_t usecs)
661 {
662 unsigned long minutes, seconds;
663 float fsecs;
664 char *timestring;
665
666 seconds = secs + (usecs / 1000000l);
667 minutes = seconds / 60l;
668 seconds = seconds % 60l;
669 if (0 == minutes && 0 == seconds) {
670 fsecs = ((float)(secs)*1000000.0 + (float)usecs) / 1000.0;
671 asprintf(×tring, "%8.2f millisecs", fsecs);
672 } else {
673 asprintf(×tring, "%3lu:%02lu min:sec", minutes, seconds);
674 }
675
676 return timestring;
677 }
678
679
680