Blame test/mpi/manual/tcutil.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *  (C) 2008 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
/*
Packit 0848f5
   Define _ISOC99_SOURCE to get snprintf() prototype visible in <stdio.h>
Packit 0848f5
   when it is compiled with --enable-stricttest.
Packit 0848f5
*/
Packit 0848f5
#define _ISOC99_SOURCE
Packit 0848f5
Packit 0848f5
#include <sys/stat.h>
Packit 0848f5
#include <sys/types.h>
Packit 0848f5
#include <unistd.h>
Packit 0848f5
#include <stdio.h>
Packit 0848f5
#include <math.h>
Packit 0848f5
#include <limits.h>
Packit 0848f5
#include <stdarg.h>
Packit 0848f5
#include <stdlib.h>
Packit 0848f5
#include <string.h>
Packit 0848f5
#include <time.h>
Packit 0848f5
#include "mpi.h"
Packit 0848f5
Packit 0848f5
#include "connectstuff.h"
Packit 0848f5
Packit 0848f5
static void printTimeStamp(void)
Packit 0848f5
{
Packit 0848f5
    time_t t;
Packit 0848f5
    struct tm *ltime;
Packit 0848f5
    time(&t);
Packit 0848f5
    ltime = localtime(&t);
Packit 0848f5
    printf("%04d-%02d-%02d %02d:%02d:%02d: ", 1900 + ltime->tm_year,
Packit 0848f5
           ltime->tm_mon, ltime->tm_mday, ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
Packit 0848f5
    fflush(stdout);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
void safeSleep(double seconds)
Packit 0848f5
{
Packit 0848f5
    struct timespec sleepAmt = { 0, 0 };
Packit 0848f5
    int ret = 0;
Packit 0848f5
    sleepAmt.tv_sec = floor(seconds);
Packit 0848f5
    sleepAmt.tv_nsec = 1e9 * (seconds - floor(seconds));
Packit 0848f5
    ret = nanosleep(&sleepAmt, NULL);
Packit 0848f5
    if (ret == -1) {
Packit 0848f5
        printf("Safesleep returned early. Sorry\n");
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
void printStackTrace()
Packit 0848f5
{
Packit 0848f5
    static char cmd[512];
Packit 0848f5
    int ierr;
Packit 0848f5
    snprintf(cmd, 512, "/bin/sh -c \"/home/eellis/bin/pstack1 %d\"", getpid());
Packit 0848f5
    ierr = system(cmd);
Packit 0848f5
    fflush(stdout);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
void msg(const char *fmt, ...)
Packit 0848f5
{
Packit 0848f5
    va_list ap;
Packit 0848f5
    va_start(ap, fmt);
Packit 0848f5
    printTimeStamp();
Packit 0848f5
    vprintf(fmt, ap);
Packit 0848f5
    fflush(stdout);
Packit 0848f5
    va_end(ap);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
/*
Packit 0848f5
 * You should free the string once you've used it
Packit 0848f5
 */
Packit 0848f5
char *getPortFromFile(const char *fmt, ...)
Packit 0848f5
{
Packit 0848f5
    char fname[PATH_MAX];
Packit 0848f5
    char dirname[PATH_MAX];
Packit 0848f5
    char *retPort;
Packit 0848f5
    char *cerr;
Packit 0848f5
    va_list ap;
Packit 0848f5
    FILE *fp;
Packit 0848f5
    int done = 0;
Packit 0848f5
    int count = 0;              /* Just used for the NFS sync - not really a count */
Packit 0848f5
Packit 0848f5
    retPort = (char *) calloc(MPI_MAX_PORT_NAME + 1, sizeof(char));
Packit 0848f5
Packit 0848f5
    va_start(ap, fmt);
Packit 0848f5
    vsnprintf(fname, PATH_MAX, fmt, ap);
Packit 0848f5
    va_end(ap);
Packit 0848f5
Packit 0848f5
    srand(getpid());
Packit 0848f5
Packit 0848f5
    while (!done) {
Packit 0848f5
        count += rand();
Packit 0848f5
        fp = fopen(fname, "rt");
Packit 0848f5
        if (fp != NULL) {
Packit 0848f5
            cerr = fgets(retPort, MPI_MAX_PORT_NAME, fp);
Packit 0848f5
            fclose(fp);
Packit 0848f5
            /* ignore bogus tag - assume that the real tag must be longer than 8
Packit 0848f5
             * characters */
Packit 0848f5
            if (strlen(retPort) >= 8) {
Packit 0848f5
                done = 1;
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
        if (!done) {
Packit 0848f5
            int retcode;
Packit 0848f5
            safeSleep(0.1);
Packit 0848f5
            /* force NFS to update by creating and then deleting a subdirectory. Ouch. */
Packit 0848f5
            snprintf(dirname, PATH_MAX, "%s___%d", fname, count);
Packit 0848f5
            retcode = mkdir(dirname, 0777);
Packit 0848f5
            if (retcode != 0) {
Packit 0848f5
                perror("Calling mkdir");
Packit 0848f5
                _exit(9);
Packit 0848f5
            }
Packit 0848f5
            else {
Packit 0848f5
                rmdir(dirname);
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
    return retPort;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
/*
Packit 0848f5
 * Returns the filename written to. Free this once you're done.
Packit 0848f5
 */
Packit 0848f5
char *writePortToFile(const char *port, const char *fmt, ...)
Packit 0848f5
{
Packit 0848f5
    char *fname;
Packit 0848f5
    va_list ap;
Packit 0848f5
    FILE *fp;
Packit 0848f5
Packit 0848f5
    fname = (char *) calloc(PATH_MAX, sizeof(char));
Packit 0848f5
Packit 0848f5
    va_start(ap, fmt);
Packit 0848f5
    vsnprintf(fname, PATH_MAX, fmt, ap);
Packit 0848f5
    va_end(ap);
Packit 0848f5
Packit 0848f5
    fp = fopen(fname, "wt");
Packit 0848f5
    fprintf(fp, "%s\n", port);
Packit 0848f5
    fclose(fp);
Packit 0848f5
Packit 0848f5
    msg("Wrote port <%s> to file <%s>\n", port, fname);
Packit 0848f5
    return fname;
Packit 0848f5
}