summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Dritschler <timo.dritschler@kit.edu>2014-05-09 18:20:11 +0200
committerTimo Dritschler <timo.dritschler@kit.edu>2014-05-09 18:20:11 +0200
commitb39079922bb4288dee30dfcb89a0fa0d20e81632 (patch)
treebb9dd4bc6ec302ce696661b7066ac825866cc43c
parent18ae33837ee1451dddf265198b51ef3483e2029b (diff)
downloadkiro-b39079922bb4288dee30dfcb89a0fa0d20e81632.tar.gz
kiro-b39079922bb4288dee30dfcb89a0fa0d20e81632.tar.bz2
kiro-b39079922bb4288dee30dfcb89a0fa0d20e81632.tar.xz
kiro-b39079922bb4288dee30dfcb89a0fa0d20e81632.zip
Restructured kiro-server implementation to make it a bit more modular
Added interface to kiro-client to access the memory allocated for communication Added new 'kiro_destroy_connection' to kiro-rdma package Changed interface of 'kiro_destroy_connection_context' and updated server and client accordingly Started to implement a more visual testing routine in test-server Made test-client use commandline arguments for address and port Updated Makefile
-rw-r--r--Makefile2
-rw-r--r--kiro-client.c59
-rw-r--r--kiro-client.h3
-rw-r--r--kiro-rdma.h50
-rw-r--r--kiro-server.c272
-rw-r--r--kiro-server.h25
-rw-r--r--kiro-trb.h2
-rw-r--r--test-client.c14
-rw-r--r--test-server.c156
9 files changed, 404 insertions, 179 deletions
diff --git a/Makefile b/Makefile
index f0f272b..a9d2143 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC=gcc
CFLAGS=-std=c99 -Wall -g -gdwarf-2 $(shell pkg-config --cflags gobject-2.0)
-LDFLAGS= -lrdmacm -libverbs -lpthread $(shell pkg-config --libs gobject-2.0)
+LDFLAGS=-lm -lrdmacm -libverbs -lpthread $(shell pkg-config --libs gobject-2.0)
.PHONY : all
diff --git a/kiro-client.c b/kiro-client.c
index 3df870f..7c328a5 100644
--- a/kiro-client.c
+++ b/kiro-client.c
@@ -53,9 +53,7 @@ struct _KiroClientPrivate {
/* (Not accessible by properties) */
struct rdma_event_channel *ec; // Main Event Channel
struct rdma_cm_id *conn; // Connection to the Server
- KiroTrb *buffer; // Ring Buffer used to hold data from server
-
};
@@ -66,7 +64,6 @@ static void kiro_client_init (KiroClient *self)
{
KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
memset(priv, 0, sizeof(&priv));
- priv->buffer = g_object_new(KIRO_TYPE_TRB, NULL);
}
static void
@@ -74,7 +71,7 @@ kiro_client_finalize (GObject *object)
{
KiroClient *self = KIRO_CLIENT(object);
KiroClientPrivate * priv = KIRO_CLIENT_GET_PRIVATE(self);
- g_object_unref(priv->buffer);
+ //PASS
}
static void
@@ -135,7 +132,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)
if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
{
printf("Failed to allocate Control Flow Memory Container.\n");
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -145,7 +142,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)
if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
{
printf("Failed to register control message memory.\n");
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -155,7 +152,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)
if(rdma_post_recv(priv->conn, priv->conn, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr))
{
printf("Posting preemtive receive for connection failed with error: %i\n", errno);
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -163,7 +160,7 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)
if(rdma_connect(priv->conn, NULL))
{
printf("Failed to establish connection to the server.\n");
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -175,20 +172,20 @@ int kiro_client_connect (KiroClient *self, char *address, char* port)
{
printf("Failure waiting for POST from server.\n");
rdma_disconnect(priv->conn);
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
printf("Got Message from Server.\n");
ctx->peer_mr = (((struct kiro_ctrl_msg *)(ctx->cf_mr_recv->mem))->peer_mri);
- printf("Expected TRB Size is: %u\n",ctx->peer_mr.length);
+ printf("Expected Memory Size is: %u\n",ctx->peer_mr.length);
ctx->rdma_mr = kiro_create_rdma_memory(priv->conn->pd, ctx->peer_mr.length, IBV_ACCESS_LOCAL_WRITE);
if(!ctx->rdma_mr)
{
printf("Failed to allocate memory for receive buffer.\n");
rdma_disconnect(priv->conn);
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -208,7 +205,7 @@ int kiro_client_sync (KiroClient *self)
{
printf("Failed to read from server.\n");
rdma_disconnect(priv->conn);
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
@@ -218,30 +215,42 @@ int kiro_client_sync (KiroClient *self)
{
printf("Failure reading from server.\n");
rdma_disconnect(priv->conn);
- kiro_destroy_connection_context(ctx);
+ kiro_destroy_connection_context(&ctx);
rdma_destroy_ep(priv->conn);
return -1;
}
- if(!kiro_trb_is_setup(priv->buffer))
- {
- //First time setup
- kiro_trb_adopt(priv->buffer, ctx->rdma_mr->mem);
- }
- else
- {
- //Refresh
- kiro_trb_refresh(priv->buffer);
- }
-
- printf("Buffer successfully read from server.\n");
+ printf("Memory successfully read from server.\n");
return 0;
}
+void* kiro_client_get_memory (KiroClient *self)
+{
+ KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+ if(!priv->conn)
+ return NULL;
+ struct kiro_connection_context *ctx = (struct kiro_connection_context *)priv->conn->context;
+ if(!ctx->rdma_mr)
+ return NULL;
+
+ return ctx->rdma_mr->mem;
+}
+size_t kiro_client_get_memory_size (KiroClient *self)
+{
+ KiroClientPrivate *priv = KIRO_CLIENT_GET_PRIVATE(self);
+ if(!priv->conn)
+ return 0;
+
+ struct kiro_connection_context *ctx = (struct kiro_connection_context *)priv->conn->context;
+ if(!ctx->rdma_mr)
+ return 0;
+
+ return ctx->rdma_mr->size;
+}
diff --git a/kiro-client.h b/kiro-client.h
index 61e5676..e3e60de 100644
--- a/kiro-client.h
+++ b/kiro-client.h
@@ -81,6 +81,9 @@ int kiro_client_connect (KiroClient* client, char* dest_addr
int kiro_client_sync (KiroClient* client);
+void* kiro_client_get_memory (KiroClient* client);
+
+size_t kior_client_get_memory_size (KiroClient* client);
G_END_DECLS
diff --git a/kiro-rdma.h b/kiro-rdma.h
index 25040c8..696c880 100644
--- a/kiro-rdma.h
+++ b/kiro-rdma.h
@@ -156,20 +156,52 @@ static void kiro_destroy_rdma_memory (struct kiro_rdma_mem *krm)
}
-static void kiro_destroy_connection_context (struct kiro_connection_context *ctx)
+static void kiro_destroy_connection_context (struct kiro_connection_context **ctx)
{
if(!ctx)
return;
+
+ if(!(*ctx))
+ return;
+
+ if((*ctx)->cf_mr_recv)
+ kiro_destroy_rdma_memory((*ctx)->cf_mr_recv);
+ if((*ctx)->cf_mr_send)
+ kiro_destroy_rdma_memory((*ctx)->cf_mr_send);
+
+ //The RDMA-Memory Region normally contains allocated memory from the USER that has
+ //just been 'registered' for RDMA. DON'T free it! Just deregister it. The user is
+ //responsible for freeing this memory.
+ if((*ctx)->rdma_mr)
+ {
+ if((*ctx)->rdma_mr->mr)
+ ibv_dereg_mr((*ctx)->rdma_mr->mr);
+
+ free((*ctx)->rdma_mr);
+ (*ctx)->rdma_mr = NULL;
+ }
+
+ free(*ctx);
+ *ctx = NULL;
+}
+
+
+static void kiro_destroy_connection (struct kiro_connection **conn)
+{
+ if(!(*conn))
+ return;
+
+ if(!(*conn)->id)
+ return;
- if(ctx->cf_mr_recv)
- kiro_destroy_rdma_memory(ctx->cf_mr_recv);
- if(ctx->cf_mr_send)
- kiro_destroy_rdma_memory(ctx->cf_mr_send);
- if(ctx->rdma_mr)
- kiro_destroy_rdma_memory(ctx->rdma_mr);
+ rdma_disconnect((*conn)->id);
+ struct kiro_connection_context *ctx = (struct kiro_connection_context *)((*conn)->id->context);
+ if(ctx)
+ kiro_destroy_connection_context(&ctx);
- free(ctx);
- ctx = NULL;
+ rdma_destroy_ep((*conn)->id);
+ free(*conn);
+ *conn = NULL;
}
diff --git a/kiro-server.c b/kiro-server.c
index 1ed47f8..c017b07 100644
--- a/kiro-server.c
+++ b/kiro-server.c
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
+#include <arpa/inet.h>
#include <rdma/rdma_verbs.h>
#include <glib.h>
#include "kiro-server.h"
@@ -52,8 +53,6 @@ struct _KiroServerPrivate {
struct rdma_event_channel *ec; // Main Event Channel
struct rdma_cm_id *base; // Base-Listening-Connection
struct kiro_connection *client; // Connection to the client
- KiroTrb *buffer; // Memory Container
-
};
@@ -65,23 +64,16 @@ static void kiro_server_init (KiroServer *self)
{
KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self);
memset(priv, 0, sizeof(&priv));
-
- priv->buffer = g_object_new(KIRO_TYPE_TRB, NULL);
- kiro_trb_reshape(priv->buffer, sizeof(uint64_t), 1000);
- uint64_t a = 0xAFFED00F;
- uint64_t b = 0x1337BEEF;
- kiro_trb_push(priv->buffer, &a);
- kiro_trb_push(priv->buffer, &b);
}
+
static void
kiro_server_finalize (GObject *object)
{
- KiroServer *self = KIRO_SERVER(object);
- KiroServerPrivate * priv = KIRO_SERVER_GET_PRIVATE(self);
- g_object_unref(priv->buffer);
+ //PASS
}
+
static void
kiro_server_class_init (KiroServerClass *klass)
{
@@ -90,8 +82,103 @@ kiro_server_class_init (KiroServerClass *klass)
}
+static int connect_client (struct kiro_connection *client)
+{
+ struct kiro_connection_context *ctx = (struct kiro_connection_context *)calloc(1,sizeof(struct kiro_connection_context));
+ if(!ctx)
+ {
+ printf("Failed to create connection context.\n");
+ rdma_destroy_id(client->id);
+ return -1;
+ }
+
+ ctx->cf_mr_send = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+ ctx->cf_mr_recv = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+ if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+ {
+ printf("Failed to allocate Control Flow Memory Container.\n");
+ goto error;
+ }
+
+ ctx->cf_mr_recv = kiro_create_rdma_memory(client->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+ ctx->cf_mr_send = kiro_create_rdma_memory(client->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
+ if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
+ {
+ printf("Failed to register control message memory.\n");
+ goto error;
+ }
+ ctx->cf_mr_recv->size = ctx->cf_mr_send->size = sizeof(struct kiro_ctrl_msg);
+ client->id->context = ctx;
+
+ if(rdma_post_recv(client->id, client, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr))
+ {
+ printf("Posting preemtive receive for connection failed.\n");
+ goto error;
+ }
+
+ if(rdma_accept(client->id, NULL))
+ {
+ printf("Failed to establish connection to the server.\n");
+ goto error;
+ }
+ printf("Client Connected.\n");
+ return 0;
+
+
+error:
+ rdma_reject(client->id, NULL, 0);
+ kiro_destroy_connection_context(&ctx);
+ rdma_destroy_id(client->id);
+ return -1;
+}
+
+
+static int welcome_client (struct kiro_connection *client, void *mem, size_t mem_size)
+{
+ struct kiro_connection_context *ctx = (struct kiro_connection_context *)(client->id->context);
+ ctx->rdma_mr = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
+ if(!ctx->rdma_mr)
+ {
+ printf("Failed to allocate RDMA Memory Container.\n");
+ return -1;
+ }
+
+ ctx->rdma_mr->mem = mem;
+ ctx->rdma_mr->size = mem_size;
+ ctx->rdma_mr->mr = rdma_reg_read(client->id, ctx->rdma_mr->mem, ctx->rdma_mr->size);
+ if(!ctx->rdma_mr->mr)
+ {
+ printf("Failed to register RDMA Memory Region.\n");
+ kiro_destroy_rdma_memory(ctx->rdma_mr);
+ return -1;
+ }
+
+ struct kiro_ctrl_msg *msg = (struct kiro_ctrl_msg *)(ctx->cf_mr_send->mem);
+ msg->msg_type = KIRO_ACK_RDMA;
+ msg->peer_mri = *(ctx->rdma_mr->mr);
+
+ if(rdma_post_send(client->id, client, ctx->cf_mr_send->mem, ctx->cf_mr_send->size, ctx->cf_mr_send->mr, IBV_SEND_SIGNALED))
+ {
+ printf("Failure while trying to post SEND.\n");
+ kiro_destroy_rdma_memory(ctx->rdma_mr);
+ return -1;
+ }
+
+ struct ibv_wc wc;
+
+ if(rdma_get_send_comp(client->id, &wc) < 0)
+ {
+ printf("Failed to post RDMA MRI to client.\n");
+ kiro_destroy_rdma_memory(ctx->rdma_mr);
+ return -1;
+ }
+ printf("RDMA MRI sent to client.\n");
+
+ return 0;
+}
+
-int kiro_server_start (KiroServer *self, char *address, char *port)
+int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, size_t mem_size)
{
KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self);
@@ -101,16 +188,21 @@ int kiro_server_start (KiroServer *self, char *address, char *port)
return -1;
}
+ if(!mem || mem_size == 0)
+ {
+ printf("Invalid memory given to provide.\n");
+ return -1;
+ }
+
struct rdma_addrinfo hints, *res_addrinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_port_space = RDMA_PS_IB;
hints.ai_flags = RAI_PASSIVE;
if(rdma_getaddrinfo(address, port, &hints, &res_addrinfo))
{
- printf("Failed to bind to address %s:%s\n",address, port);
+ printf("Failed to create address information.");
return -1;
}
- printf("Bound to address %s:%s\n",address, port);
struct ibv_qp_init_attr qp_attr;
memset(&qp_attr, 0, sizeof(qp_attr));
@@ -128,6 +220,25 @@ int kiro_server_start (KiroServer *self, char *address, char *port)
}
printf("Endpoint created.\n");
+ char *addr_local = NULL;
+ struct sockaddr* src_addr = rdma_get_local_addr(priv->base);
+ if(!src_addr)
+ {
+ addr_local = "NONE";
+ }
+ else
+ {
+ addr_local = inet_ntoa(((struct sockaddr_in *)src_addr)->sin_addr);
+ /*
+ if(src_addr->sa_family == AF_INET)
+ addr_local = &(((struct sockaddr_in*)src_addr)->sin_addr);
+ else
+ addr_local = &(((struct sockaddr_in6*)src_addr)->sin6_addr);
+ */
+ }
+
+ printf("Bound to address %s:%s\n",addr_local, port);
+
if(rdma_listen(priv->base, 0))
{
printf("Failed to put server into listening state.\n");
@@ -137,13 +248,10 @@ int kiro_server_start (KiroServer *self, char *address, char *port)
printf("Enpoint listening.\n");
- // ---> *SNIP*
-
priv->client = (struct kiro_connection *)calloc(1, sizeof(struct kiro_connection));
- if(!priv->client)
+ if(!(priv->client))
{
printf("Failed to create container for client connection.\n");
- rdma_destroy_ep(priv->base);
return -1;
}
priv->client->identifier = 0; //First Client
@@ -157,59 +265,20 @@ int kiro_server_start (KiroServer *self, char *address, char *port)
}
printf("Connection Request received.\n");
- struct kiro_connection_context *ctx = (struct kiro_connection_context *)calloc(1,sizeof(struct kiro_connection_context));
- if(!ctx)
- {
- printf("Failed to create connection context.\n");
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
-
- ctx->cf_mr_send = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
- ctx->cf_mr_recv = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
- if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
- {
- printf("Failed to allocate Control Flow Memory Container.\n");
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
-
- ctx->cf_mr_recv = kiro_create_rdma_memory(priv->client->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
- ctx->cf_mr_send = kiro_create_rdma_memory(priv->client->id->pd, sizeof(struct kiro_ctrl_msg), IBV_ACCESS_LOCAL_WRITE);
- if(!ctx->cf_mr_recv || !ctx->cf_mr_send)
- {
- printf("Failed to register control message memory.\n");
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
- ctx->cf_mr_recv->size = ctx->cf_mr_send->size = sizeof(struct kiro_ctrl_msg);
- priv->client->id->context = ctx;
- if(rdma_post_recv(priv->client->id, priv->client, ctx->cf_mr_recv->mem, ctx->cf_mr_recv->size, ctx->cf_mr_recv->mr))
+ if(connect_client(priv->client))
{
- printf("Posting preemtive receive for connection failed.\n");
- kiro_destroy_connection_context(ctx);
+ printf("Client connection failed!\n");
rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
free(priv->client);
return -1;
}
- if(rdma_accept(priv->client->id, NULL))
+ if(welcome_client(priv->client, mem, mem_size))
{
- printf("Failed to establish connection to the server.\n");
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
+ printf("Failed to setup client communication.\n");
+ kiro_destroy_connection(&(priv->client));
+ rdma_destroy_id(priv->base);
return -1;
}
@@ -224,88 +293,17 @@ int kiro_server_start (KiroServer *self, char *address, char *port)
if(rdma_migrate_id(priv->base, priv->ec))
{
printf("Was unable to migrate connection to new Event Channel.\n");
- rdma_disconnect(priv->client->id);
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
-
- printf("Client Connected.\n");
-
-
- ctx->rdma_mr = (struct kiro_rdma_mem *)calloc(1, sizeof(struct kiro_rdma_mem));
- if(!ctx->rdma_mr)
- {
- printf("Failed to allocate RDMA Memory Container.\n");
- rdma_disconnect(priv->client->id);
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
-
- ctx->rdma_mr->mem = kiro_trb_get_raw_buffer(priv->buffer);
- ctx->rdma_mr->size = kiro_trb_get_raw_size(priv->buffer);
- ctx->rdma_mr->mr = rdma_reg_read(priv->client->id, ctx->rdma_mr->mem, ctx->rdma_mr->size);
- if(!ctx->rdma_mr->mr)
- {
- printf("Failed to register RDMA Memory Region.\n");
- rdma_disconnect(priv->client->id);
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
-
- struct kiro_ctrl_msg *msg = (struct kiro_ctrl_msg *)(ctx->cf_mr_send->mem);
- msg->msg_type = KIRO_ACK_RDMA;
- msg->peer_mri = *(ctx->rdma_mr->mr);
-
- if(rdma_post_send(priv->client->id, priv->client, ctx->cf_mr_send->mem, ctx->cf_mr_send->size, ctx->cf_mr_send->mr, IBV_SEND_SIGNALED))
- {
- printf("Failure while trying to post SEND.\n");
- rdma_disconnect(priv->client->id);
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
+ kiro_destroy_connection(&(priv->client));
+ rdma_destroy_id(priv->base);
return -1;
}
- struct ibv_wc wc;
-
- if(rdma_get_send_comp(priv->client->id, &wc) < 0)
- {
- printf("Failed to post RDMA MRI to client.\n");
- rdma_disconnect(priv->client->id);
- kiro_destroy_connection_context(ctx);
- rdma_destroy_ep(priv->base);
- rdma_destroy_ep(priv->client->id);
- free(priv->client);
- return -1;
- }
- printf("RDMA MRI sent to client.\n");
sleep(1);
return 0;
}
-int kiro_server_sync (KiroServer *self)
-{
- //PASS
- return 0;
-}
-
-
-
-
-
-
diff --git a/kiro-server.h b/kiro-server.h
index 1d85419..cb9b57c 100644
--- a/kiro-server.h
+++ b/kiro-server.h
@@ -76,7 +76,30 @@ GObject kiro_server_new (void);
/* server functions */
-int kiro_server_start (KiroServer* server, char* bind_addr, char* bind_port);
+/**
+ * kiro_server_start - Starts the server, providing the given memory
+ * @server: KIRO SERVER to perform the operation on
+ * @bind_addr: Local address to bind the server to
+ * @bind_port: Local port to listen for connections
+ * @mem: Pointer to the memory that is to be provided
+ * @mem_size: Size in bytes of the given memory
+ * Description:
+ * Starts the server to provide the given memory to any connecting
+ * client.
+ * Notes:
+ * If the bind_addr is NULL, the server will bind to the first device
+ * it can find on the machine and listen across all IPs. Otherwise it
+ * will try to bind to the device associated with the given address.
+ * Address is given as a string of either a hostname or a dot-seperated
+ * IPv4 address or a colon-seperated IPv6 hex-address.
+ * If bind_port is NULL the server will choose a free port randomly
+ * and return the chosen port as return value.
+ * If server creation fails, -1 is returned instead.
+ * See also:
+ * kiro_trb_reshape, kiro_trb_adopt,
+ * kiro_trb_clone
+ */
+int kiro_server_start (KiroServer* server, char* bind_addr, char* bind_port, void* mem, size_t mem_size);
G_END_DECLS
diff --git a/kiro-trb.h b/kiro-trb.h
index b1e95a7..5c2b462 100644
--- a/kiro-trb.h
+++ b/kiro-trb.h
@@ -282,7 +282,7 @@ int kiro_trb_clone (KiroTrb* trb, void* source);
* In case of failure, no internal memory will change as if the
* call to kiro_trb_push has never happened.
* See also:
- * kiro_trb_push_dma, kiro_trb_get_element_size, kiro_trb_clone,
+ * kiro_trb_dma_push, kiro_trb_get_element_size, kiro_trb_clone,
* kiro_trb_adopt
*/
int kiro_trb_push (KiroTrb* trb, void* source);
diff --git a/test-client.c b/test-client.c
index 0a318f1..5c78d42 100644
--- a/test-client.c
+++ b/test-client.c
@@ -4,10 +4,16 @@
#include "kiro-client.h"
-int main(void)
+int main ( int argc, char *argv[] )
{
+ if (argc < 3)
+ {
+ printf("Not enough aruments. Usage: ./client <address> <port>\n");
+ return -1;
+ }
KiroClient *client = g_object_new(KIRO_TYPE_CLIENT, NULL);
- kiro_client_connect(client, "192.168.11.61", "60010");
- kiro_client_sync(client);
- return 0;
+ if(-1 != kiro_client_connect(client, argv[1], argv[2]))
+ kiro_client_sync(client);
+ g_object_unref(client);
+ return 0;
} \ No newline at end of file
diff --git a/test-server.c b/test-server.c
index 2b08f15..1becb31 100644
--- a/test-server.c
+++ b/test-server.c
@@ -2,11 +2,165 @@
#include <stdio.h>
#include <stdlib.h>
#include "kiro-server.h"
+#include "kiro-trb.h"
+#include <gmodule.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <math.h>
+
+
+
+static const char g_digits[10][20] = {
+ /* 0 */
+ { 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0xff, 0x00, 0x00, 0xff,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0x00 },
+ /* 1 */
+ { 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0x00 },
+ /* 2 */
+ { 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff },
+ /* 3 */
+ { 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0x00 },
+ /* 4 */
+ { 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0xff },
+ /* 5 */
+ { 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0x00 },
+ /* 6 */
+ { 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0x00 },
+ /* 7 */
+ { 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00 },
+ /* 8 */
+ { 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0x00 },
+ /* 9 */
+ { 0x00, 0xff, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0xff, 0xff, 0x00 }
+};
+
+static const guint DIGIT_WIDTH = 4;
+static const guint DIGIT_HEIGHT = 5;
+
+static void
+print_number (gchar *buffer, guint number, guint x, guint y, guint width)
+{
+ for (int i = 0; i < DIGIT_WIDTH; i++) {
+ for (int j = 0; j < DIGIT_HEIGHT; j++) {
+ char val = (char) g_digits[number][j*DIGIT_WIDTH+i];
+ if(val != 0x00) {
+ //This should make the frame counter appear in a bright yellow
+ val = 0xBE;
+ }
+ buffer[(y+j)*width + (x+i)] = (guint8) val;
+ }
+ }
+}
+
+static void
+print_current_frame (gchar *buffer, guint number, guint width, guint height, GRand *rand)
+{
+ guint divisor = 10000000;
+ int x = 1;
+
+ while (divisor > 0) {
+ print_number(buffer, number / divisor, x, 1, width);
+ number = number % divisor;
+ divisor = divisor / 10;
+ x += DIGIT_WIDTH + 1;
+ }
+
+
+ //Rainbow pattern is the same for every row. Just calculate one single
+ //Scanline, so we can reuse it and dont have to do the whole calculation
+ //for every row again.
+ char default_line[width];
+ for (int p = 0; p < width; p++) {
+ default_line[p] = (char) ((p*256) / (width));
+ }
+
+
+ //Use memcpy to quickly fill every row with the precalculated rainbow
+ //pattern
+ for (guint y = 16; y < height; y++) {
+ guint index = y * width;
+ memcpy(&buffer[index], &default_line[0], width);
+ }
+
+ //This block will fill a square at the center of the image with normal
+ //distributed random data
+ const double mean = 128.0;
+ const double std = 32.0;
+
+ for (guint y = (height/3); y < ((height*2)/3); y++) {
+ guint row_start = y * width;
+ for (guint i = (width/3); i < ((width*2)/3); i++) {
+ int index = row_start + i;
+ double u1 = g_rand_double(rand);
+ double u2 = g_rand_double(rand);
+ double r = sqrt(-2 * log(u1)) * cos(2 * G_PI * u2);
+ buffer[index] = (guint8) (r * std + mean);
+ }
+ }
+}
int main(void)
{
KiroServer *server = g_object_new(KIRO_TYPE_SERVER, NULL);
- kiro_server_start(server, "192.168.11.61", "60010");
+ KiroTrb *rb = g_object_new(KIRO_TYPE_TRB, NULL);
+ kiro_trb_reshape(rb, 512*512, 1000);
+ GRand *rand = g_rand_new();
+ if(0 > kiro_server_start(server, NULL, "60010", kiro_trb_get_raw_buffer(rb), kiro_trb_get_raw_size(rb)))
+ {
+ printf("Failed to start server properly.\n");
+ goto done;
+ }
+
+ guint frame = 0;
+ while(1)
+ {
+ print_current_frame(kiro_trb_dma_push(rb), frame, 512, 512, rand);
+ frame++;
+ }
+
+done:
+ g_rand_free(rand);
+ g_object_unref(rb);
+
return 0;
} \ No newline at end of file