From b39079922bb4288dee30dfcb89a0fa0d20e81632 Mon Sep 17 00:00:00 2001 From: Timo Dritschler Date: Fri, 9 May 2014 18:20:11 +0200 Subject: 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 --- Makefile | 2 +- kiro-client.c | 59 +++++++------ kiro-client.h | 3 + kiro-rdma.h | 50 +++++++++-- kiro-server.c | 272 +++++++++++++++++++++++++++++----------------------------- kiro-server.h | 25 +++++- kiro-trb.h | 2 +- test-client.c | 14 ++- test-server.c | 156 ++++++++++++++++++++++++++++++++- 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 #include #include +#include #include #include #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
\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 #include #include "kiro-server.h" +#include "kiro-trb.h" +#include +#include +#include +#include + + + +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 -- cgit v1.2.3