1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/*
* Copyright (C) by Argonne National Laboratory
* See COPYRIGHT in top-level directory
*/
/*
Define _ISOC99_SOURCE to get snprintf() prototype visible in <stdio.h>
when it is compiled with --enable-stricttest.
*/
#define _ISOC99_SOURCE
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "mpi.h"
#include "connectstuff.h"
/* define FNAME_SIZE slightly less to avoid warnings in snprintf */
#define FNAME_SIZE PATH_MAX - 10
static void printTimeStamp(void)
{
time_t t;
struct tm *ltime;
time(&t);
ltime = localtime(&t);
printf("%04d-%02d-%02d %02d:%02d:%02d: ", 1900 + ltime->tm_year,
ltime->tm_mon, ltime->tm_mday, ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
fflush(stdout);
}
void safeSleep(double seconds)
{
struct timespec sleepAmt = { 0, 0 };
int ret = 0;
sleepAmt.tv_sec = floor(seconds);
sleepAmt.tv_nsec = 1e9 * (seconds - floor(seconds));
ret = nanosleep(&sleepAmt, NULL);
if (ret == -1) {
printf("Safesleep returned early. Sorry\n");
}
}
void printStackTrace()
{
static char cmd[512];
snprintf(cmd, 512, "/bin/sh -c \"/home/eellis/bin/pstack1 %d\"", getpid());
int ret = system(cmd);
assert(ret == 0);
fflush(stdout);
}
void msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printTimeStamp();
vprintf(fmt, ap);
fflush(stdout);
va_end(ap);
}
/*
* You should free the string once you've used it
*/
char *getPortFromFile(const char *fmt, ...)
{
char fname[FNAME_SIZE];
char dirname[PATH_MAX];
char *retPort;
va_list ap;
FILE *fp;
int done = 0;
int count = 0; /* Just used for the NFS sync - not really a count */
retPort = (char *) calloc(MPI_MAX_PORT_NAME + 1, sizeof(char));
va_start(ap, fmt);
vsnprintf(fname, FNAME_SIZE, fmt, ap);
va_end(ap);
srand(getpid());
while (!done) {
count += rand();
fp = fopen(fname, "rt");
if (fp != NULL) {
char *s = fgets(retPort, MPI_MAX_PORT_NAME, fp);
assert(s != NULL);
fclose(fp);
/* ignore bogus tag - assume that the real tag must be longer than 8
* characters */
if (strlen(retPort) >= 8) {
done = 1;
}
}
if (!done) {
int retcode;
safeSleep(0.1);
/* force NFS to update by creating and then deleting a subdirectory. Ouch. */
snprintf(dirname, PATH_MAX, "%s___%d", fname, count);
retcode = mkdir(dirname, 0777);
if (retcode != 0) {
perror("Calling mkdir");
_exit(9);
} else {
rmdir(dirname);
}
}
}
return retPort;
}
/*
* Returns the filename written to. Free this once you're done.
*/
char *writePortToFile(const char *port, const char *fmt, ...)
{
char *fname;
va_list ap;
FILE *fp;
fname = (char *) calloc(PATH_MAX, sizeof(char));
va_start(ap, fmt);
vsnprintf(fname, PATH_MAX, fmt, ap);
va_end(ap);
fp = fopen(fname, "wt");
fprintf(fp, "%s\n", port);
fclose(fp);
msg("Wrote port <%s> to file <%s>\n", port, fname);
return fname;
}
|