Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program performance_test
- use iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT, C_PTR, C_LOC
- implicit none
- ! Interfaces that ensure type compatability between Fortran and C.
- interface
- subroutine client(ipaddr, portnum) bind(C, name="client")
- use iso_c_binding, only: c_char, c_int
- character(kind=c_char) :: ipaddr(*)
- integer(kind=c_int), value :: portnum
- end subroutine client
- subroutine calc(indata, length) bind(C, name="calc")
- use iso_c_binding, only: c_ptr, c_int
- implicit none
- integer(c_int), value :: length
- type(c_ptr), value :: indata
- end subroutine calc
- end interface
- ! type declaration statements
- integer(c_int), allocatable, target :: array(:)
- type(c_ptr) :: cptr
- integer portno, length, i
- ! executable statements
- ! Call client.c and connect to localhost on port number `portno'.
- portno=55555
- call client(C_CHAR_"localhost"//C_NULL_CHAR, portno)
- ! Put numbers in the array
- length = 1000000
- allocate(array(0:length))
- cptr=c_loc(array(1))
- do i=1, length
- array(i) = 2
- end do
- ! Call client.c and pass the query on towards calcs.f90.
- call calc(cptr, length)
- deallocate(array)
- end program performance_test
- /* The original code for this client can be found here:
- * http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/client.c */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- // Static variables
- static int sockfd;
- /* This function is called when a system call fails. It displays a message about
- * the error on stderr and then aborts the program. */
- void error(char *msg)
- {
- perror(msg);
- exit(0);
- }
- /* Callable function from Fortran, used by calcf.f90, to connect to a server.
- */
- int client(char *ipaddr, int in_portno)
- {
- int portno;
- struct sockaddr_in serv_addr;
- struct hostent *server;
- portno = in_portno;
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- error("ERROR opening socket");
- server = gethostbyname(ipaddr);
- if (server == NULL) {
- fprintf(stderr,"ERROR, no such hostn");
- exit(0);
- }
- memset(((char *) &serv_addr), 0, (sizeof(serv_addr)));
- serv_addr.sin_family = AF_INET;
- memcpy(((char *)server->h_addr),
- ((char *)&serv_addr.sin_addr.s_addr),
- (server->h_length));
- serv_addr.sin_port = htons(portno);
- if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
- error("ERROR connecting");
- return 0;
- }
- /* Callable function from Fortran, used by calcf.f90, as a calculator.
- * calc passes the query stored in buffer to server and returns the
- * answer. */
- int *calc(int *indata, int length)
- {
- int n;
- n = write(sockfd, indata, sizeof(int)*length);
- if (n < 0)
- error("ERROR writing to socket");
- n = read(sockfd, indata, sizeof(int)*length);
- if (n < 0)
- error("ERROR reading from socket");
- return indata;
- }
- /* The original code for this server can be found here:
- * http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/server.c */
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <math.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- /* This function is called when a system call fails. It displays a message about
- * the error on stderr and then aborts the program. */
- void error(char *msg)
- {
- perror(msg);
- exit(1);
- }
- /* Callable function from Fortran, used by calcs.f90, to start a server that
- * can recieve queries. */
- int server(int in_portno)
- {
- int sockfd, newsockfd, portno, clilen;
- struct sockaddr_in serv_addr, cli_addr; int n;
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- error("ERROR opening socket");
- memset(((char *) &serv_addr), 0, (sizeof(serv_addr)));
- portno = in_portno;
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(portno);
- if (bind(sockfd, (struct sockaddr *) &serv_addr,
- sizeof(serv_addr)) < 0)
- error("ERROR on binding");
- listen(sockfd,5);
- clilen = sizeof(cli_addr);
- while(1)
- {
- int length = 1000000;
- int indata[length];
- newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
- if (newsockfd < 0)
- error("ERROR on accept");
- // Here comes the query from client.c
- n = read(newsockfd, indata, sizeof(int)*length);
- if (n < 0) error("ERROR reading from socket");
- square(indata);
- // write returns the data to the client
- n = write(newsockfd, indata, sizeof(int)*length);
- if (n < 0) error("ERROR writing to socket");
- }
- return 0;
- }
- program calculator_server
- ! Calculator at the server side of the client/server calculator
- ! Responsible for starting up the server server.c
- use iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT, C_PTR
- implicit none
- ! type declaration statements
- integer calc, ans, portnum, calculate
- ! Interface that ensures type compatibility between Fortran and C
- interface
- subroutine server(portnum) bind(C, name="server")
- use iso_c_binding, only: c_int
- integer(kind=c_int), value :: portnum
- end subroutine server
- subroutine square(intarray) bind(C, name="square")
- use iso_c_binding
- type(c_ptr), value :: intarray
- end subroutine square
- end interface
- ! Start the server with portnumber
- portnum = 55555
- call server(portnum)
- end program calculator_server
- ! **********************************************************************
- subroutine square(cptr) bind(C, name="square")
- use iso_c_binding
- implicit none
- ! Variable declarations
- type(c_ptr) :: cptr
- integer*8 :: iptr
- integer :: length, i
- integer pointee(1000000)
- pointer(iptr, pointee)
- iptr = loc(cptr)
- length = 1000000
- ! Execution
- do i = 1, length
- pointee(i)= pointee(i)**2
- end do
- end subroutine square
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement