Since I'm vanishing for a few weeks, a smattering of code from FTMPI
for possible consideration... This commit was SVN r2245.
Этот коммит содержится в:
родитель
b1ff3e50c2
Коммит
242f062386
16
src/mca/service/stdio/Makefile
Обычный файл
16
src/mca/service/stdio/Makefile
Обычный файл
@ -0,0 +1,16 @@
|
||||
SNL_OBJECTS = ./snipe_lite/msg.c \
|
||||
./snipe_lite/msgbuf2.c \
|
||||
./snipe_lite/memory.c \
|
||||
./snipe_lite/syslog.c \
|
||||
./snipe_lite/snipe_lite.c
|
||||
|
||||
all : sioapp cioapp
|
||||
|
||||
sioapp : sioapp.c
|
||||
gcc -o sioapp sioapp.c libsio.c $(SNL_OBJECTS) -I./snipe_lite
|
||||
|
||||
cioapp : cioapp.c
|
||||
gcc -o cioapp cioapp.c libcio.c $(SNL_OBJECTS) -I./snipe_lite
|
||||
|
||||
clean :
|
||||
rm -f *.o sioapp cioapp
|
96
src/mca/service/stdio/README
Обычный файл
96
src/mca/service/stdio/README
Обычный файл
@ -0,0 +1,96 @@
|
||||
This should be in a design document but....
|
||||
|
||||
Random thoughts on stdio redirection.
|
||||
|
||||
- stdin redirection should be buffered (i.e. fragment-based). stdin
|
||||
should go to process 0. Any need to broadcast stdin?
|
||||
- stdout/stderr also buffered. Fragment headers: to indicate origin,
|
||||
and to handle out of order delivery in future distributed situations.
|
||||
- pipes or ptys from ompid to processes. Fairly portable pty code is
|
||||
in src/util/pty.c. Goal: wrap up selection of pipes vs ptys in a
|
||||
transparent fashion for easy selection at compile- or run-time (MCA
|
||||
parameter-based I guess). Note ptys are typically necessary when stdin
|
||||
is a tty so that interactive input is possible.
|
||||
- stdin redirection: base this on LA-MPI's rts/cts fragment-based
|
||||
approach.
|
||||
- Consider basing ompid -> mpirun stdout/stderr redirection on FTMPI
|
||||
libcio/sio ported to use oob framework (tcp component for non-blocking
|
||||
operation).
|
||||
|
||||
|
||||
|
||||
In this directory:
|
||||
|
||||
libcio/sio are the client and server parts of the FTMPI stdout and
|
||||
stderr I/O forwarding.
|
||||
|
||||
snipe_lite is a close analog of our OOB
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Explanatory email from Thara:
|
||||
|
||||
From: angskun@cs.utk.edu
|
||||
Subject: Re: libsio, libcio
|
||||
Date: August 13, 2004 13:11:14 MDT
|
||||
To: ddd@lanl.gov
|
||||
Cc: fagg@cs.utk.edu
|
||||
|
||||
Dear David,
|
||||
|
||||
Everything in snipe_lite directory is for basic connection management
|
||||
in FT-MPI. The libcio/sio use the snipe_lite for communication.
|
||||
You may replace it with socket or OpenMPI communication library.
|
||||
|
||||
cioapp.c : client/console/ application example
|
||||
sioapp.c : server/daemon application example
|
||||
libcio.*, libsio.* : the library and include file
|
||||
|
||||
Example:
|
||||
*** client/console machine ***
|
||||
[angskun@torc0 ~/ioapp]$ ./cioapp 3
|
||||
Port is 6781
|
||||
[0:stdout] Hi world, my name is foo 1/5 [bar code is 0 (pid 19409)]
|
||||
Hi world, my name is foo 2/5 [bar code is 0 (pid 19409)]
|
||||
Hi world, my name is foo 3/5 [bar code is 0 (pid 19409)]
|
||||
Hi world, my name is foo 4/5 [bar code is 0 (pid 19409)]
|
||||
Hi world, my name is foo 5/5 [bar code is 0 (pid 19409)]
|
||||
[1:stdout] Hi world, my name is foo 1/5 [bar code is 1 (pid 19410)]
|
||||
Hi world, my name is foo 2/5 [bar code is 1 (pid 19410)]
|
||||
Hi world, my name is foo 3/5 [bar code is 1 (pid 19410)]
|
||||
Hi world, my name is foo 4/5 [bar code is 1 (pid 19410)]
|
||||
Hi world, my name is foo 5/5 [bar code is 1 (pid 19410)]
|
||||
[2:stdout] Hi world, my name is foo 1/5 [bar code is 2 (pid 19411)]
|
||||
Hi world, my name is foo 2/5 [bar code is 2 (pid 19411)]
|
||||
Hi world, my name is foo 3/5 [bar code is 2 (pid 19411)]
|
||||
Hi world, my name is foo 4/5 [bar code is 2 (pid 19411)]
|
||||
Hi world, my name is foo 5/5 [bar code is 2 (pid 19411)]
|
||||
[angskun@torc0 ~/ioapp]$
|
||||
|
||||
*** server / daemon machine ***
|
||||
$./sioapp torc0 6781 3
|
||||
|
||||
Best Regards,
|
||||
Thara
|
||||
|
||||
----- Original Message -----
|
||||
From: "David Daniel" <ddd@lanl.gov>
|
||||
To: "THara Angskun" <angskun@cs.utk.edu>
|
||||
Cc: "Graham E Fagg" <fagg@cs.utk.edu>
|
||||
Sent: Friday, August 13, 2004 2:09 PM
|
||||
Subject: libsio, libcio
|
||||
|
||||
Thara
|
||||
|
||||
I'm looking at using libcio/sio as a starting point for standard I/O
|
||||
redirection in Open MPI.
|
||||
|
||||
Graham mentioned that you had some tests for testing them on their own.
|
||||
If you could let me have a copy that would be very helpful.
|
||||
|
||||
Thanks, David
|
||||
--
|
||||
David Daniel <ddd@lanl.gov> +1-505-667-0883
|
||||
Advanced Computing Laboratory, LANL, MS-B287, Los Alamos NM 87545, USA
|
55
src/mca/service/stdio/cioapp.c
Обычный файл
55
src/mca/service/stdio/cioapp.c
Обычный файл
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
#define TIMEOUT 500
|
||||
#define SERV_PORT 6780
|
||||
|
||||
|
||||
int setupContactPoint(int *port)
|
||||
{
|
||||
int listenfd, rc;
|
||||
struct sockaddr_in servaddr;
|
||||
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
(*port) = SERV_PORT;
|
||||
servaddr.sin_port = htons((*port));
|
||||
while((rc=bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))!=0) {
|
||||
servaddr.sin_port = htons(++(*port));
|
||||
}
|
||||
listen(listenfd, 5);
|
||||
return listenfd;
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
int port,listenfd;
|
||||
int number_of_server_child=0;
|
||||
int n_child;
|
||||
int ret;
|
||||
|
||||
if(argc!=2) {
|
||||
printf("%s <#of server's child process>\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
listenfd=setupContactPoint(&port);
|
||||
n_child=atoi(argv[1]);
|
||||
printf("Port is %d\n",port);
|
||||
|
||||
rioc_init(listenfd, 0);
|
||||
ret=rioc_poll(TIMEOUT,&number_of_server_child);
|
||||
while(ret!=0 || number_of_server_child != n_child) {
|
||||
ret=rioc_poll(TIMEOUT,&number_of_server_child);
|
||||
}
|
||||
}
|
296
src/mca/service/stdio/libcio.c
Обычный файл
296
src/mca/service/stdio/libcio.c
Обычный файл
@ -0,0 +1,296 @@
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
HARNESS FT_MPI
|
||||
HARNESS FTMPI_NOTIFIER
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
THara Angskun <angskun@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#include "libcio.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int rioc_pair[RIO_MAXFD];
|
||||
static int c_num_pair;
|
||||
static int main_fd;
|
||||
|
||||
/* rioc_init - initialize data structure
|
||||
@param fd file descriptor
|
||||
@block block flag (1== block,0==nonblock)
|
||||
*/
|
||||
int rioc_init(int fd,int block)
|
||||
{
|
||||
int i,s;
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
rioc_pair[i]=-1;
|
||||
}
|
||||
c_num_pair = 0;
|
||||
main_fd = fd;
|
||||
rioc_register_socket(fd);
|
||||
if(block) {
|
||||
s = allowconn (main_fd, 0, NULL);
|
||||
rioc_register_socket(s);
|
||||
}
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rioc_stop - clean up data structure
|
||||
*/
|
||||
int rioc_stop(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
if(c_num_pair==0) break;
|
||||
if(rioc_pair[i]!=-1) {
|
||||
closeconn(i);
|
||||
rioc_pair[i]=-1;
|
||||
c_num_pair--;
|
||||
}
|
||||
}
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rioc_register_pipe2_socket - Register I/O
|
||||
@param src_fd source file descriptor
|
||||
@param dest_fd destination file descriptor
|
||||
*/
|
||||
int rioc_register_socket(int fd)
|
||||
{
|
||||
if(fd==main_fd) {
|
||||
rioc_pair[fd]=0;
|
||||
} else {
|
||||
rioc_pair[fd]=1;
|
||||
}
|
||||
c_num_pair++;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rioc_pollinit - init poll call every time if number of pair has been changed
|
||||
@param poll_fd poll file descriptor list.
|
||||
*/
|
||||
int rioc_pollinit(struct pollfd **poll_fd)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
#ifndef WIN32
|
||||
if((*poll_fd)!=NULL) {
|
||||
_FREE(*poll_fd);
|
||||
}
|
||||
j=0;
|
||||
(*poll_fd)=(struct pollfd *)_MALLOC(sizeof(struct pollfd)*c_num_pair);
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
if(rioc_pair[i]!=-1) {
|
||||
(*poll_fd)[j].fd=i;
|
||||
(*poll_fd)[j].events = POLLIN;
|
||||
(*poll_fd)[j].revents = 0;
|
||||
j++;
|
||||
}
|
||||
if(j>=c_num_pair) break;
|
||||
}
|
||||
#endif
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rioc_poll - startup I/O redirection (NOTE: This function return only no valid pair of src/dest left or timeout)
|
||||
@param timeout timeout (-1 for infinity)
|
||||
@return number of connection left before timeout
|
||||
*/
|
||||
int rioc_poll(int timeout, int *ncon)
|
||||
{
|
||||
|
||||
int i,count;
|
||||
struct pollfd *poll_fd;
|
||||
struct timeval begin, current;
|
||||
char buf[RIO_MAXBUF];
|
||||
int max_pair;
|
||||
int ret;
|
||||
int s;
|
||||
long diff;
|
||||
int update;
|
||||
int active;
|
||||
|
||||
#ifndef WIN32
|
||||
gettimeofday(&begin,NULL);
|
||||
poll_fd = NULL;
|
||||
rioc_pollinit(&poll_fd);
|
||||
update=0;
|
||||
|
||||
do {
|
||||
gettimeofday(¤t,NULL);
|
||||
diff=(1000000*(current.tv_sec-begin.tv_sec)) + (current.tv_usec-begin.tv_usec);
|
||||
diff=diff/1000; /* millisecond */
|
||||
if(timeout>=0) {
|
||||
if(diff > timeout) {
|
||||
if((poll_fd)!=NULL) {
|
||||
_FREE(poll_fd);
|
||||
}
|
||||
if(c_num_pair!=0) return c_num_pair-1;
|
||||
return c_num_pair;
|
||||
}
|
||||
}
|
||||
|
||||
if((ret=poll(poll_fd, c_num_pair, timeout)) <0) {
|
||||
if((poll_fd)!=NULL) {
|
||||
_FREE(poll_fd);
|
||||
}
|
||||
return RIO_EPOLL;
|
||||
}
|
||||
if(ret==0) { /* time out */
|
||||
if((poll_fd)!=NULL) {
|
||||
_FREE(poll_fd);
|
||||
}
|
||||
if(c_num_pair!=0) return c_num_pair-1;
|
||||
return c_num_pair;
|
||||
}
|
||||
max_pair=c_num_pair; /* we need max_pair because c_num_pair is dynamic value */
|
||||
active=0;
|
||||
for(i=0;i<max_pair;i++) {
|
||||
if(poll_fd[i].revents!=0) {
|
||||
if(poll_fd[i].fd==main_fd) {
|
||||
rioc_pair[main_fd]++;
|
||||
(*ncon)=rioc_pair[main_fd];
|
||||
s = allowconn (main_fd, 0, NULL);
|
||||
rioc_register_socket(s);
|
||||
update=1;
|
||||
} else {
|
||||
count=readmsgconn(poll_fd[i].fd,buf,RIO_MAXBUF);
|
||||
if(count<=0) {
|
||||
close(poll_fd[i].fd);
|
||||
rioc_pair[poll_fd[i].fd]=-1;
|
||||
c_num_pair--;
|
||||
update=1;
|
||||
} else {
|
||||
buf[count]='\0';
|
||||
printf("%s",buf);
|
||||
buf[0]='\0';
|
||||
}
|
||||
}
|
||||
active++;
|
||||
}
|
||||
if(active==ret) break;
|
||||
}
|
||||
/* Don't check if(c_num_pair!=max_pair). because they may add/delete at the same time */
|
||||
if(update==1) {
|
||||
rioc_pollinit(&poll_fd);
|
||||
update=0;
|
||||
}
|
||||
} while(c_num_pair>1);
|
||||
|
||||
/* close(main_fd); */
|
||||
|
||||
if((poll_fd)!=NULL) {
|
||||
_FREE(poll_fd);
|
||||
}
|
||||
|
||||
if(c_num_pair!=0) return c_num_pair-1;
|
||||
#endif
|
||||
return c_num_pair;
|
||||
}
|
||||
|
||||
/* rioc_getoutput
|
||||
@param mainfd main output file descriptor to accept output
|
||||
@param expected_con expected number of connection
|
||||
*/
|
||||
int rioc_getoutput(int mainfd,int expected_con)
|
||||
{
|
||||
fd_set rfds, rfds_bak;
|
||||
int maxfd, minfd, i, ret;
|
||||
int active_con; /* number of active connection */
|
||||
char buf[RIO_MAXBUF];
|
||||
int fd;
|
||||
int updated=0;
|
||||
int curcon=0;
|
||||
int respawn=0;
|
||||
|
||||
#ifndef WIN32
|
||||
FD_ZERO(&rfds_bak);
|
||||
FD_SET(mainfd,&rfds_bak);
|
||||
maxfd=mainfd+1;
|
||||
minfd=mainfd;
|
||||
updated=1;
|
||||
|
||||
while(expected_con > 0) {
|
||||
|
||||
if(updated>0) {
|
||||
FD_ZERO(&rfds);
|
||||
maxfd=0;
|
||||
minfd=0;
|
||||
for(fd=0;fd<FD_SETSIZE;fd++) {
|
||||
if(FD_ISSET(fd,&rfds_bak)) {
|
||||
FD_SET(fd,&rfds);
|
||||
if(fd>=maxfd) maxfd=fd+1;
|
||||
if(fd<minfd) minfd=fd;
|
||||
}
|
||||
}
|
||||
updated=0;
|
||||
}
|
||||
|
||||
active_con = select(maxfd, &rfds, NULL, NULL, NULL);
|
||||
if(active_con <= 0) {
|
||||
return RIO_EPOLL;
|
||||
}
|
||||
i=minfd;
|
||||
while(active_con > 0) {
|
||||
if(FD_ISSET(i,&rfds)) {
|
||||
if(i==mainfd) {
|
||||
ret = allowconn (i, 0, NULL);
|
||||
if(ret>0) {
|
||||
FD_SET(ret,&rfds_bak);
|
||||
updated=1;
|
||||
curcon++;
|
||||
if(curcon>expected_con) {
|
||||
respawn=1;
|
||||
}
|
||||
if(respawn==1) {
|
||||
expected_con++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret=readmsgconn(i,buf,RIO_MAXBUF);
|
||||
if(ret<=0) {
|
||||
close(i);
|
||||
expected_con--;
|
||||
FD_CLR(i,&rfds_bak);
|
||||
updated=1;
|
||||
} else {
|
||||
buf[ret]='\0';
|
||||
printf("%s",buf);
|
||||
buf[0]='\0';
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
active_con--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return RIO_SUCCESS;
|
||||
}
|
68
src/mca/service/stdio/libcio.h
Обычный файл
68
src/mca/service/stdio/libcio.h
Обычный файл
@ -0,0 +1,68 @@
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
HARNESS FT_MPI
|
||||
HARNESS FTMPI_NOTIFIER
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
THara Angskun <angskun@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __RIO_H
|
||||
#define __RIO_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h> /* for FD_SETSIZE */
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/types.h>
|
||||
#include "snipe_lite.h"
|
||||
|
||||
#else
|
||||
#include "../../wincomm/wincomm.h"
|
||||
#endif
|
||||
|
||||
#define RIO_SUCCESS 0
|
||||
#define RIO_EPOLL -1
|
||||
|
||||
#define RIO_MAXFD FD_SETSIZE
|
||||
#define RIO_MAXBUF 8192
|
||||
|
||||
|
||||
|
||||
int rioc_init(int main_fd,int block);
|
||||
int rioc_poll(int timeout,int *ncon);
|
||||
int rioc_register_socket(int fd);
|
||||
int rioc_stop (void);
|
||||
#endif
|
289
src/mca/service/stdio/libsio.c
Обычный файл
289
src/mca/service/stdio/libsio.c
Обычный файл
@ -0,0 +1,289 @@
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
HARNESS FT_MPI
|
||||
HARNESS FTMPI_NOTIFIER
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
THara Angskun <angskun@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#include "libsio.h"
|
||||
#include "debug.h"
|
||||
|
||||
static struct pair rios_pair[RIO_MAXFD];
|
||||
static int s_num_pair;
|
||||
static struct pollfd* ppoll = NULL;
|
||||
static int ppoll_space = 0;
|
||||
|
||||
/* rios_init - initialize data structure
|
||||
*/
|
||||
int rios_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
rios_pair[i].name=NULL;
|
||||
rios_pair[i].sockfd=-1;
|
||||
rios_pair[i].mypair=-1;
|
||||
rios_pair[i].silent=0;
|
||||
}
|
||||
s_num_pair = 0;
|
||||
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_stop - clean up data structure
|
||||
*/
|
||||
int rios_stop(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
if(s_num_pair==0) break;
|
||||
if(rios_pair[i].sockfd!=-1) {
|
||||
close(rios_pair[i].sockfd);
|
||||
close(i);
|
||||
rios_pair[i].sockfd=-1;
|
||||
rios_pair[i].silent=0;
|
||||
if(rios_pair[i].name!=NULL) _FREE(rios_pair[i].name);
|
||||
rios_pair[i].name=NULL;
|
||||
if(rios_pair[i].mypair!=-1) {
|
||||
close(rios_pair[i].mypair);
|
||||
rios_pair[rios_pair[i].mypair].sockfd=-1;
|
||||
rios_pair[rios_pair[i].mypair].silent=0;
|
||||
if(rios_pair[rios_pair[i].mypair].name!=NULL)
|
||||
_FREE(rios_pair[rios_pair[i].mypair].name);
|
||||
rios_pair[rios_pair[i].mypair].name=NULL;
|
||||
s_num_pair--;
|
||||
}
|
||||
s_num_pair--;
|
||||
}
|
||||
}
|
||||
if( ppoll != NULL ) _FREE(ppoll);
|
||||
ppoll_space = 0;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_unregister - unregister
|
||||
@param src_fd source file descriptor
|
||||
*/
|
||||
int rios_unregister(int src_fd)
|
||||
{
|
||||
if(src_fd <0 || src_fd >= RIO_MAXFD || rios_pair[src_fd].sockfd==-1 ) {
|
||||
return RIO_EINVLFD;
|
||||
}
|
||||
close(src_fd);
|
||||
if(rios_pair[src_fd].mypair==-1) {
|
||||
writemsgconn(rios_pair[src_fd].sockfd,"",0); /* tell listener to close connection */
|
||||
close(rios_pair[src_fd].sockfd);
|
||||
} else {
|
||||
rios_pair[rios_pair[src_fd].mypair].mypair=-1;
|
||||
rios_pair[src_fd].mypair=-1;
|
||||
}
|
||||
rios_pair[src_fd].sockfd=-1;
|
||||
rios_pair[src_fd].silent=0; /* reset it to normal */
|
||||
if(rios_pair[src_fd].name!=NULL) _FREE(rios_pair[src_fd].name);
|
||||
rios_pair[src_fd].name=NULL;
|
||||
s_num_pair--;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_register_dup
|
||||
@param template_fd
|
||||
@param my_fd
|
||||
@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up)
|
||||
*/
|
||||
int rios_register_dup(char *name,int template_fd,int my_fd, int silent)
|
||||
{
|
||||
if(template_fd <0 || template_fd >= RIO_MAXFD || rios_pair[template_fd].sockfd == -1 || my_fd < 0 || my_fd >= RIO_MAXFD) {
|
||||
return RIO_EINVLFD;
|
||||
}
|
||||
rios_pair[my_fd].sockfd=rios_pair[template_fd].sockfd;
|
||||
rios_pair[my_fd].mypair=template_fd;
|
||||
rios_pair[template_fd].mypair=my_fd;
|
||||
if(name!=NULL) {
|
||||
rios_pair[my_fd].name=_MALLOC(sizeof(char)*(strlen(name)+1));
|
||||
strcpy(rios_pair[my_fd].name,name);
|
||||
}
|
||||
rios_pair[my_fd].silent=silent;
|
||||
s_num_pair++;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_register_pipe2_socket - Register I/O
|
||||
@param src_fd source file descriptor
|
||||
@param dest_fd destination file descriptor
|
||||
@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up)
|
||||
*/
|
||||
int rios_register_pipe2_socket(char *name,int src_fd,int dest_fd, int silent)
|
||||
{
|
||||
if(src_fd <0 || src_fd >= RIO_MAXFD || dest_fd < 0 || dest_fd >= RIO_MAXFD) {
|
||||
return RIO_EINVLFD;
|
||||
}
|
||||
rios_pair[src_fd].sockfd=dest_fd;
|
||||
if(name!=NULL) {
|
||||
rios_pair[src_fd].name=_MALLOC(sizeof(char)*(strlen(name)+1));
|
||||
strcpy(rios_pair[src_fd].name,name);
|
||||
}
|
||||
rios_pair[src_fd].silent=silent;
|
||||
s_num_pair++;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_register_pipe2_host_port - Register I/O
|
||||
@param src_fd source file descriptor
|
||||
@param host hostname
|
||||
@param port port
|
||||
@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up)
|
||||
*/
|
||||
int rios_register_pipe2_host_port(char *name,int src_fd,char *host,int port, int silent)
|
||||
{
|
||||
int dest_fd;
|
||||
dest_fd = getconn (host, &port, 10); /* search a range of 10 */
|
||||
if(dest_fd<0) {
|
||||
return RIO_EINVLFD;
|
||||
}
|
||||
return rios_register_pipe2_socket(name,src_fd,dest_fd,silent);
|
||||
}
|
||||
|
||||
/* rios_register_pipe2_addr_port - Register I/O
|
||||
@param src_fd source file descriptor
|
||||
@param addr address
|
||||
@param port port
|
||||
*/
|
||||
int rios_register_pipe2_addr_port(char *name,int src_fd,long addr,int port, int silent)
|
||||
{
|
||||
int dest_fd;
|
||||
dest_fd = getconn_addr (addr, &port, 10); /* search a range of 10 */
|
||||
if(dest_fd<0) {
|
||||
return RIO_EINVLFD;
|
||||
}
|
||||
return rios_register_pipe2_socket(name,src_fd,dest_fd,silent);
|
||||
}
|
||||
|
||||
/* rios_pollinit - init poll call every time if number of pair has been changed
|
||||
@param poll_fd poll file descriptor list.
|
||||
@param free_me free pollfd
|
||||
*/
|
||||
int rios_pollinit(struct pollfd **poll_fd,int free_me)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
*poll_fd = NULL;
|
||||
if(s_num_pair <= 0 ) return RIO_EINVLPAIR;
|
||||
|
||||
if( ppoll_space < s_num_pair ) {
|
||||
if( ppoll != NULL ) _FREE( ppoll );
|
||||
ppoll_space = s_num_pair + (s_num_pair >> 1);
|
||||
ppoll = (struct pollfd*)_MALLOC( sizeof(struct pollfd) * ppoll_space );
|
||||
}
|
||||
j=0;
|
||||
for(i=0;i<RIO_MAXFD;i++) {
|
||||
if(rios_pair[i].sockfd!=-1) {
|
||||
ppoll[j].fd=i;
|
||||
ppoll[j].events = POLLIN;
|
||||
ppoll[j].revents = 0;
|
||||
j++;
|
||||
}
|
||||
if(j>=s_num_pair) break;
|
||||
}
|
||||
*poll_fd = ppoll;
|
||||
return RIO_SUCCESS;
|
||||
}
|
||||
|
||||
/* rios_poll - startup I/O redirection (NOTE: This function return only no valid pair of src/dest left or timeout)
|
||||
@param timeout timeout (-1 for infinity)
|
||||
@return number of connection left before timeout
|
||||
*/
|
||||
int rios_poll(int timeout)
|
||||
{
|
||||
|
||||
int i,count;
|
||||
struct pollfd *poll_fd;
|
||||
struct timeval begin, current;
|
||||
char buf[RIO_MAXBUF];
|
||||
char tmpbuf[RIO_MAXBUF+500];
|
||||
int max_pair;
|
||||
int ret;
|
||||
long diff;
|
||||
|
||||
gettimeofday(&begin,NULL);
|
||||
poll_fd = NULL;
|
||||
ret=rios_pollinit(&poll_fd,0);
|
||||
if(ret<0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
while(s_num_pair>0) {
|
||||
gettimeofday(¤t,NULL);
|
||||
diff=(1000000*(current.tv_sec-begin.tv_sec)) + (current.tv_usec-begin.tv_usec);
|
||||
diff=diff/1000; /* millisecond */
|
||||
if(diff > timeout) {
|
||||
return s_num_pair;
|
||||
}
|
||||
|
||||
if((ret=poll(poll_fd, s_num_pair, timeout)) <0) {
|
||||
return RIO_EPOLL;
|
||||
}
|
||||
if(ret==0) { /* time out */
|
||||
return s_num_pair;
|
||||
}
|
||||
max_pair=s_num_pair; /* we need max_pair because s_num_pair is dynamic value */
|
||||
for(i=0;i<max_pair;i++) {
|
||||
if(poll_fd[i].revents!=0) {
|
||||
if( poll_fd[i].revents & POLLERR ) {
|
||||
rios_unregister( poll_fd[i].fd );
|
||||
} else {
|
||||
count=read(poll_fd[i].fd,buf,RIO_MAXBUF);
|
||||
if( count <= 0 ) {
|
||||
rios_unregister(poll_fd[i].fd);
|
||||
} else {
|
||||
buf[count]='\0';
|
||||
if (rios_pair[poll_fd[i].fd].silent==1) { /* shut up */
|
||||
sprintf(tmpbuf,"%s",buf);
|
||||
} else { /* shut down, ... I mean normal */
|
||||
sprintf(tmpbuf,"[%s] %s",rios_pair[poll_fd[i].fd].name,buf);
|
||||
}
|
||||
ret=writemsgconn(rios_pair[poll_fd[i].fd].sockfd,tmpbuf,strlen(tmpbuf));
|
||||
if(ret!=strlen(tmpbuf)) {
|
||||
rios_unregister(poll_fd[i].fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(s_num_pair!=max_pair) { /* someone close connection */
|
||||
ret=rios_pollinit(&poll_fd,1);
|
||||
if(ret<0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RIO_SUCCESS;
|
||||
}
|
74
src/mca/service/stdio/libsio.h
Обычный файл
74
src/mca/service/stdio/libsio.h
Обычный файл
@ -0,0 +1,74 @@
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
HARNESS FT_MPI
|
||||
HARNESS FTMPI_NOTIFIER
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
THara Angskun <angskun@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __RIO_H
|
||||
#define __RIO_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h> /* for FD_SETSIZE */
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include "snipe_lite.h"
|
||||
|
||||
#define RIO_SUCCESS 0
|
||||
#define RIO_EPOLL -1
|
||||
#define RIO_EINVLFD -2
|
||||
#define RIO_EINVLPAIR -3
|
||||
|
||||
#define RIO_MAXFD FD_SETSIZE
|
||||
#define RIO_MAXBUF 8192
|
||||
|
||||
struct pair {
|
||||
char *name;
|
||||
int sockfd;
|
||||
int mypair;
|
||||
int silent; /* -1 = yell, 0 = normal, 1= shut up. */
|
||||
};
|
||||
|
||||
int rios_init(void);
|
||||
int rios_poll(int timeout);
|
||||
int rios_register_pipe2_socket(char *name,int srcfd,int destfd,int silent);
|
||||
int rios_register_pipe2_host_port(char *name,int srcfd, char* host, int port, int silent);
|
||||
int rios_register_pipe2_addr_port(char *name,int srcfd, long addr, int port, int silent);
|
||||
int rios_register_dup(char *name,int template_fd,int my_fd, int silent);
|
||||
int rios_unregister(int srcfd);
|
||||
int rios_stop (void);
|
||||
#endif
|
81
src/mca/service/stdio/sioapp.c
Обычный файл
81
src/mca/service/stdio/sioapp.c
Обычный файл
@ -0,0 +1,81 @@
|
||||
#include <stdio.h>
|
||||
#include "libsio.h"
|
||||
|
||||
#define TIMEOUT 500
|
||||
|
||||
/*
|
||||
This file is an example for application that use libsio
|
||||
It simply create numbers of processes and sent their output to
|
||||
speicify host and port
|
||||
*/
|
||||
|
||||
struct rio {
|
||||
int pid;
|
||||
int pp[2]; /* stdout */
|
||||
int pp2[2]; /* stderr */
|
||||
} *rios;
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
|
||||
int nchild, ret;
|
||||
int entry=0;
|
||||
char cioapp_host[256];
|
||||
char buf[256];
|
||||
int cioapp_port;
|
||||
int startup_silent=0; /* 1=silent, 0= verbose */
|
||||
int pid,k;
|
||||
|
||||
if(argc!=4) {
|
||||
printf("%s <cioapp_hostname> <cioapp_port> <#of child processes>\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
strcpy(cioapp_host,argv[1]);
|
||||
cioapp_port=atoi(argv[2]);
|
||||
nchild=atoi(argv[3]);
|
||||
if(nchild <1) {
|
||||
printf("#of child must be more than 1\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rios_init();
|
||||
rios=(struct rio *)malloc(sizeof(struct rio)*nchild);
|
||||
|
||||
for(entry=0;entry<nchild;entry++) {
|
||||
if (pipe(rios[entry].pp) == -1) perror("pipe");
|
||||
if (pipe(rios[entry].pp2) == -1) perror("pipe");
|
||||
|
||||
sprintf(buf,"%d:stdout",entry);
|
||||
ret=rios_register_pipe2_host_port(buf,rios[entry].pp[0],cioapp_host,cioapp_port,startup_silent);
|
||||
|
||||
if(ret!=RIO_SUCCESS) printf("Cannot connect to %s:%d ret %d\n",cioapp_host,cioapp_port,ret);
|
||||
|
||||
sprintf(buf,"%d:stderr",entry);
|
||||
ret=rios_register_dup(buf,rios[entry].pp[0],rios[entry].pp2[0],startup_silent);
|
||||
if(ret!=RIO_SUCCESS) printf("Cannot duplicate destination for stderr (ret=%d)\n",ret);
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == 0) {
|
||||
dup2(rios[entry].pp[1],1);
|
||||
dup2(rios[entry].pp2[1],2);
|
||||
for(k=0;k<5;k++) {
|
||||
printf("Hi world, my name is foo %d/%d [bar code is %d (pid %d)]\n",k+1,5,entry,getpid());
|
||||
sleep(1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
rios[entry].pid=pid;
|
||||
close(rios[entry].pp[1]);
|
||||
close(rios[entry].pp2[1]);
|
||||
rios[entry].pp[1] = -1;
|
||||
rios[entry].pp2[1] = -1;
|
||||
}
|
||||
|
||||
/* Now, parent poll for child stdout/err */
|
||||
while(1) {
|
||||
rios_poll(TIMEOUT);
|
||||
}
|
||||
return 0;
|
||||
}
|
58
src/mca/service/stdio/snipe_lite/debug.h
Обычный файл
58
src/mca/service/stdio/snipe_lite/debug.h
Обычный файл
@ -0,0 +1,58 @@
|
||||
#ifndef DEBUG_H_HAS_BEEN_INCLUDED
|
||||
#define DEBUG_H_HAS_BEEN_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef HAVE_ALLOCA
|
||||
# ifndef __GNUC__
|
||||
# ifdef _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# else
|
||||
# ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif /* _AIX */
|
||||
# endif /* HAVE_ALLOCA_H */
|
||||
# endif /* _MSC_VER */
|
||||
# else /* Im a __GNUC__ happy compiler */
|
||||
#include <stdlib.h>
|
||||
# endif /* __GNUC__ */
|
||||
#endif /* HAVE_ALLOCA */
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#if !defined(__FILE__)
|
||||
#define __FILE__ "unsupported"
|
||||
#endif /* __FILE */
|
||||
#if !defined(__LINE__)
|
||||
#define __LINE__ -1
|
||||
#endif /* __LINE__ */
|
||||
extern void* ftmpi_malloc( size_t, char*, int );
|
||||
extern void* ftmpi_calloc( size_t, size_t, char*, int );
|
||||
extern void* ftmpi_realloc( void*, size_t, char*, int );
|
||||
extern void ftmpi_free( void*, char*, int );
|
||||
extern void ftmpi_display_memory_usage( void );
|
||||
|
||||
#define _MALLOC(size) ftmpi_malloc( (size), __FILE__, __LINE__ )
|
||||
#define _CALLOC(nb, size) ftmpi_calloc( (nb), (size), __FILE__, __LINE__ )
|
||||
#define _REALLOC(ptr, size) ftmpi_realloc( (ptr), (size), __FILE__, __LINE__ )
|
||||
#define _FREE(ptr) ftmpi_free( (ptr), __FILE__, __LINE__ )
|
||||
#define DUMP_ALLOCATED_MEMORY() ftmpi_display_memory_usage()
|
||||
|
||||
#else /* !defined(NDEBUG) */
|
||||
#include <stdlib.h>
|
||||
#define _MALLOC(size) malloc((size))
|
||||
#define _CALLOC(nb, size) calloc((nb), (size))
|
||||
#define _REALLOC(ptr, size) realloc( (ptr), (size) )
|
||||
#define _FREE(ptr) free((ptr))
|
||||
#define DUMP_ALLOCATED_MEMORY()
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#endif /* DEBUG_H_HAS_BEEN_INCLUDED */
|
198
src/mca/service/stdio/snipe_lite/memory.c
Обычный файл
198
src/mca/service/stdio/snipe_lite/memory.c
Обычный файл
@ -0,0 +1,198 @@
|
||||
#if !defined(NDEBUG)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct __mem_allocator smemAllocator_t;
|
||||
|
||||
#define VALIDATOR 0xdeadbeaf
|
||||
/* #define EXTREME_DEBUG */
|
||||
#ifdef EXTREME_DEBUG
|
||||
#define ZEROS_FOLLOW 1024
|
||||
#else
|
||||
#define ZEROS_FOLLOW 0
|
||||
#endif /* EXTREME_DEBUG */
|
||||
#define VALUE_CHAR 0xbe
|
||||
|
||||
struct __mem_allocator {
|
||||
smemAllocator_t* prev;
|
||||
smemAllocator_t* next;
|
||||
unsigned int lineno;
|
||||
unsigned int validator;
|
||||
char* pFileName;
|
||||
unsigned int length;
|
||||
int index;
|
||||
};
|
||||
|
||||
static int __alloc_index = 0;
|
||||
static smemAllocator_t* pdllmem = NULL;
|
||||
|
||||
#ifdef EXTREME_DEBUG
|
||||
static int __overflow_detection( smemAllocator_t* pTemp )
|
||||
{
|
||||
int i;
|
||||
unsigned char* pchar = ((char*)&pTemp[1]) + pTemp->length;
|
||||
|
||||
for( i = 0; i < ZEROS_FOLLOW; i++ ) {
|
||||
if( pchar[i] != VALUE_CHAR ) {
|
||||
printf( "buffer overflow detected at position %d(%p) on memory allocated in %s at line %d (pointer %p size %d) \n",
|
||||
i, pchar + i, pTemp->pFileName, pTemp->lineno, ((char*)pTemp) + sizeof(smemAllocator_t), pTemp->length );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* EXTREME_DEBUG */
|
||||
|
||||
void* ftmpi_malloc( size_t size, char* file, int lineno )
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
smemAllocator_t* pTemp;
|
||||
|
||||
totalLength = sizeof( smemAllocator_t ) + size + ZEROS_FOLLOW;
|
||||
pTemp = (smemAllocator_t*)malloc( totalLength );
|
||||
if( pTemp == NULL ) return NULL;
|
||||
pTemp->length = size;
|
||||
pTemp->validator = VALIDATOR;
|
||||
pTemp->pFileName = file;
|
||||
pTemp->lineno = lineno;
|
||||
pTemp->index = __alloc_index++;
|
||||
|
||||
if( pdllmem == NULL ) {
|
||||
pdllmem = pTemp;
|
||||
pTemp->next = pTemp;
|
||||
pTemp->prev = pTemp;
|
||||
} else {
|
||||
pdllmem->prev->next = pTemp;
|
||||
pTemp->prev = pdllmem->prev;
|
||||
pTemp->next = pdllmem;
|
||||
pdllmem->prev = pTemp;
|
||||
}
|
||||
#ifdef EXTREME_DEBUG
|
||||
memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW );
|
||||
#endif /* EXTREME_DEBUG */
|
||||
return (void*)&pTemp[1];
|
||||
}
|
||||
|
||||
void* ftmpi_calloc( size_t number, size_t size, char* file, int lineno )
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
smemAllocator_t* pTemp;
|
||||
|
||||
totalLength = sizeof( smemAllocator_t ) + number * size + ZEROS_FOLLOW;
|
||||
pTemp = (smemAllocator_t*)calloc( 1, totalLength );
|
||||
pTemp->length = number * size;
|
||||
pTemp->validator = VALIDATOR;
|
||||
pTemp->pFileName = file;
|
||||
pTemp->lineno = lineno;
|
||||
pTemp->index = __alloc_index++;
|
||||
|
||||
if( pdllmem == NULL ) {
|
||||
pdllmem = pTemp;
|
||||
pTemp->next = pTemp;
|
||||
pTemp->prev = pTemp;
|
||||
} else {
|
||||
pdllmem->prev->next = pTemp;
|
||||
pTemp->prev = pdllmem->prev;
|
||||
pTemp->next = pdllmem;
|
||||
pdllmem->prev = pTemp;
|
||||
}
|
||||
#ifdef EXTREME_DEBUG
|
||||
memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW );
|
||||
#endif /* EXTREME_DEBUG */
|
||||
return (void*)&pTemp[1];
|
||||
}
|
||||
|
||||
void* ftmpi_realloc( void* ptr, size_t size, char* file, int lineno )
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
smemAllocator_t* pTemp = (smemAllocator_t*)((char*)ptr - sizeof(smemAllocator_t));
|
||||
smemAllocator_t *prev, *next, *old;
|
||||
|
||||
prev = pTemp->prev;
|
||||
next = pTemp->next;
|
||||
old = pTemp;
|
||||
|
||||
#ifdef EXTREME_DEBUG
|
||||
if( __overflow_detection( pTemp ) != 0 ) assert(0);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
totalLength = sizeof( smemAllocator_t ) + size + ZEROS_FOLLOW;
|
||||
pTemp = (smemAllocator_t*)realloc( pTemp, totalLength );
|
||||
pTemp->length = size;
|
||||
pTemp->validator = VALIDATOR;
|
||||
pTemp->pFileName = file;
|
||||
pTemp->lineno = lineno;
|
||||
pTemp->index = __alloc_index++;
|
||||
|
||||
if( pdllmem == old ) {
|
||||
if( prev == old ) {
|
||||
assert( next == old );
|
||||
prev = next = pTemp;
|
||||
}
|
||||
pdllmem = pTemp;
|
||||
}
|
||||
prev->next = pTemp;
|
||||
next->prev = pTemp;
|
||||
pTemp->prev = prev;
|
||||
pTemp->next = next;
|
||||
#ifdef EXTREME_DEBUG
|
||||
memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW );
|
||||
#endif /* EXTREME_DEBUG */
|
||||
return (void*)&pTemp[1];
|
||||
}
|
||||
|
||||
void ftmpi_free( void* ptr, char* file, int lineno )
|
||||
{
|
||||
smemAllocator_t* pTemp = (smemAllocator_t*)((char*)ptr - sizeof(smemAllocator_t));
|
||||
|
||||
/* remove it from the allocated memory */
|
||||
#ifdef EXTREME_DEBUG
|
||||
if( __overflow_detection( pTemp ) != 0 ) assert(0);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
assert( pTemp->prev->next == pTemp );
|
||||
assert( pTemp->next->prev == pTemp );
|
||||
pTemp->prev->next = pTemp->next;
|
||||
pTemp->next->prev = pTemp->prev;
|
||||
if( pTemp == pdllmem ) {
|
||||
if( pTemp->next == pTemp ) {
|
||||
assert( pTemp->prev == pTemp );
|
||||
pdllmem = NULL;
|
||||
} else {
|
||||
pdllmem = pTemp->next;
|
||||
}
|
||||
}
|
||||
assert( pTemp->validator == VALIDATOR );
|
||||
pTemp->validator = 0;
|
||||
/* keep this informations to see where the memory has been freed */
|
||||
pTemp->pFileName = file;
|
||||
pTemp->lineno = lineno;
|
||||
|
||||
/* And now really free the memory */
|
||||
free( pTemp );
|
||||
}
|
||||
|
||||
void ftmpi_display_memory_usage( void )
|
||||
{
|
||||
smemAllocator_t* pTemp = pdllmem;
|
||||
int totalSize = 0, chunks = 0;
|
||||
|
||||
if( pTemp == NULL ) return;
|
||||
printf( ">> BEGIN MEMORY USAGE and TRACE\n" );
|
||||
do {
|
||||
#ifdef EXTREME_DEBUG
|
||||
if( __overflow_detection( pTemp ) != 0 ) assert(0);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
printf( "Allocate %d bytes in file %s at line %d pointer %p index %d\n",
|
||||
pTemp->length, pTemp->pFileName, pTemp->lineno,
|
||||
((char*)pTemp + sizeof(smemAllocator_t)), pTemp->index );
|
||||
chunks++;
|
||||
totalSize += pTemp->length;
|
||||
pTemp = pTemp->next;
|
||||
} while( pTemp != pdllmem );
|
||||
printf( "Allocated %d chunks of memory with the total size of %d bytes\n",
|
||||
chunks, totalSize );
|
||||
printf( ">> END MEMORY USAGE and TRACE\n" );
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
258
src/mca/service/stdio/snipe_lite/msg.c
Обычный файл
258
src/mca/service/stdio/snipe_lite/msg.c
Обычный файл
@ -0,0 +1,258 @@
|
||||
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
Graham E Fagg <fagg@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#include "msgbuf.h"
|
||||
#include "msg.h"
|
||||
#ifdef WIN32
|
||||
#include "wincomm.h"
|
||||
#else
|
||||
#include "snipe_lite.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* Note this is a simple (bad) description of a basic header */
|
||||
/*
|
||||
0-3 PKMESSAGEVER used to make sure its a packed message.. so if its not, then drop it.... if we can.
|
||||
|
||||
4-7 PACKEDMESSAGELEN length of packed data in octets (can be zero but not negative)
|
||||
8-11 SENDERS ID arbitary id that they specify
|
||||
12-15 NUMBER OF TAGS if no tags then set to zero
|
||||
16-((4*ntag)-1) individual tags ...
|
||||
16+(4*ntag)- Start of packed data.
|
||||
|
||||
*/
|
||||
|
||||
/* Note to avoid using writeV etc we get a message buffer of our own JUST for packing stuff in and out of */
|
||||
/* we don't use the msgbuf routines as that effects cache coherency */
|
||||
|
||||
char hdrbuf [4096];
|
||||
|
||||
|
||||
/* this routine sends a message down a socket as a complete message */
|
||||
/* this includes a simple header (sender, tag, length) */
|
||||
/* if the free flag is set then the message buffer is freed */
|
||||
/* if free is set then even if its not send it is still freed always */
|
||||
|
||||
/* return value is either the total length sent or an error */
|
||||
|
||||
/* if the complete amount is not sent then the buffer is not freed */
|
||||
|
||||
int send_pkmesg (int send_s,int myid,int ntag,int * tagp,int buf_id,int free_buf)
|
||||
/* int send_s; socket to send_s */
|
||||
/* int myid; ID I place in message header */
|
||||
/* int ntag; Number of Tags in header */
|
||||
/* int *tagp; pointer to Tags to put in header */
|
||||
/* int buf_id; message buffer I am sending or if you want to send an EMPTY message send EMPTYMSGBUF */
|
||||
/* int free_buf; non zero if you want to free the buffer up after a good send */
|
||||
{
|
||||
int len = 0;
|
||||
char * buf_ptr;
|
||||
int ret = -1;
|
||||
int *data;
|
||||
int valid;
|
||||
int i;
|
||||
|
||||
|
||||
if (buf_id != EMPTYMSGBUF) valid = check_buf (buf_id);
|
||||
else valid = 1;
|
||||
|
||||
if (!valid) return (BADBUFFER);
|
||||
|
||||
if (buf_id != EMPTYMSGBUF)
|
||||
get_msg_buf_info(buf_id,&buf_ptr,&len); /* get buffer info */
|
||||
else {
|
||||
buf_ptr = NULL; /* if empty message */
|
||||
len = 0;
|
||||
}
|
||||
|
||||
data = (int*) hdrbuf;
|
||||
|
||||
*data++ = htonl (PKMESSAGEVER);
|
||||
*data++ = htonl (len);
|
||||
*data++ = htonl (myid);
|
||||
*data++ = htonl (ntag);
|
||||
|
||||
for (i=0;i<ntag;i++) { /* pack the tags */
|
||||
*data++ = htonl (tagp[i]);
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
PRINT("TRYING TO SEND %d %d - size %d of buf %d\n",myid,ntag,len, buf_id);
|
||||
#endif
|
||||
|
||||
while(ret < 1){
|
||||
ret = writeconn(send_s,(char*) hdrbuf,sizeof(int)*(4+ntag));
|
||||
if(ret <= 0){
|
||||
if ((buf_id != EMPTYMSGBUF)&&(free_buf)) free_msg_buf(buf_id);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
ret = writeconn(send_s,buf_ptr,len);
|
||||
if(ret <= 0){
|
||||
if ((buf_id != EMPTYMSGBUF)&&(free_buf)) free_msg_buf(buf_id);
|
||||
return(ret);
|
||||
}
|
||||
else
|
||||
if ((buf_id != EMPTYMSGBUF)&&(free_buf)) free_msg_buf(buf_id);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* recv a packed message and return the buffer of the message / size etc */
|
||||
/* This route will allocate a buffer if it is needed (i.e. if it has a */
|
||||
/* payload). */
|
||||
|
||||
/* If there isn't enought space for all the tags it drops tags */
|
||||
/* ntags can be NULL or 0 */
|
||||
/* if there is a protocol error i.e. protocol versions don't match it bombs */
|
||||
|
||||
int recv_pkmesg (int recv_s,int * from,int * ntag,int * tagp,int * buf_id)
|
||||
{
|
||||
int len;
|
||||
char * buf_ptr = NULL;
|
||||
int *hdata;
|
||||
int *hdata2;
|
||||
int size;
|
||||
int ret;
|
||||
int client;
|
||||
int i, j;
|
||||
int tmp;
|
||||
int rtags; /* how many tags to receive even if it drops some */
|
||||
int tbid; /* temp buf id */
|
||||
|
||||
#ifdef VERBOSE
|
||||
PRINT("Atempting to receive from %d via socket %d\n",recv_s, from);
|
||||
#endif
|
||||
|
||||
|
||||
/* download the data into the header buffer */
|
||||
hdata = (int*) hdrbuf;
|
||||
hdata2 = (int*) hdrbuf;
|
||||
|
||||
ret = readconn(recv_s,(char*)hdata,sizeof(int)*4);
|
||||
if(!ret){
|
||||
return(ret);
|
||||
}
|
||||
|
||||
tmp = ntohl(hdata[0]);
|
||||
if (tmp != PKMESSAGEVER) { /* Header check */
|
||||
#ifdef VERBOSE
|
||||
printf("Recv_pkmesg has received a message with an incorrect hdr [0x%x]\n", hdata[0]);
|
||||
#endif
|
||||
return (MSG_BAD_HEADER);
|
||||
}
|
||||
|
||||
size = ntohl(hdata[1]);
|
||||
client = ntohl(hdata[2]);
|
||||
rtags = ntohl(hdata[3]);
|
||||
|
||||
#ifdef VERBOSE
|
||||
printf("header 0x%x size %d from %d ntags %d\n",
|
||||
tmp, size, client, rtags);
|
||||
#endif
|
||||
|
||||
/* now we have a copy of the header we can overwrite the headerbuffer */
|
||||
|
||||
/* download the message tags into the header buffer */
|
||||
if (rtags>0) {
|
||||
hdata2 = (int*) hdrbuf;
|
||||
ret = readconn(recv_s,(char*)hdata2,sizeof(int)*rtags);
|
||||
if(!ret){
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* ok copy over the ones we have been given space for */
|
||||
/* check to see if we are even excepting tags first ! */
|
||||
if (ntag) {
|
||||
j = *ntag;
|
||||
if (j>rtags) j=rtags;
|
||||
|
||||
for(i=0;i<j;i++) {
|
||||
*tagp = ntohl(*hdata2);
|
||||
tagp++;
|
||||
hdata2++;
|
||||
}
|
||||
|
||||
/* NOTE we only do the conversion on the ones we keep. Saves a few usecs? */
|
||||
|
||||
/* return the number of tags copied down */
|
||||
*ntag = j;
|
||||
}
|
||||
else
|
||||
j = 0; /* no tags copied */
|
||||
|
||||
/* copy across the return info */
|
||||
|
||||
/* senders id */
|
||||
if (from) *from = client;
|
||||
|
||||
/* if no data (payload) to copy in, return outa here */
|
||||
if(size == 0){
|
||||
if (buf_id) *buf_id = EMPTYMSGBUF;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* get a buffer for the incoming data */
|
||||
/* the buffer must be resizable */
|
||||
/* i.e. we need a buffer, resize one if needed */
|
||||
/* Also we reset the unpack len (toend) value automatically on it */
|
||||
|
||||
tbid = get_msg_buf_of_size(size, 1, 1);
|
||||
|
||||
get_msg_buf_info(tbid, &buf_ptr, &len); /* get the buffers ptr */
|
||||
|
||||
ret = readconn(recv_s, buf_ptr, size); /* read socket into buffer */
|
||||
|
||||
/* now we need to return the buffer id */
|
||||
/* if its been given a NULL pointer we blow it away */
|
||||
|
||||
if (!buf_id) { /* a null return address! */
|
||||
#ifdef VERBOSE
|
||||
printf("Recv_pkmesg has a valid buffer but a NULL return address!\n");
|
||||
#endif
|
||||
free_msg_buf (tbid); /* blow it away */
|
||||
}
|
||||
else
|
||||
*buf_id = tbid; /* return it */
|
||||
|
||||
return(ret); /* return read data length */
|
||||
}
|
||||
|
49
src/mca/service/stdio/snipe_lite/msg.h
Обычный файл
49
src/mca/service/stdio/snipe_lite/msg.h
Обычный файл
@ -0,0 +1,49 @@
|
||||
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
Graham E Fagg <fagg@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _GHCORE_MSG_H
|
||||
#define _GHCORE_MSG_H 1
|
||||
|
||||
|
||||
#define EMPTYMSGBUF -1812
|
||||
#define MSG_BAD_HEADER -1111
|
||||
|
||||
#define PKMESSAGEVER 0xABCD
|
||||
|
||||
|
||||
int send_pkmesg (int send_s,int myid,int ntag,int * tagp,int buf_id,int free_buf);
|
||||
int recv_pkmesg (int recv_s,int * from,int * ntag,int * tagp,int * buf_id);
|
||||
|
||||
#endif /* _GHCORE_MSG_H */
|
155
src/mca/service/stdio/snipe_lite/msgbuf.h
Обычный файл
155
src/mca/service/stdio/snipe_lite/msgbuf.h
Обычный файл
@ -0,0 +1,155 @@
|
||||
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
HARNESS FT_MPI
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors:
|
||||
Graham E Fagg <fagg@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _GHCORE_MSGBUF_H
|
||||
#define _GHCORE_MSGBUF_H 1
|
||||
|
||||
|
||||
|
||||
/*
|
||||
message packing/unpacking routines
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* Uncomment the following line to enable msgbuf V2.0 */
|
||||
#define MSG_BUF_V2
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef MSG_BUF_V2
|
||||
|
||||
#define _msg_resize_buf _hn_msg_resize_buf
|
||||
#define init_msg_bufs hn_init_msg_bufs
|
||||
#define dump_msg_bufs hn_dump_msg_bufs
|
||||
#define check_buf hn_check_buf
|
||||
#define get_msg_buf_info hn_get_msg_buf_info
|
||||
#define get_msg_buf hn_get_msg_buf
|
||||
#define set_unpksize hn_set_unpksize
|
||||
#define get_msg_buf_of_size hn_get_msg_buf_of_size
|
||||
#define free_msg_buf hn_free_msg_buf
|
||||
#define end_msg_buf hn_end_msg_buf
|
||||
|
||||
#define pk_int8 hn_pk_int8
|
||||
#define pk_int16 hn_pk_int16
|
||||
#define pk_int32 hn_pk_int32
|
||||
#define pk_raw32 hn_pk_raw32
|
||||
#define pk_int64 hn_pk_int64
|
||||
#define pk_int128 hn_pk_int128
|
||||
#define pk_real32 hn_pk_real32
|
||||
#define pk_real64 hn_pk_real64
|
||||
#define pk_byte hn_pk_byte
|
||||
#define pk_string hn_pk_string
|
||||
|
||||
#define upk_int8 hn_upk_int8
|
||||
#define upk_int16 hn_upk_int16
|
||||
#define upk_int32 hn_upk_int32
|
||||
#define upk_raw32 hn_upk_raw32
|
||||
#define upk_int64 hn_upk_int64
|
||||
#define upk_int128 hn_upk_int128
|
||||
#define upk_real32 hn_upk_real32
|
||||
#define upk_real64 hn_upk_real64
|
||||
#define upk_byte hn_upk_byte
|
||||
#define upk_string hn_upk_string
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int init_msg_bufs (); /* must call first */
|
||||
int get_msg_buf_info (int buf,char ** base,int * len); /* get info on buf */
|
||||
int get_msg_buf (int resizable ); /* get a free buf */
|
||||
int get_msg_buf_of_size (unsigned long reqsize,int resize,int setunpksize); /* get a free buf that is a particular size */
|
||||
int free_msg_buf (int buf); /* free a buf */
|
||||
int check_buf (int buf); /* valid buf ? */
|
||||
int dump_msg_bufs (); /* dump msg buf information */
|
||||
int end_msg_buf (); /* free ALL bufs */
|
||||
|
||||
/* pack and unpack binary data */
|
||||
int pk_byte (int buf,void * ptr,long n);
|
||||
int upk_byte (int buf,void * ptr,long n);
|
||||
int pk_raw32 (int buf,void * ptr,long n);
|
||||
int upk_raw32 (int buf,void * ptr,long n);
|
||||
|
||||
/* pack basic integer types */
|
||||
|
||||
int pk_int8 (int buf,void * ptr,long n);
|
||||
int pk_int16 (int buf,void * ptr,long n);
|
||||
int pk_int32 (int buf,void * ptr,long n);
|
||||
int pk_int64 (int buf,void * ptr,long n);
|
||||
int pk_int128 (int buf,void * ptr,long n);
|
||||
|
||||
/* pack real numbers */
|
||||
int pk_real32 (int buf,void * ptr,long n);
|
||||
int pk_real64 (int buf,void * ptr,long n);
|
||||
|
||||
/* unpack basic integer types */
|
||||
|
||||
int upk_int8 (int buf,void * ptr,long n);
|
||||
int upk_int16 (int buf,void * ptr,long n);
|
||||
int upk_int32 (int buf,void * ptr,long n);
|
||||
int upk_int64 (int buf,void * ptr,long n);
|
||||
int upk_int128 (int buf,void * ptr,long n);
|
||||
|
||||
/* unpack real numbers */
|
||||
int upk_real32 (int buf,void * ptr,long n);
|
||||
int upk_real64 (int buf,void * ptr,long n);
|
||||
|
||||
/* handles strings */
|
||||
/* note this takes NULL terminated strings and returns null terminated strings */
|
||||
|
||||
int pk_string (int buf,char *strptr);
|
||||
int upk_string (int buf,void * strptr,long maxlen);
|
||||
|
||||
/* error codes (i.e. rather than just -1) */
|
||||
#define BADBUFFER -2010 /* bad buffer id */
|
||||
#define OUTOFBUFFERS -2011 /* no free msg buffers free */
|
||||
#define OUTOFMEMORY -2012 /* cannot allocate any more memory for message buffers */
|
||||
#define BADLUCK -13 /* no comment */
|
||||
#define BADPARM -2014 /* other parameters are bad/invalid pointers */
|
||||
#define BADDATA -2015 /* to/from data addr is bad (null etc) */
|
||||
|
||||
|
||||
#endif /* _GHCORE_MSGBUF_H */
|
1762
src/mca/service/stdio/snipe_lite/msgbuf2.c
Обычный файл
1762
src/mca/service/stdio/snipe_lite/msgbuf2.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1007
src/mca/service/stdio/snipe_lite/snipe_lite.c
Обычный файл
1007
src/mca/service/stdio/snipe_lite/snipe_lite.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
110
src/mca/service/stdio/snipe_lite/snipe_lite.h
Обычный файл
110
src/mca/service/stdio/snipe_lite/snipe_lite.h
Обычный файл
@ -0,0 +1,110 @@
|
||||
|
||||
|
||||
/*
|
||||
HARNESS G_HCORE
|
||||
|
||||
Innovative Computer Laboratory,
|
||||
University of Tennessee,
|
||||
Knoxville, TN, USA.
|
||||
|
||||
harness@cs.utk.edu
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Authors: Graham Fagg <fagg@cs.utk.edu>
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
NOTICE
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby granted
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both the copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
Neither the University of Tennessee nor the Authors make any
|
||||
representations about the suitability of this software for any
|
||||
purpose. This software is provided ``as is'' without express or
|
||||
implied warranty.
|
||||
|
||||
HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the
|
||||
U.S. Department of Energy.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
SNIPE_LITE was part of the SNIPE experimental metacomputing system
|
||||
|
||||
the comms library was a non threaded 'get the message there' TCP
|
||||
library that is a little more carefull than the cs340 socketfun stuff
|
||||
|
||||
Incept for this code was in 1998.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _SNIPE_LITE_H
|
||||
#define _SNIPE_LITE_H 1
|
||||
|
||||
/* Syslog facility for snipe_lite */
|
||||
#include "syslog.h"
|
||||
extern syslog_t* slsyslog;
|
||||
|
||||
/*
|
||||
Create listening socket etc
|
||||
*/
|
||||
|
||||
int setportconn (int *s,int port,int range) ;
|
||||
int allowconn (int s,int fe,int * spid);
|
||||
int probeconn (int s,int fe,int * spid);
|
||||
int pollconn (int s,int dir,int tout);
|
||||
|
||||
/*
|
||||
Client connect
|
||||
*/
|
||||
int getconn (char * host,int * port,int search); /* by host name */
|
||||
int getconn_addr (unsigned long addr,int * port,int search); /* by sa_addr */
|
||||
|
||||
/*
|
||||
Close by either side
|
||||
*/
|
||||
int closeconn (int s);
|
||||
|
||||
/*
|
||||
Stream based blocking send/recv operations
|
||||
*/
|
||||
int writeconn (int s,char * data,int len);
|
||||
int readconn (int s,char * data,int len);
|
||||
|
||||
/*
|
||||
Message based/styled communications
|
||||
*/
|
||||
int writemsgconn (int s,char * data,int len);
|
||||
int readmsgconn (int s,char * data,int mlen);
|
||||
|
||||
|
||||
void nodelay(int s); /* hack routine to improve performance.. maybe */
|
||||
void setnonblocking(int s); /* sets the given socket non-blocking */
|
||||
void setblocking(int s); /* sets the given socket blocking again */
|
||||
int setsendrecvbufs(int s, int bufsize); /* Sets send/recv buffer sizes */
|
||||
int free_default_name(void);
|
||||
|
||||
char *getHostnameByAddr(int addr);
|
||||
|
||||
/* Benchmarking ops */
|
||||
double sec_time(void);
|
||||
|
||||
/* defines */
|
||||
/* these needs to be set per daemon type really */
|
||||
|
||||
#ifdef IMA_LINUX
|
||||
#include <sys/socket.h>
|
||||
#define LISTENBACKLOG SOMAXCONN
|
||||
#else
|
||||
#define LISTENBACKLOG 128
|
||||
#endif
|
||||
|
||||
int get_my_addr( char** pdefault_name );
|
||||
|
||||
#endif /* _SNIPE_LITE_H */
|
196
src/mca/service/stdio/snipe_lite/syslog.c
Обычный файл
196
src/mca/service/stdio/snipe_lite/syslog.c
Обычный файл
@ -0,0 +1,196 @@
|
||||
#include "syslog.h"
|
||||
#include "debug.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _log_flags {
|
||||
char* name;
|
||||
char* optname;
|
||||
syslog_t** syslog;
|
||||
} log_flag_t;
|
||||
|
||||
struct syslog_t {
|
||||
char* name;
|
||||
int level;
|
||||
FILE* output;
|
||||
int private_id;
|
||||
};
|
||||
|
||||
static log_flag_t logFlags[] = {
|
||||
{ "CONN", "conn", &LOG_CONN },
|
||||
{ "RESTART", "restart", &LOG_RESTART },
|
||||
{ "NOTIFIER", "not", &LOG_NOTIFIER },
|
||||
{ "MPI", "mpi", &LOG_MPI },
|
||||
{ "CALLBACK", "callback", &LOG_CALLBACK },
|
||||
{ "DDT", "ddt", &LOG_DDT },
|
||||
{ "IOVEC", "iovec", &LOG_IOVEC },
|
||||
{ "SNIPE2", "snipe2", &LOG_SNIPE2 },
|
||||
{ "SYS", "sys", &LOG_SYS }
|
||||
};
|
||||
|
||||
syslog_t* conn_syslog = NULL; /* connection stuff */
|
||||
syslog_t* restart_syslog = NULL; /* restart messages */
|
||||
syslog_t* mpi_syslog = NULL; /* high level messages */
|
||||
syslog_t* notif_syslog = NULL; /* communications with the notifier */
|
||||
syslog_t* cb_syslog = NULL; /* callback functions */
|
||||
syslog_t* ddt_syslog = NULL; /* ddt stuff */
|
||||
syslog_t* iovec_syslog = NULL; /* iovec informations */
|
||||
syslog_t* snipe2_syslog = NULL; /* snipe2 information */
|
||||
syslog_t* sys_syslog = NULL; /* system messages */
|
||||
|
||||
int ftmpi_syslog_init( int private_id )
|
||||
{
|
||||
char envName[128];
|
||||
char *pEnv, *pFileEnv;
|
||||
int i, pos = 0;
|
||||
|
||||
pEnv = getenv( "HARNESS_FTMPI_DEBUG" );
|
||||
if( pEnv == NULL ) return 0;
|
||||
|
||||
while( 1 ) {
|
||||
if( pEnv[pos] == ' ' ) continue;
|
||||
for( i = 0; i < (sizeof(logFlags) / sizeof(log_flag_t)); i++ ) {
|
||||
if( strcmp( pEnv, logFlags[i].optname ) == 0 ) {
|
||||
/* one of the flags is present */
|
||||
sprintf( envName, "HARNESS_FTMPI_%s_FILE", logFlags[i].name );
|
||||
pFileEnv = getenv( envName );
|
||||
if( pFileEnv == NULL )
|
||||
*(logFlags[i].syslog) = syslog_init( NULL, private_id, 100 );
|
||||
else {
|
||||
FILE* pf = fopen( pFileEnv, "w" );
|
||||
if( pf == NULL ) {
|
||||
fprintf( stderr, "Unable to open the file %s\n", pFileEnv );
|
||||
} else {
|
||||
*(logFlags[i].syslog) = syslog_init( pf, private_id, 100 );
|
||||
}
|
||||
}
|
||||
pos += strlen(logFlags[i].optname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while( 1 ) {
|
||||
if( pEnv[pos] == '\0' ) return 1;
|
||||
if( pEnv[pos] == ',' ) pos++;
|
||||
else if( pEnv[pos] == ' ' ) pos++;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog_t* syslog_init( FILE* output, int private_id, int level )
|
||||
{
|
||||
syslog_t* pSyslog = _MALLOC( sizeof(struct syslog_t) );
|
||||
|
||||
if( output == NULL ) pSyslog->output = stderr;
|
||||
else pSyslog->output = output;
|
||||
pSyslog->level = level;
|
||||
pSyslog->private_id = private_id;
|
||||
/* unsigned int activeFlags = LOG_RESTART|LOG_CONN|LOG_SYS|LOG_SNIPE2; */
|
||||
return pSyslog;
|
||||
}
|
||||
|
||||
int syslog_close( syslog_t** pSyslog )
|
||||
{
|
||||
if( (*pSyslog) == NULL ) return 0;
|
||||
fflush( (*pSyslog)->output );
|
||||
_FREE( (*pSyslog) );
|
||||
*pSyslog = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void syslog_hint( syslog_t* pSyslog, const unsigned int level, const char* file, int lineno, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
|
||||
if( pSyslog == NULL ) return;
|
||||
if( level < pSyslog->level ) return;
|
||||
|
||||
fprintf( pSyslog->output, "%x-%s:%d [H-%s] ", pSyslog->private_id, file, lineno, pSyslog->name );
|
||||
va_start( list, fmt );
|
||||
vfprintf( pSyslog->output, fmt, list );
|
||||
va_end( list );
|
||||
}
|
||||
|
||||
void syslog_warning( syslog_t* pSyslog, const char* file, int lineno, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
FILE* output;
|
||||
int id = 0;
|
||||
char* name = "UNKN";
|
||||
|
||||
if( pSyslog == NULL ) output = stderr;
|
||||
else {
|
||||
output = pSyslog->output;
|
||||
id = pSyslog->private_id;
|
||||
name = pSyslog->name;
|
||||
}
|
||||
|
||||
fprintf( output, "%x-%s:%d [W-%s] ", id, file, lineno, name );
|
||||
va_start( list, fmt );
|
||||
vfprintf( output, fmt, list );
|
||||
va_end( list );
|
||||
}
|
||||
|
||||
void syslog_fatal( syslog_t* pSyslog, const char* file, int lineno, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
FILE* output;
|
||||
int id = 0;
|
||||
char* name = "UNKN";
|
||||
|
||||
if( pSyslog == NULL ) output = stderr;
|
||||
else {
|
||||
output = pSyslog->output;
|
||||
id = pSyslog->private_id;
|
||||
name = pSyslog->name;
|
||||
}
|
||||
|
||||
fprintf( output, "%x-%s:%d [F-%s] ", id, file, lineno, name );
|
||||
va_start( list, fmt );
|
||||
vfprintf( output, fmt, list );
|
||||
va_end( list );
|
||||
#if !defined(NDEBUG)
|
||||
{
|
||||
int* l = NULL;
|
||||
*l = 0; /* generate a SEGV could be trapped with a debugger */
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
# if !defined(__GNUC__) && !defined(ACCEPT_C99)
|
||||
/* Simple case as the compiler thas not support macros with
|
||||
* a variable number of arguments.
|
||||
*/
|
||||
void HINT( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
|
||||
va_start( list, fmt );
|
||||
syslog_hint( flags, "unknown", -1, fmt, list );
|
||||
va_end( list );
|
||||
}
|
||||
# endif /* !defined(__GNUC__) && !defined(ACCEPT_C99) */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#if !defined(__GNUC__) && !defined(ACCEPT_C99)
|
||||
void WARNING( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
|
||||
va_start( list, fmt );
|
||||
syslog_warning( flags, "unknown", -1, fmt, list );
|
||||
va_end( list );
|
||||
}
|
||||
|
||||
void FATAL( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... )
|
||||
{
|
||||
va_list list;
|
||||
|
||||
va_start( list, fmt );
|
||||
syslog_fatal( flags, "unknown", -1, fmt, list );
|
||||
va_end( list );
|
||||
}
|
||||
#endif /* !defined(__GNUC__) && !defined(ACCEPT_C99) */
|
||||
|
118
src/mca/service/stdio/snipe_lite/syslog.h
Обычный файл
118
src/mca/service/stdio/snipe_lite/syslog.h
Обычный файл
@ -0,0 +1,118 @@
|
||||
#ifndef SYSLOG_H_HAS_BEEN_INCLUDED
|
||||
#define SYSLOG_H_HAS_BEEN_INCLUDED
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
typedef struct syslog_t syslog_t;
|
||||
|
||||
#define LOG_CONN conn_syslog /* connection stuff */
|
||||
#define LOG_RESTART restart_syslog /* restart messages */
|
||||
#define LOG_MPI mpi_syslog /* high level messages */
|
||||
#define LOG_NOTIFIER notif_syslog /* communications with the notifier */
|
||||
#define LOG_CALLBACK cb_syslog /* callback functions */
|
||||
#define LOG_DDT ddt_syslog /* ddt stuff */
|
||||
#define LOG_IOVEC iovec_syslog /* iovec informations */
|
||||
#define LOG_SNIPE2 snipe2_syslog /* snipe2 information */
|
||||
#define LOG_SYS sys_syslog /* system messages */
|
||||
|
||||
extern syslog_t* conn_syslog; /* connection stuff */
|
||||
extern syslog_t* restart_syslog; /* restart messages */
|
||||
extern syslog_t* mpi_syslog; /* high level messages */
|
||||
extern syslog_t* notif_syslog; /* communications with the notifier */
|
||||
extern syslog_t* cb_syslog; /* callback functions */
|
||||
extern syslog_t* ddt_syslog; /* ddt stuff */
|
||||
extern syslog_t* iovec_syslog; /* iovec informations */
|
||||
extern syslog_t* snipe2_syslog; /* snipe2 information */
|
||||
extern syslog_t* sys_syslog; /* system messages */
|
||||
|
||||
extern syslog_t* syslog_init( FILE* output, int private_id, int level );
|
||||
extern void syslog_hint( syslog_t* syslog, const unsigned int level,
|
||||
const char* file, int lineno,
|
||||
const char* fmt, ... );
|
||||
extern void syslog_warning( syslog_t* syslog,
|
||||
const char* file, int lineno,
|
||||
const char* fmt, ... );
|
||||
extern void syslog_fatal( syslog_t* syslog,
|
||||
const char* file, int lineno,
|
||||
const char* fmt, ... );
|
||||
|
||||
#if defined(NDEBUG)
|
||||
# if defined(__GNUC__)
|
||||
# define DO_DEBUG(args...)
|
||||
# define HINT( SYSLOG, LEVEL, FMT...)
|
||||
# define WARNING( SYSLOG, FMT... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, ##FMT )
|
||||
# define FATAL( SYSLOG, FMT... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, ##FMT )
|
||||
# else
|
||||
# if defined(ACCEPT_C99)
|
||||
# define DO_DEBUG( ... )
|
||||
# define HINT( SYSLOG, LEVEL, args... )
|
||||
# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ )
|
||||
# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ )
|
||||
# else
|
||||
# define DO_DEBUG( Args )
|
||||
static void HINT( syslog_t* syslog, const unsigned int level, const char* fmt, ... ) { /* empty hopefully removed by the compiler */};
|
||||
extern void WARNING( syslog_t* syslog, const char* fmt, ... );
|
||||
extern void FATAL( syslog_t* syslog, const char* fmt, ... );
|
||||
# endif /* ACCEPT_C99 */
|
||||
# endif /* __GNUC__ */
|
||||
#else /* NDEBUG not defined */
|
||||
# if defined(__GNUC__)
|
||||
# define DO_DEBUG(args...) args
|
||||
# define HINT( SYSLOG, LEVEL, FMT, args...) if( (SYSLOG) != NULL ) syslog_hint( (SYSLOG), (LEVEL), __FILE__, (int)__LINE__, FMT, ##args )
|
||||
# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), ##args )
|
||||
# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), ##args )
|
||||
# else
|
||||
# if defined(ACCEPT_C99)
|
||||
# define DO_DEBUG( ... ) __VA_ARGS__
|
||||
# define HINT( SYSLOG, LEVEL, args... ) if( (SYSLOG) != NULL ) syslog_hint( (SYSLOG), (LEVEL), __FILE__, (int)__LINE__, __VA_ARGS__ )
|
||||
# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ )
|
||||
# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ )
|
||||
# else
|
||||
# define DO_DEBUG( Args ) Args
|
||||
extern void HINT( syslog_t* syslog, const unsigned int level, const char* fmt, ... );
|
||||
extern void WARNING( syslog_t* syslog, const char* fmt, ... );
|
||||
extern void FATAL( syslog_t* syslog, const char* fmt, ... );
|
||||
# endif /* ACCEPT_C99 */
|
||||
# endif /* __GNUC__ */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
extern int errno;
|
||||
#define DUMP_SOCKET_ERROR(SOCK, ERRNO) \
|
||||
do { \
|
||||
struct sockaddr_in sockname; \
|
||||
socklen_t length = sizeof(struct sockaddr); \
|
||||
\
|
||||
if( getpeername( (SOCK), (struct sockaddr*)&sockname, &length ) == 0 ) { \
|
||||
WARNING( LOG_CONN, "sock %d [%s:%d] generate error %d %s\n", \
|
||||
(SOCK), inet_ntoa(sockname.sin_addr), sockname.sin_port, \
|
||||
(ERRNO), strerror((ERRNO)) ); \
|
||||
} else { \
|
||||
WARNING( LOG_CONN, "unable to get the peer name on socket %d. error %d %s\n", \
|
||||
(SOCK), errno, strerror(errno) ); \
|
||||
if( (ERRNO) != 0 ) \
|
||||
WARNING( LOG_CONN, " initial error was %d:%s\n", (ERRNO), strerror((ERRNO)) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DUMP_SOCKET_INFO(LOGGING, SOCK, SSTR, ESTR) \
|
||||
do { \
|
||||
struct sockaddr_in sockname; \
|
||||
socklen_t length = sizeof(struct sockaddr); \
|
||||
\
|
||||
if( getpeername( (SOCK), (struct sockaddr*)&sockname, &length ) == 0 ) { \
|
||||
HINT( LOGGING, 10, " %s sock %d [%s:%d] %s", (SSTR), \
|
||||
(SOCK), inet_ntoa(sockname.sin_addr), sockname.sin_port, (ESTR) ); \
|
||||
} else { \
|
||||
HINT( LOGGING, 10, " unable to get the peer name on socket %d. error %d %s\n", \
|
||||
(SOCK), errno, strerror(errno) ); \
|
||||
HINT( LOGGING, 10, " %s sock %d [??:??] %s", (SSTR), (SOCK), (ESTR) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* SYSLOG_H_HAS_BEEN_INCLUDED */
|
Загрузка…
x
Ссылка в новой задаче
Block a user