2 * Copyright (C) 2005-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief A client for an lpp solving server.
23 * @author Sebastian Hack
33 #include <sys/socket.h>
34 #include <sys/types.h>
35 #include <sys/resource.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
45 #define INADDR_NONE (in_addr_t)(-1)
64 static int winsock_init(void)
66 WORD wVersionRequested;
70 wVersionRequested = MAKEWORD( 2, 2 );
72 err = WSAStartup( wVersionRequested, &wsaData );
74 /* Tell the user that we could not find a usable */
79 /* Confirm that the WinSock DLL supports 2.2.*/
80 /* Note that if the DLL supports versions greater */
81 /* than 2.2 in addition to 2.2, it will still return */
82 /* 2.2 in wVersion since that is the version we */
85 if ( LOBYTE( wsaData.wVersion ) != 2 ||
86 HIBYTE( wsaData.wVersion ) != 2 ) {
87 /* Tell the user that we could not find a usable */
96 static int connect_tcp(const char *host, uint16_t port)
100 struct sockaddr_in sin;
107 memset(&sin, 0, sizeof(sin));
108 sin.sin_family = AF_INET;
109 sin.sin_port = htons(port);
111 if ((phe = gethostbyname(host)))
112 memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
113 else if((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
114 lpp_print_err("cannot get host entry for %s", host);
118 ppe = getprotobyname("tcp");
119 ERRNO_CHECK_RETURN(s = socket(PF_INET, SOCK_STREAM, ppe->p_proto), <, 0, -1);
120 ERRNO_CHECK_RETURN(connect(s, (struct sockaddr *) &sin, sizeof(sin)), <, 0, -1);
125 char **lpp_get_solvers(const char *host)
131 ERR_CHECK_RETURN(fd = connect_tcp(host, LPP_PORT), <, 0,
132 ("could not connect to %s", host), NULL);
134 comm = lpp_comm_new(fd, LPP_BUFSIZE);
136 lpp_writel(comm, LPP_CMD_SOLVERS);
139 res = malloc((n + 1) * sizeof(res[0]));
144 for(i = 0; i < n; ++i)
145 res[i] = lpp_reads(comm);
148 lpp_writel(comm, LPP_CMD_BYE);
155 void lpp_set_dbg(const char *host, int mask)
160 ERR_CHECK_RETURN_VOID(fd = connect_tcp(host, LPP_PORT), <, 0, ("could not connect to %s", host));
162 comm = lpp_comm_new(fd, LPP_BUFSIZE);
164 lpp_writel(comm, LPP_CMD_SET_DEBUG);
165 lpp_writel(comm, mask);
167 lpp_writel(comm, LPP_CMD_BYE);
173 void lpp_solve_net(lpp_t *lpp, const char *host, const char *solver)
178 ir_timer_t *t_send, *t_recv;
180 ERR_CHECK_RETURN_VOID(fd = connect_tcp(host, LPP_PORT), <, 0,
181 ("could not connect to %s", host));
183 comm = lpp_comm_new(fd, LPP_BUFSIZE);
186 lpp_writel(comm, LPP_CMD_SOLVER);
187 lpp_writes(comm, solver);
191 ERR_CHECK_RETURN_VOID(lpp_ack(fd, sizeof(buf), buf), == 0,
192 ("could not set solver: %s", solver));
195 t_send = ir_timer_new();
196 t_recv = ir_timer_new();
198 ir_timer_push(t_send);
199 lpp_writel(comm, LPP_CMD_PROBLEM);
200 lpp_serialize(comm, lpp, 1);
201 lpp_serialize_values(comm, lpp, lpp_value_start);
204 lpp->send_time = ir_timer_elapsed_usec(t_send);
208 int cmd = lpp_readl(comm);
210 case LPP_CMD_SOLUTION:
211 ir_timer_push(t_recv);
212 lpp_deserialize_stats(comm, lpp);
213 lpp_deserialize_values(comm, lpp, lpp_value_solution);
215 lpp->recv_time = ir_timer_elapsed_usec(t_recv);
219 lpp_readbuf(comm, buf, sizeof(buf));
220 buf[sizeof(buf) - 1] = '\0';
222 if(lpp->log != NULL) {
223 fputs(buf, lpp->log);
225 if(buf[n - 1] != '\n')
226 putc('\n', lpp->log);
231 fprintf(stderr, "solver process died unexpectedly\n");
234 fprintf(stderr, "invalid command: %s(%d)\n", lpp_get_cmd_name(cmd), cmd);
239 lpp_writel(comm, LPP_CMD_BYE);