From 2d23900bc82acb810449c5f4ffdd072f55c0a6c1 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Wed, 24 Apr 2013 16:49:51 +0200 Subject: [PATCH] Some refactorings and initial try at O(1) lookup of encoder indices (linker magic provided). --- compiler/C_CodeGen.jrag | 4 +- lib/c/Makefile | 12 ++-- lib/c/labcomm.c | 35 ++++++++--- lib/c/labcomm.h | 24 +++----- lib/c/labcomm.linkscript | 8 +++ lib/c/labcomm_dynamic_buffer_writer.c | 2 + ...fd_reader_writer.c => labcomm_fd_reader.c} | 61 +++++-------------- lib/c/labcomm_fd_reader.h | 12 ++++ lib/c/labcomm_fd_reader_writer.h | 16 ----- lib/c/labcomm_fd_writer.c | 61 +++++++++++++++++++ lib/c/labcomm_fd_writer.h | 12 ++++ lib/c/labcomm_private.h | 34 ++--------- lib/c/test/labcomm_mem_reader.c | 6 +- lib/c/test/labcomm_mem_reader.h | 4 +- lib/c/test/labcomm_mem_writer.c | 1 + lib/c/test/test_labcomm.c | 1 + ...e.c => test_labcomm_basic_type_encoding.c} | 7 ++- 17 files changed, 171 insertions(+), 129 deletions(-) create mode 100644 lib/c/labcomm.linkscript rename lib/c/{labcomm_fd_reader_writer.c => labcomm_fd_reader.c} (52%) create mode 100644 lib/c/labcomm_fd_reader.h delete mode 100644 lib/c/labcomm_fd_reader_writer.h create mode 100644 lib/c/labcomm_fd_writer.c create mode 100644 lib/c/labcomm_fd_writer.h rename lib/c/test/{test_labcomm_private.c => test_labcomm_basic_type_encoding.c} (97%) diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index d445088..f79bbfc 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -803,8 +803,8 @@ aspect C_Signature { } } env.println("};"); - env.println("labcomm_signature_t labcomm_signature_" + - env.prefix + getName() + " = {"); + env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + + env.prefix + getName() + ") = {"); env.indent(); env.println("LABCOMM_SAMPLE, \"" + getName() + "\","); env.println("(int (*)(labcomm_signature_t *, void *))labcomm_sizeof_" + diff --git a/lib/c/Makefile b/lib/c/Makefile index dd08db0..f201fa6 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -2,15 +2,15 @@ # Use LLVM clang if it's found. CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc) -CFLAGS = -g -Wall -Werror -O3 -I. -Itest +CFLAGS = -g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH LDFLAGS = -L. -LDLIBS_TEST = -lcunit -llabcomm +LDLIBS_TEST = -Tlabcomm.linkscript -lcunit -llabcomm -OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader_writer.o labcomm_mem_reader.o labcomm_mem_writer.o +OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o LABCOMMC_PATH=../../compiler LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar -TESTS=test_labcomm_private test_labcomm test_labcomm_errors +TESTS=test_labcomm_basic_type_encoding test_labcomm test_labcomm_errors TEST_DIR=test TESTDATA_DIR=$(TEST_DIR)/testdata TEST_GEN_DIR=$(TESTDATA_DIR)/gen @@ -42,9 +42,9 @@ labcomm.o : labcomm.c labcomm.h labcomm_private.h labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h -$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h +#$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h -$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h +#$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h ethaddr.o: ethaddr.c diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 5256de8..bdcd204 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -7,11 +7,15 @@ #include <errno.h> #include <string.h> +#include <stdarg.h> + #include "labcomm.h" #include "labcomm_private.h" #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" +#define LABCOMM_VERSION "LabComm2013" + typedef struct labcomm_sample_entry { struct labcomm_sample_entry *next; int index; @@ -146,6 +150,8 @@ static labcomm_sample_entry_t *get_sample_by_index( return p; } +#ifdef LABCOMM_ENCODER_LINEAR_SEARCH + static int get_encoder_index( labcomm_encoder_t *e, labcomm_signature_t *s) @@ -163,6 +169,25 @@ static int get_encoder_index( return result; } +#else + +static int get_encoder_index( + labcomm_encoder_t *e, + labcomm_signature_t *s) +{ + int result = 0; + extern labcomm_signature_t labcomm_first_signature; + extern labcomm_signature_t labcomm_last_signature; + + if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) { + //fprintf(stderr, "%d\n", (int)(s - &labcomm_start)); + result = s - &labcomm_first_signature + LABCOMM_USER; + } + return result; +} + +#endif + void labcomm_encoder_start(struct labcomm_encoder *e, labcomm_signature_t *s) { @@ -301,12 +326,6 @@ void labcomm_internal_encode( } } -void labcomm_internal_encoder_user_action(labcomm_encoder_t *e, - int action) -{ - e->writer.write(&e->writer, action); -} - void labcomm_encoder_free(labcomm_encoder_t* e) { e->writer.write(&e->writer, labcomm_writer_free); @@ -501,7 +520,7 @@ static int do_decode_one(labcomm_decoder_t *d) } labcomm_decoder_t *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t), + int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), void *reader_context) { labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t)); @@ -522,7 +541,7 @@ labcomm_decoder_t *labcomm_decoder_new( result->do_decode_one = do_decode_one; result->on_error = on_error_fprintf; result->on_new_datatype = on_new_datatype; - result->reader.read(&result->reader, labcomm_reader_alloc); + result->reader.read(&result->reader, labcomm_reader_alloc, LABCOMM_VERSION); } return result; } diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index baedb8d..48d4cbe 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -1,20 +1,8 @@ #ifndef _LABCOMM_H_ #define _LABCOMM_H_ -#ifdef ARM_CORTEXM3_CODESOURCERY - #include <machine/endian.h> -#else - #include <endian.h> -#endif - -// Some projects can not use stdio.h. -#ifndef LABCOMM_NO_STDIO - #include <stdio.h> -#endif - -#include <stdlib.h> -#include <string.h> #include <stdarg.h> +#include <unistd.h> /* Forward declaration */ struct labcomm_encoder; @@ -94,7 +82,8 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d, */ typedef enum { - labcomm_reader_alloc, + labcomm_reader_alloc, /* (..., char *labcomm_version) + Allocate all neccessary data */ labcomm_reader_free, labcomm_reader_start, labcomm_reader_continue, @@ -108,13 +97,13 @@ typedef struct labcomm_reader { int data_size; int count; int pos; - int (*read)(struct labcomm_reader *, labcomm_reader_action_t); + int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...); int (*ioctl)(struct labcomm_reader *, int, va_list); labcomm_error_handler_callback on_error; } labcomm_reader_t; struct labcomm_decoder *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t), + int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), void *reader_context); int labcomm_decoder_decode_one( struct labcomm_decoder *decoder); @@ -128,7 +117,8 @@ void labcomm_decoder_free( */ typedef enum { - labcomm_writer_alloc, /* Allocate all neccessary data */ + labcomm_writer_alloc, /* (..., char *labcomm_version) + Allocate all neccessary data */ labcomm_writer_free, /* Free all allocated data */ labcomm_writer_start, /* Start writing an ordinary sample */ labcomm_writer_continue, /* Buffer full during ordinary sample */ diff --git a/lib/c/labcomm.linkscript b/lib/c/labcomm.linkscript new file mode 100644 index 0000000..27cf28f --- /dev/null +++ b/lib/c/labcomm.linkscript @@ -0,0 +1,8 @@ +SECTIONS { + labcomm : { + labcomm_first_signature = ABSOLUTE(.) ; + *(labcomm) + labcomm_last_signature = ABSOLUTE(.) ; + } +} +INSERT AFTER .data; diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c index 5e180ec..4c20171 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.c +++ b/lib/c/labcomm_dynamic_buffer_writer.c @@ -1,4 +1,6 @@ #include <errno.h> +#include <stdlib.h> +#include <stdarg.h> #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" diff --git a/lib/c/labcomm_fd_reader_writer.c b/lib/c/labcomm_fd_reader.c similarity index 52% rename from lib/c/labcomm_fd_reader_writer.c rename to lib/c/labcomm_fd_reader.c index 3ddafc4..62cb6b4 100644 --- a/lib/c/labcomm_fd_reader_writer.c +++ b/lib/c/labcomm_fd_reader.c @@ -1,18 +1,29 @@ #include <errno.h> #include <unistd.h> -#include "labcomm_fd_reader_writer.h" +#include <stdlib.h> +#include <string.h> +#include "labcomm_fd_reader.h" #define BUFFER_SIZE 2048 int labcomm_fd_reader( labcomm_reader_t *r, - labcomm_reader_action_t action) + labcomm_reader_action_t action, + ...) { int result = -EINVAL; int *fd = r->context; switch (action) { case labcomm_reader_alloc: { + va_list ap; + va_start(ap, action); + char *version = va_arg(ap, char *); + char *tmp = strdup(version); + + read(*fd, tmp, strlen(version)); + free(tmp); + r->data = malloc(BUFFER_SIZE); if (r->data) { r->data_size = BUFFER_SIZE; @@ -23,6 +34,7 @@ int labcomm_fd_reader( } r->count = 0; r->pos = 0; + va_end(ap); } break; case labcomm_reader_start: case labcomm_reader_continue: { @@ -60,48 +72,3 @@ int labcomm_fd_reader( return result; } -int labcomm_fd_writer( - labcomm_writer_t *w, - labcomm_writer_action_t action, ...) -{ - int result = 0; - int *fd = w->context; - - switch (action) { - case labcomm_writer_alloc: { - w->data = malloc(BUFFER_SIZE); - if (! w->data) { - result = -ENOMEM; - w->data_size = 0; - w->count = 0; - w->pos = 0; - } else { - w->data_size = BUFFER_SIZE; - w->count = BUFFER_SIZE; - w->pos = 0; - } - } break; - case labcomm_writer_free: { - free(w->data); - w->data = 0; - w->data_size = 0; - w->count = 0; - w->pos = 0; - } break; - case labcomm_writer_start: - case labcomm_writer_start_signature: { - w->pos = 0; - } break; - case labcomm_writer_continue: - case labcomm_writer_continue_signature: { - result = write(*fd, w->data, w->pos); - w->pos = 0; - } break; - case labcomm_writer_end: - case labcomm_writer_end_signature: { - result = write(*fd, w->data, w->pos); - w->pos = 0; - } break; - } - return result; -} diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h new file mode 100644 index 0000000..c06cb3a --- /dev/null +++ b/lib/c/labcomm_fd_reader.h @@ -0,0 +1,12 @@ +#ifndef _LABCOMM_FD_READER_H_ +#define _LABCOMM_FD_READER_H_ + +#include "labcomm.h" + +extern int labcomm_fd_reader( + labcomm_reader_t *reader, + labcomm_reader_action_t action, + ...); + +#endif + diff --git a/lib/c/labcomm_fd_reader_writer.h b/lib/c/labcomm_fd_reader_writer.h deleted file mode 100644 index e5125d5..0000000 --- a/lib/c/labcomm_fd_reader_writer.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _LABCOMM_FD_READER_WRITER_H_ -#define _LABCOMM_FD_READER_WRITER_H_ - -#include "labcomm.h" - -extern int labcomm_fd_reader( - labcomm_reader_t *reader, - labcomm_reader_action_t action); - -extern int labcomm_fd_writer( - labcomm_writer_t *writer, - labcomm_writer_action_t action, - ...); - -#endif - diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c new file mode 100644 index 0000000..196e18f --- /dev/null +++ b/lib/c/labcomm_fd_writer.c @@ -0,0 +1,61 @@ +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include "labcomm_fd_writer.h" + +#define BUFFER_SIZE 2048 + +int labcomm_fd_writer( + labcomm_writer_t *w, + labcomm_writer_action_t action, + ...) +{ + int result = 0; + int *fd = w->context; + + switch (action) { + case labcomm_writer_alloc: { + va_list ap; + va_start(ap, action); + char *version = va_arg(ap, char *); + + write(*fd, version, strlen(version)); + w->data = malloc(BUFFER_SIZE); + if (! w->data) { + result = -ENOMEM; + w->data_size = 0; + w->count = 0; + w->pos = 0; + } else { + w->data_size = BUFFER_SIZE; + w->count = BUFFER_SIZE; + w->pos = 0; + } + va_end(ap); + } break; + case labcomm_writer_free: { + free(w->data); + w->data = 0; + w->data_size = 0; + w->count = 0; + w->pos = 0; + } break; + case labcomm_writer_start: + case labcomm_writer_start_signature: { + w->pos = 0; + } break; + case labcomm_writer_continue: + case labcomm_writer_continue_signature: { + result = write(*fd, w->data, w->pos); + w->pos = 0; + } break; + case labcomm_writer_end: + case labcomm_writer_end_signature: { + result = write(*fd, w->data, w->pos); + w->pos = 0; + } break; + } + return result; +} diff --git a/lib/c/labcomm_fd_writer.h b/lib/c/labcomm_fd_writer.h new file mode 100644 index 0000000..ea89eb2 --- /dev/null +++ b/lib/c/labcomm_fd_writer.h @@ -0,0 +1,12 @@ +#ifndef _LABCOMM_FD_WRITER_H_ +#define _LABCOMM_FD_WRITER_H_ + +#include "labcomm.h" + +extern int labcomm_fd_writer( + labcomm_writer_t *writer, + labcomm_writer_action_t action, + ...); + +#endif + diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 2d67778..4271200 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -38,6 +38,12 @@ */ #define LABCOMM_USER 0x40 +/* + * + */ +#define LABCOMM_DECLARE_SIGNATURE(name) \ + labcomm_signature_t name __attribute__((section("labcomm"))) + /* * Semi private decoder declarations */ @@ -194,34 +200,6 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d) return labcomm_read_string(&d->reader); } -static inline int labcomm_buffer_read(struct labcomm_reader *r, - labcomm_reader_action_t action) -{ - // If this gets called, it is an error, - // so note error and let producer proceed - r->context = r; - r->pos = 0; - return 0; -} - -static inline int labcomm_buffer_reader_error(struct labcomm_reader *r) -{ - return r->context != NULL; -} - -static inline void labcomm_buffer_reader_setup( - labcomm_reader_t *r, - void *data, - int length) -{ - r->context = NULL; // Used as error flag - r->data = data; - r->data_size = length; - r->count = length; - r->pos = 0; - r->read = labcomm_buffer_read; -} - /* * Semi private encoder declarations */ diff --git a/lib/c/test/labcomm_mem_reader.c b/lib/c/test/labcomm_mem_reader.c index 0c4e3f1..e111433 100644 --- a/lib/c/test/labcomm_mem_reader.c +++ b/lib/c/test/labcomm_mem_reader.c @@ -1,6 +1,8 @@ #include "labcomm_mem_reader.h" #include <errno.h> +#include <stdlib.h> +#include <string.h> /* This implementation assumes labcomm will call end exactly once after each start * It is not allowed to save data in mcontext->enc_data, @@ -13,7 +15,9 @@ */ // TODO make labcomm use result! -int labcomm_mem_reader(labcomm_reader_t *r, labcomm_reader_action_t action) +int labcomm_mem_reader(labcomm_reader_t *r, + labcomm_reader_action_t action, + ...) { int result = -EINVAL; labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) r->context; diff --git a/lib/c/test/labcomm_mem_reader.h b/lib/c/test/labcomm_mem_reader.h index 5cac018..55b8ea9 100644 --- a/lib/c/test/labcomm_mem_reader.h +++ b/lib/c/test/labcomm_mem_reader.h @@ -12,6 +12,8 @@ struct labcomm_mem_reader_context_t { unsigned char *enc_data; }; -int labcomm_mem_reader( labcomm_reader_t *r, labcomm_reader_action_t action); +int labcomm_mem_reader(labcomm_reader_t *r, + labcomm_reader_action_t action, + ...); #endif diff --git a/lib/c/test/labcomm_mem_writer.c b/lib/c/test/labcomm_mem_writer.c index 294a471..4370361 100644 --- a/lib/c/test/labcomm_mem_writer.c +++ b/lib/c/test/labcomm_mem_writer.c @@ -2,6 +2,7 @@ #include <stddef.h> // For size_t. #include <stdarg.h> +#include <stdlib.h> #include <errno.h> #include "labcomm.h" diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c index fc4004c..1c5020f 100644 --- a/lib/c/test/test_labcomm.c +++ b/lib/c/test/test_labcomm.c @@ -2,6 +2,7 @@ #include "CUnit/Basic.h" #include "CUnit/Console.h" #include <stdbool.h> +#include <stdlib.h> #include <labcomm.h> #include <labcomm_mem_writer.h> diff --git a/lib/c/test/test_labcomm_private.c b/lib/c/test/test_labcomm_basic_type_encoding.c similarity index 97% rename from lib/c/test/test_labcomm_private.c rename to lib/c/test/test_labcomm_basic_type_encoding.c index 33e2a1a..c8dfff7 100644 --- a/lib/c/test/test_labcomm_private.c +++ b/lib/c/test/test_labcomm_basic_type_encoding.c @@ -9,7 +9,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...) exit(1); } -int test_read(struct labcomm_reader *r, labcomm_reader_action_t a) +int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...) { fprintf(stderr, "test_read should not be called\n"); exit(1); @@ -40,7 +40,7 @@ static labcomm_decoder_t decoder = { .context = NULL, .data = buffer, .data_size = sizeof(buffer), - .count = sizeof(buffer), + .count = 0, .pos = 0, .read = test_read, .ioctl = NULL, @@ -60,7 +60,8 @@ typedef unsigned char byte; encoder.writer.pos = 0; \ labcomm_encode_##type(&encoder, value); \ writer_assert(#type, __LINE__, expect_count, (uint8_t*)expect_bytes); \ - decoder.reader.pos = 0; \ + decoder.reader.count = encoder.writer.pos; \ + decoder.reader.pos = 0; \ decoded = labcomm_decode_##type(&decoder); \ if (decoded != value) { \ fprintf(stderr, "Decode error" format " != " format " @%s:%d \n", value, decoded, \ -- GitLab