add unix socket bench
This commit is contained in:
parent
9797a64f06
commit
cccc1cfb58
@ -6,7 +6,7 @@ TEST_DEPS := dev_null
|
|||||||
# Tests: need to be compiled and run by test-% target
|
# Tests: need to be compiled and run by test-% target
|
||||||
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread uname rlimit client server server_epoll unix_socket
|
TESTS := empty argv hello_world malloc file getpid spawn pipe time truncate readdir mkdir link tls pthread uname rlimit client server server_epoll unix_socket
|
||||||
# Benchmarks: need to be compiled and run by bench-% target
|
# Benchmarks: need to be compiled and run by bench-% target
|
||||||
BENCHES := spawn_and_exit_latency pipe_throughput
|
BENCHES := spawn_and_exit_latency pipe_throughput unix_socket_throughput
|
||||||
|
|
||||||
# Top-level Makefile targets
|
# Top-level Makefile targets
|
||||||
BUILD_TARGETS := $(TEST_DEPS) $(TESTS) $(BENCHES)
|
BUILD_TARGETS := $(TEST_DEPS) $(TESTS) $(BENCHES)
|
||||||
|
@ -54,10 +54,6 @@ int create_client_socket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
// XXX: this is a hack! remove this in the future
|
|
||||||
void* ptr = malloc(64);
|
|
||||||
free(ptr);
|
|
||||||
|
|
||||||
int listen_fd = create_server_socket();
|
int listen_fd = create_server_socket();
|
||||||
if (listen_fd == -1) {
|
if (listen_fd == -1) {
|
||||||
printf("ERROR: failed to create server socket");
|
printf("ERROR: failed to create server socket");
|
||||||
|
5
test/unix_socket_throughput/Makefile
Normal file
5
test/unix_socket_throughput/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
include ../test_common.mk
|
||||||
|
|
||||||
|
EXTRA_C_FLAGS := -Wno-incompatible-pointer-types-discards-qualifiers
|
||||||
|
EXTRA_LINK_FLAGS :=
|
||||||
|
BIN_ARGS :=
|
153
test/unix_socket_throughput/main.c
Normal file
153
test/unix_socket_throughput/main.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <spawn.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define KB (1024UL)
|
||||||
|
#define MB (1024UL * 1024UL)
|
||||||
|
#define GB (1024UL * 1024UL * 1024UL)
|
||||||
|
|
||||||
|
#define TOTAL_BYTES (2 * GB)
|
||||||
|
#define BUF_SIZE (128 * KB)
|
||||||
|
|
||||||
|
#define MIN(x, y) ((x) <= (y) ? (x) : (y))
|
||||||
|
|
||||||
|
const char SOCK_PATH[] = "echo_socket";
|
||||||
|
|
||||||
|
int create_server_socket() {
|
||||||
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd == -1) {
|
||||||
|
printf("ERROR: failed to create a unix socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_un local;
|
||||||
|
local.sun_family = AF_UNIX;
|
||||||
|
strcpy(local.sun_path, SOCK_PATH);
|
||||||
|
socklen_t len = strlen(local.sun_path) + sizeof(local.sun_family);
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr *)&local, len) == -1) {
|
||||||
|
printf("ERROR: failed to bind\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(fd, 5) == -1) {
|
||||||
|
printf("ERROR: failed to listen\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_client_socket() {
|
||||||
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd == -1) {
|
||||||
|
printf("ERROR: failed to create a unix socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_un remote;
|
||||||
|
remote.sun_family = AF_UNIX;
|
||||||
|
strcpy(remote.sun_path, SOCK_PATH);
|
||||||
|
socklen_t len = strlen(remote.sun_path) + sizeof(remote.sun_family);
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr *)&remote, len) == -1) {
|
||||||
|
printf("ERROR: failed to connect\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
int listen_fd = create_server_socket();
|
||||||
|
if (listen_fd == -1) {
|
||||||
|
printf("ERROR: failed to create server socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_rd_fd = create_client_socket();
|
||||||
|
if (socket_rd_fd == -1) {
|
||||||
|
printf("ERROR: failed to create client socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_un remote;
|
||||||
|
socklen_t len = sizeof(remote);
|
||||||
|
int socket_wr_fd = accept(listen_fd, (struct sockaddr *)&remote, &len);
|
||||||
|
if (socket_wr_fd == -1) {
|
||||||
|
printf("ERROR: failed to accept socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following is same as 'pipe_throughput'
|
||||||
|
|
||||||
|
// Spawn a child process that reads from the pipe
|
||||||
|
posix_spawn_file_actions_t file_actions;
|
||||||
|
posix_spawn_file_actions_init(&file_actions);
|
||||||
|
posix_spawn_file_actions_adddup2(&file_actions, socket_rd_fd, STDIN_FILENO);
|
||||||
|
posix_spawn_file_actions_addclose(&file_actions, socket_wr_fd);
|
||||||
|
|
||||||
|
int child_pid;
|
||||||
|
if (posix_spawn(&child_pid, "dev_null", &file_actions,
|
||||||
|
NULL, NULL, NULL) < 0) {
|
||||||
|
printf("ERROR: failed to spawn a child process\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(socket_rd_fd);
|
||||||
|
|
||||||
|
// Start the timer
|
||||||
|
struct timeval tv_start, tv_end;
|
||||||
|
gettimeofday(&tv_start, NULL);
|
||||||
|
|
||||||
|
// Tell the reader how many data are to be transfered
|
||||||
|
size_t remain_bytes = TOTAL_BYTES;
|
||||||
|
if (write(socket_wr_fd, &remain_bytes, sizeof(remain_bytes)) != sizeof(remain_bytes)) {
|
||||||
|
printf("ERROR: failed to write to pipe\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the reader the buffer size that it should use
|
||||||
|
size_t buf_size = BUF_SIZE;
|
||||||
|
if (write(socket_wr_fd, &buf_size, sizeof(buf_size)) != sizeof(buf_size)) {
|
||||||
|
printf("ERROR: failed to write to pipe\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a specified amount of data in a buffer of specified size
|
||||||
|
char buf[BUF_SIZE] = {0};
|
||||||
|
while (remain_bytes > 0) {
|
||||||
|
size_t len = MIN(buf_size, remain_bytes);
|
||||||
|
if ((len = write(socket_wr_fd, &buf, len)) < 0) {
|
||||||
|
printf("ERROR: failed to write to pipe\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
remain_bytes -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the child process to read all data and exit
|
||||||
|
int status = 0;
|
||||||
|
if (wait4(child_pid, &status, 0, NULL) < 0) {
|
||||||
|
printf("ERROR: failed to wait4 the child process\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the timer
|
||||||
|
gettimeofday(&tv_end, NULL);
|
||||||
|
|
||||||
|
// Calculate the throughput
|
||||||
|
double total_s = (tv_end.tv_sec - tv_start.tv_sec)
|
||||||
|
+ (double)(tv_end.tv_usec - tv_start.tv_usec) / 1000000;
|
||||||
|
if (total_s < 1.0) {
|
||||||
|
printf("WARNING: run long enough to get meaningful results\n");
|
||||||
|
if (total_s == 0) { return 0; }
|
||||||
|
}
|
||||||
|
double total_mb = (double)TOTAL_BYTES / MB;
|
||||||
|
double throughput = total_mb / total_s;
|
||||||
|
printf("Throughput of unix socket is %.2f MB/s\n", throughput);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user