diff options
-rw-r--r-- | vpp-api/lua/.gitignore | 2 | ||||
-rw-r--r-- | vpp-api/lua/Makefile | 6 | ||||
-rw-r--r-- | vpp-api/lua/README.md | 47 | ||||
-rw-r--r-- | vpp-api/lua/cough.c | 183 | ||||
-rw-r--r-- | vpp-api/lua/vpp-lapi.lua | 30 |
5 files changed, 28 insertions, 240 deletions
diff --git a/vpp-api/lua/.gitignore b/vpp-api/lua/.gitignore deleted file mode 100644 index 061eabdc5e8..00000000000 --- a/vpp-api/lua/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# A .gitignore to avoid ignoring the Makefile -!Makefile diff --git a/vpp-api/lua/Makefile b/vpp-api/lua/Makefile deleted file mode 100644 index b5a95b2fe9d..00000000000 --- a/vpp-api/lua/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: libcough.so - -libcough.so: cough.c - gcc -o libcough.so -shared -fPIC cough.c -clean: - rm -f libcough.so diff --git a/vpp-api/lua/README.md b/vpp-api/lua/README.md index 3fc93b888a9..4ecdb34d2f3 100644 --- a/vpp-api/lua/README.md +++ b/vpp-api/lua/README.md @@ -6,44 +6,39 @@ To run the examples here: 1) install luajit - "sudo apt-get install luajit" on ubuntu -2) make build-vpp-api in the top directory +2) "make build-vpp-api" in the top VPP directory -3) "make" in this directory to build libcough.so +3) "make run" in a separate terminal window + This ensures you have an instance of VPP running -4) "make run" in a separate terminal window - -5) sudo luajit examples/example-cli.lua +4) sudo luajit examples/example-cli.lua This will result in something like this: -libcough detected - -Version: 17.01-rc0~37-g8b3191e -00000000 31 37 2E 30 31 2D 72 63 30 7E 33 37 2D 67 38 62 17.01-rc0~37-g8b -00000010 33 31 39 31 65 00 00 00 00 00 00 00 00 00 00 00 3191e........... +Version: +00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ -{ [1] = { ["luaapi_message_name"] = show_version_reply,["program"] = vpe,["version"] = 17.01-rc0~37-g8b3191e,["build_date"] = Fri Nov 11 15:30:21 UTC 2016,["retval"] = 0,["build_directory"] = /home/ubuntu/vpp,["_vl_msg_id"] = 166,["context"] = 0,} ,} +{ [1] = { ["luaapi_message_name"] = show_version_reply,["program"] = vpe,["version"] = ,["build_date"] = Fri Nov 25 10:58:48 UTC 2016,["retval"] = 0,["build_directory"] = /home/ubuntu/vpp,["_vl_msg_id"] = 170,["context"] = 0,} ,} --- -{ [1] = { ["luaapi_message_name"] = cli_inband_reply,["_vl_msg_id"] = 90,["length"] = 94,["reply"] = vpp v17.01-rc0~37-g8b3191e built by ubuntu on vpp-lapi-commit at Fri Nov 11 15:30:21 UTC 2016 +{ [1] = { ["luaapi_message_name"] = cli_inband_reply,["_vl_msg_id"] = 94,["length"] = 66,["reply"] = vpp v built by ubuntu on vpp-toys at Fri Nov 25 10:58:48 UTC 2016 ,["retval"] = 0,["context"] = 0,} ,} --- -6) You can also run the performance test bench: +5) You can also run the performance test bench: $ sudo luajit bench.lua -libcough detected - -10001 iterations, average speed 4108LL per second -10001 iterations, average speed 4660LL per second -10001 iterations, average speed 4095LL per second -10001 iterations, average speed 4542LL per second -10001 iterations, average speed 8048LL per second -10001 iterations, average speed 6805LL per second -10001 iterations, average speed 5170LL per second -10001 iterations, average speed 6585LL per second -10001 iterations, average speed 6714LL per second -10001 iterations, average speed 6942LL per second -Average tps across the tests: 5766LL +10001 iterations, average speed 5624LL per second +10001 iterations, average speed 6650LL per second +10001 iterations, average speed 6053LL per second +10001 iterations, average speed 7056LL per second +10001 iterations, average speed 6388LL per second +10001 iterations, average speed 5849LL per second +10001 iterations, average speed 6321LL per second +10001 iterations, average speed 6368LL per second +10001 iterations, average speed 5958LL per second +10001 iterations, average speed 6482LL per second +Average tps across the tests: 6274LL Note: the above is run in an lxd container running inside 2-core xhyve VM on a Macbook Pro, so I would not take the performance numbers for granted :) diff --git a/vpp-api/lua/cough.c b/vpp-api/lua/cough.c deleted file mode 100644 index 4251c732202..00000000000 --- a/vpp-api/lua/cough.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * This is a temporary helper library to seamlessly run against - * the current API as exposed by libpneum. - * In the future once the sync API is exposed as well as - * a way to free the received data, this can go away. - */ - -#include <dlfcn.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <stdlib.h> -#include <pthread.h> - -pthread_mutex_t mut; -pthread_mutex_t *cb_lock = &mut; - -void *pneum_handle = NULL; - -typedef void* (*arbitrary)(); - -int (*orig_pneum_connect)(char *name, char *chroot_prefix) = NULL; -int (*orig_pneum_connect_sync)(char *name, char *chroot_prefix) = NULL; -int (*orig_pneum_disconnect)(void) = NULL; -int (*orig_pneum_read)(char **data, int *l) = NULL; -int (*orig_pneum_write)(char *data, int len) = NULL; -int (*orig_pneum_has_data)(void) = NULL; -int (*orig_pneum_data_free)(char *data) = NULL; - -arbitrary my_function = NULL; - -typedef uint8_t u8; -typedef uint32_t u32; - -u8 *cough_read_buffer; -u32 cough_read_buffer_size = 1000000; -u32 cough_read_head = 0; -u32 cough_read_lock_start = 0; /* lock_start till head is busy memory */ -u32 cough_read_tail = 0; - - -int wrap_pneum_callback(char *data, int len) { - // printf("Cough callback! with %d bytes\n", len); - pthread_mutex_lock(cb_lock); - if(cough_read_lock_start == cough_read_head) { - // printf("Reset read head!\n"); - cough_read_head = 0; - cough_read_tail = 0; - cough_read_lock_start = 0; - } - u32 store_len = len; - memcpy(cough_read_buffer + cough_read_head, &store_len, sizeof(u32)); - cough_read_head += sizeof(u32); - memcpy(cough_read_buffer + cough_read_head, data, len); - cough_read_head += len; - pthread_mutex_unlock(cb_lock); - return len; -} - -int cough_pneum_attach(char *pneum_fname, char *cough_fname) { - /* this is needed to make the pneum aware of the wrap_pneum_callback */ - pneum_handle = dlopen(cough_fname, RTLD_NOW|RTLD_GLOBAL); - /* now let's try to load pneum itself */ - pneum_handle = dlopen(pneum_fname, RTLD_NOW|RTLD_GLOBAL); - if (pneum_handle) { - *(void**)(&orig_pneum_connect) = dlsym(pneum_handle,"pneum_connect"); - *(void**)(&orig_pneum_connect_sync) = dlsym(pneum_handle,"pneum_connect_sync"); - *(void**)(&orig_pneum_disconnect) = dlsym(pneum_handle,"pneum_disconnect"); - *(void**)(&orig_pneum_read) = dlsym(pneum_handle,"pneum_read"); - *(void**)(&orig_pneum_write) = dlsym(pneum_handle,"pneum_write"); - *(void**)(&orig_pneum_has_data) = dlsym(pneum_handle,"pneum_has_data"); - *(void**)(&orig_pneum_data_free) = dlsym(pneum_handle,"pneum_data_free"); - // If you uncomment the below line we pretend we have an async-only libpneum - orig_pneum_connect_sync = NULL; - cough_read_buffer = malloc(cough_read_buffer_size); - } else { - printf("Could not get cough handle\n"); - printf("Error: %s", dlerror()); - return -1; - } - - *(void**)(&my_function) = dlsym(pneum_handle,"something"); -} - - -int pneum_connect(char *name, char *chroot_prefix) { - if(orig_pneum_connect) { - return(orig_pneum_connect(name, chroot_prefix)); - } else { - printf("COUGH: pneum_connect\n"); - return -1; - } -} -int pneum_connect_sync(char *name, char *chroot_prefix) { - if(orig_pneum_connect_sync) { - int ret = (orig_pneum_connect_sync(name, chroot_prefix)); - return ret; - } else { - return(orig_pneum_connect(name, chroot_prefix)); - } -} - - -int pneum_disconnect(void) { - if(orig_pneum_disconnect) { - return orig_pneum_disconnect(); - } else { - printf("COUGH: pneum_disconnect\n"); - return -1; - } -} - -int pneum_has_data(void) { - if (orig_pneum_connect_sync) { - /* always return 1 in a pass-through case */ - return 1; - } else { - // printf("COUGH: pneum_has_data\n"); - return (cough_read_head != cough_read_tail); - } -} - - -int pneum_read(char **data, int *l) { - if(orig_pneum_connect_sync) { - return orig_pneum_read(data, l); - } else { - while(!pneum_has_data()); - u32 n_bytes; - pthread_mutex_lock(cb_lock); - memcpy(&n_bytes, cough_read_buffer + cough_read_tail, sizeof(u32)); - cough_read_tail += sizeof(u32); - void * dataptr = (void *) (cough_read_buffer + cough_read_tail); - *data = dataptr; - cough_read_tail += n_bytes; - *l = n_bytes; - pthread_mutex_unlock(cb_lock); - return n_bytes; - } -} - -int pneum_write(char *data, int len) { - if(orig_pneum_write) { - return(orig_pneum_write(data, len)); - } else { - printf("COUGH: pneum_write\n"); - return -1; - } -} - -void pneum_data_free(char *data) { - if (orig_pneum_connect_sync) { - if(orig_pneum_data_free) { - orig_pneum_data_free(data); - } else { - printf("COUGH: pneum_data_free\n"); - } - } else { - u32 *len; - uint32_t index = ((u8*)data) - cough_read_buffer; - pthread_mutex_lock(cb_lock); - if ((index < cough_read_head) && (index > cough_read_lock_start)) { - len = (void *)(data - sizeof(u32)); - cough_read_lock_start = index + *len; - } - pthread_mutex_unlock(cb_lock); - } -} diff --git a/vpp-api/lua/vpp-lapi.lua b/vpp-api/lua/vpp-lapi.lua index 4f2e3f53d59..c88b456d260 100644 --- a/vpp-api/lua/vpp-lapi.lua +++ b/vpp-api/lua/vpp-lapi.lua @@ -273,33 +273,17 @@ end function vpp.init(vpp, args) local pneum_api = args.pneum_api or [[ int cough_pneum_attach(char *pneum_path, char *cough_path); - int pneum_connect(char *name, char *chroot_prefix); - int pneum_connect_sync(char *name, char *chroot_prefix); + int pneum_connect(char *name, char *chroot_prefix, void *cb); int pneum_disconnect(void); int pneum_read(char **data, int *l); int pneum_write(char *data, int len); - -void pneum_data_free(char *data); + void pneum_free(char *data); ]] vpp.pneum_path = args.pneum_path ffi.cdef(pneum_api) local init_res = 0 - if pcall(function() - vpp.cough_path = args.cough_path or "./libcough.so" - vpp.cough = ffi.load(vpp.cough_path) - end) then - pcall(function() - if(vpp.cough.cough_pneum_attach) then - vpp.pneum_is_cough = true - print("libcough detected\n") - init_res = vpp.cough.cough_pneum_attach(vpp.c_str(vpp.pneum_path), vpp.c_str(vpp.cough_path)) - vpp.pneum = vpp.cough - end - end) - else - vpp.pneum = ffi.load(vpp.pneum_path) - end + vpp.pneum = ffi.load(vpp.pneum_path) if (init_res < 0) then return nil end @@ -463,9 +447,9 @@ void pneum_data_free(char *data); local len = 0 local val = nil if field.array and (type(v) == "table") then - print("NTFY: field " .. tostring(k) .. " in message " .. tostring(c_type) .. " is an array") + -- print("NTFY: field " .. tostring(k) .. " in message " .. tostring(c_type) .. " is an array") for field_i, field_v in ipairs(v) do - print("NTFY: setting member#" .. tostring(field_i) .. " to value " .. vpp.dump(field_v)) + -- print("NTFY: setting member#" .. tostring(field_i) .. " to value " .. vpp.dump(field_v)) local field_len, field_val = lua2c(field.c_type, field_v, dst[k][field_i-1]) len = len + field_len end @@ -544,7 +528,7 @@ function vpp.connect(vpp, client_name) if client_name then name = client_name end - local ret = vpp.pneum.pneum_connect_sync(vpp.c_str(client_name), nil) + local ret = vpp.pneum.pneum_connect(vpp.c_str(client_name), nil, nil) if tonumber(ret) == 0 then vpp.is_connected = true end @@ -712,7 +696,7 @@ function vpp.api_read(vpp) out["luaapi_message_name"] = reply_msg_name end - vpp.pneum.pneum_data_free(ffi.cast('void *',rep[0])) + vpp.pneum.pneum_free(ffi.cast('void *',rep[0])) return reply_msg_name, out end |