[virglrenderer-devel] [PATCH 1/1] vtest: command dispatch now uses a jump-table

Nathan Gauër nathan.gauer at lse.epita.fr
Mon Jun 4 12:42:28 UTC 2018


removed the switch and goto based loop.
To add a command, create the corresponding define in vtest_protocol.h and
an entry in the jump-table (vrend_server.c).

Signed-off-by: Nathan Gauër <nathan.gauer at lse.epita.fr>
---
 vtest/vtest.h          |  11 ++---
 vtest/vtest_renderer.c |  17 +++++--
 vtest/vtest_server.c   | 108 ++++++++++++++++++++++-------------------
 3 files changed, 75 insertions(+), 61 deletions(-)

diff --git a/vtest/vtest.h b/vtest/vtest.h
index deb6618..6b1d91d 100644
--- a/vtest/vtest.h
+++ b/vtest/vtest.h
@@ -27,10 +27,10 @@
 #include <errno.h>
 int vtest_create_renderer(int in_fd, int out_fd, uint32_t length);
 
-int vtest_send_caps(void);
+int vtest_send_caps(uint32_t length_dw);
 
-int vtest_create_resource(void);
-int vtest_resource_unref(void);
+int vtest_create_resource(uint32_t length_dw);
+int vtest_resource_unref(uint32_t length_dw);
 int vtest_submit_cmd(uint32_t length_dw);
 
 int vtest_transfer_get(uint32_t length_dw);
@@ -38,10 +38,9 @@ int vtest_transfer_put(uint32_t length_dw);
 
 int vtest_block_read(int fd, void *buf, int size);
 
-int vtest_resource_busy_wait(void);
-int vtest_renderer_create_fence(void);
+int vtest_resource_busy_wait(uint32_t length_dw);
+int vtest_renderer_create_fence(uint32_t length_dw);
 int vtest_poll(void);
 
 void vtest_destroy_renderer(void);
 #endif
-
diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c
index 3b8fe1a..fb34955 100644
--- a/vtest/vtest_renderer.c
+++ b/vtest/vtest_renderer.c
@@ -35,6 +35,8 @@
 #include "vtest_protocol.h"
 #include "util.h"
 
+#define UNUSED_PARAMETER(Param) (void)Param
+
 static int ctx_id = 1;
 static int fence_id = 1;
 
@@ -153,8 +155,9 @@ void vtest_destroy_renderer(void)
   renderer.out_fd = -1;
 }
 
-int vtest_send_caps(void)
+int vtest_send_caps(uint32_t length_dw)
 {
+    UNUSED_PARAMETER(length_dw);
     uint32_t  max_ver, max_size;
     void *caps_buf;
     uint32_t hdr_buf[2];
@@ -182,8 +185,9 @@ end:
     return 0;
 }
 
-int vtest_create_resource(void)
+int vtest_create_resource(uint32_t length_dw)
 {
+    UNUSED_PARAMETER(length_dw);
     uint32_t res_create_buf[VCMD_RES_CREATE_SIZE];
     struct virgl_renderer_resource_create_args args;
     int ret;
@@ -211,8 +215,9 @@ int vtest_create_resource(void)
     return ret;
 }
 
-int vtest_resource_unref(void)
+int vtest_resource_unref(uint32_t length_dw)
 {
+    UNUSED_PARAMETER(length_dw);
     uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE];
     int ret;
     uint32_t handle;
@@ -347,8 +352,9 @@ int vtest_transfer_put(uint32_t length_dw)
     return 0;
 }
 
-int vtest_resource_busy_wait(void)
+int vtest_resource_busy_wait(uint32_t length_dw)
 {
+  UNUSED_PARAMETER(length_dw);
   uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE];
   int ret, fd;
   int flags;
@@ -392,8 +398,9 @@ int vtest_resource_busy_wait(void)
   return 0;
 }
 
-int vtest_renderer_create_fence(void)
+int vtest_renderer_create_fence(uint32_t length_dw)
 {
+  UNUSED_PARAMETER(length_dw);
   virgl_renderer_create_fence(fence_id++, ctx_id);
   return 0;
 }
diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c
index 918639b..d9b8077 100644
--- a/vtest/vtest_server.c
+++ b/vtest/vtest_server.c
@@ -86,67 +86,75 @@ static int wait_for_socket_accept(int sock)
     return -1;
 }
 
+static int (*_commands_ftable[])(uint32_t length_dw) = {
+    NULL /* CMD ids starts at 1 */,
+    vtest_send_caps,
+    vtest_create_resource,
+    vtest_resource_unref,
+    vtest_transfer_get,
+    vtest_transfer_put,
+    vtest_submit_cmd,
+    vtest_resource_busy_wait,
+    NULL /* vtest_create_renderer */,
+};
+
 static int run_renderer(int in_fd, int out_fd)
 {
+#define COMMAND_COUNT (sizeof(_commands_ftable) / sizeof(*_commands_ftable))
+
     int ret;
     uint32_t header[VTEST_HDR_SIZE];
     bool inited = false;
-again:
-    ret = vtest_wait_for_fd_read(in_fd);
-    if (ret < 0)
-      goto fail;
-
-    ret = vtest_block_read(in_fd, &header, sizeof(header));
-
-    if (ret == 8) {
-      if (!inited) {
-	if (header[1] != VCMD_CREATE_RENDERER)
-	  goto fail;
-	ret = vtest_create_renderer(in_fd, out_fd, header[0]);
-	inited = true;
-      }
-      vtest_poll();
-      switch (header[1]) {
-      case VCMD_GET_CAPS:
-	ret = vtest_send_caps();
-	break;
-      case VCMD_RESOURCE_CREATE:
-	ret = vtest_create_resource();
-	break;
-      case VCMD_RESOURCE_UNREF:
-	ret = vtest_resource_unref();
-	break;
-      case VCMD_SUBMIT_CMD:
-	ret = vtest_submit_cmd(header[0]);
-	break;
-      case VCMD_TRANSFER_GET:
-	ret = vtest_transfer_get(header[0]);
-	break;
-      case VCMD_TRANSFER_PUT:
-	ret = vtest_transfer_put(header[0]);
-	break;
-      case VCMD_RESOURCE_BUSY_WAIT:
-        vtest_renderer_create_fence();
-	ret = vtest_resource_busy_wait();
-	break;
-      default:
-	break;
-      }
 
-      if (ret < 0) {
-	goto fail;
-      }
+    do {
+        ret = vtest_wait_for_fd_read(in_fd);
+        if (ret < 0) {
+            break;
+        }
+
+        ret = vtest_block_read(in_fd, &header, sizeof(header));
+        if (ret != 8) {
+            break;
+        }
+
+        if (!inited) {
+            /* The first command MUST be VCMD_CREATE_RENDERER */
+            if (header[1] != VCMD_CREATE_RENDERER) {
+                break;
+            }
+
+            ret = vtest_create_renderer(in_fd, out_fd, header[0]);
+            inited = true;
+            vtest_poll();
+            continue;
+        }
+
+        vtest_poll();
+        if (header[1] <= 0 || header[1] > COMMAND_COUNT) {
+            break;
+        }
+
+        /* only specific case to handle */
+        if (header[1] == VCMD_RESOURCE_BUSY_WAIT) {
+            vtest_renderer_create_fence(header[0]);
+        }
+
+        if (_commands_ftable[header[1]] == NULL) {
+            break;
+        }
+
+        ret = _commands_ftable[header[1]](header[0]);
+        if (ret < 0) {
+            break;
+        }
+    } while (1);
 
-      goto again;
-    }
-    if (ret <= 0) {
-      goto fail;
-    }
-fail:
     fprintf(stderr, "socket failed - closing renderer\n");
+
     vtest_destroy_renderer();
     close(in_fd);
     return 0;
+#undef COMMAND_COUNT
 }
 
 int main(int argc, char **argv)
-- 
2.17.0



More information about the virglrenderer-devel mailing list