metalsvm/apps/gfx_client.c

152 lines
3.4 KiB
C

/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* Chair for Operating Systems, RWTH Aachen University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of MetalSVM.
*/
#include <metalsvm/stdlib.h>
#if defined(CONFIG_LWIP) && LWIP_SOCKET
#include "gfx_client.h"
#include <lwip/sockets.h>
#ifdef CONFIG_GFX
static int myrank;
static int sockfd;
#ifndef SINGLE_CONNECT
#define SINGLE_CONNECT 1
#endif
#define SINGLE_CONNECT_RANK 0
#define USE_GETHOSTBYNAME 0
//int gfx_init(int* pargc, char*** pargv, int rank){
int gfx_init(char* ip_str, char* port_str, int rank) {
char* hostname;
int port;
struct sockaddr_in serveraddr;
#if USE_GETHOSTBYNAME
struct hostent *server;
#endif
//*pargc -=2;
myrank = rank;
#if SINGLE_CONNECT
// currently only rank 0 will connect to the gfx-server
if (rank != SINGLE_CONNECT_RANK) {
return 0;
}
#endif
/* hostname und port aus den parametern ermitteln) */
//kprintf("pargc: %d\n", *pargc);
hostname = ip_str; //(*pargv)[(*pargc)];
port = atoi(port_str); //atoi((*pargv)[(*pargc)+1]);
kprintf("gfx-client connecting to host: %s, port: %d\n", hostname, port);
/* socket erzeugen */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
return -1;
#if 1
/* Disable the Nagle (TCP No Delay) algorithm */
int flag = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) < 0) {
kprintf("Couldn't setsockopt(TCP_NODELAY)\n");
return -1;
}
#endif
#if USE_GETHOSTBYNAME
/* dns eintrag vom server ermitteln */
serveraddr = gethostbyname(hostname);
if (server == NULL){
fprintf(stderr, "%s: no such host\n", hostname);
return -2;
}
#endif
/* adresse vom server ermitteln */
memset((char *) &serveraddr, 0x00, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
#if USE_GETHOSTBYNAME
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);
#else
serveraddr.sin_addr.s_addr = inet_addr(hostname);
#endif
serveraddr.sin_port = htons(port);
/* verbindung herstellen */
if (connect(sockfd, (const struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
return -3;
return 0;
}
int gfx_send(char* buf, int size, int tag){
int ret, pos = 0;
uint32_t u32size, u32tag;
#if SINGLE_CONNECT
if (myrank != SINGLE_CONNECT_RANK)
return 0;
#endif
u32size = size;
u32tag = tag;
// printf("sending stuff....");
// printf("tag: %d, size: %d\n", tag, size);
// fflush(stdout);
ret = write(sockfd, &u32tag, sizeof(u32tag));
if (ret != sizeof(tag))
return -1;
ret = write(sockfd, &u32size, sizeof(u32size));
if (ret != sizeof(size))
return -2;
do{
ret = write(sockfd, &buf[pos], size-pos);
pos += ret;
} while (pos < size);
return 0;
}
int gfx_finalize(){
// uint32_t u32tag = (uint32_t)(-1);
uint32_t u32tag = 1111;
#if SINGLE_CONNECT
if (myrank == SINGLE_CONNECT_RANK) {
write(sockfd, &u32tag, sizeof(u32tag));
close(sockfd);
}
#endif
return 0;
}
#endif
#endif