Commit b415dd0d authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Add support for O(1) signature indexing without resorting to

[GNU] ld tricks (instead we rely on cpp tricks and some heuristics
for memory allocation) so we probably should rewrite labcomm compiler
to generate cleaner code for this use-case.
parent ef2ec643
...@@ -34,3 +34,5 @@ lib/c/test/test_labcomm_generated_encoding ...@@ -34,3 +34,5 @@ lib/c/test/test_labcomm_generated_encoding
lib/java/se/lth/control/labcomm/WriterWrapper.class lib/java/se/lth/control/labcomm/WriterWrapper.class
lib/c/liblabcomm.so.1 lib/c/liblabcomm.so.1
lib/c/test/test_labcomm_pthread_scheduler lib/c/test/test_labcomm_pthread_scheduler
lib/c/liblabcomm_plain_c.so.1
lib/c/test/test_signature_plain_c
...@@ -201,8 +201,14 @@ aspect C_CodeGen { ...@@ -201,8 +201,14 @@ aspect C_CodeGen {
} }
public void Program.C_emitC(C_env env) { public void Program.C_emitC(C_env env) {
C_emitSignature(env); env.print("#if ! defined(LABCOMM_GEN_CODE) && ");
env.println("! defined(LABCOMM_GEN_SIGNATURE)");
env.println("#define LABCOMM_GEN_CODE");
env.println("#define LABCOMM_GEN_SIGNATURE");
env.println("#endif");
env.println("#if defined(LABCOMM_GEN_CODE)");
for (int i = 0; i < getNumDecl(); i++) { for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignatureBitsAndForward(env);
getDecl(i).C_emitDecoder(env); getDecl(i).C_emitDecoder(env);
getDecl(i).C_emitDecoderRegisterHandler(env); getDecl(i).C_emitDecoderRegisterHandler(env);
getDecl(i).C_emitDecoderIoctl(env); getDecl(i).C_emitDecoderIoctl(env);
...@@ -211,6 +217,12 @@ aspect C_CodeGen { ...@@ -211,6 +217,12 @@ aspect C_CodeGen {
getDecl(i).C_emitEncoderIoctl(env); getDecl(i).C_emitEncoderIoctl(env);
getDecl(i).C_emitSizeof(env); getDecl(i).C_emitSizeof(env);
} }
env.println("#endif");
env.println("#if defined(LABCOMM_GEN_SIGNATURE)");
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignature(env);
}
env.println("#endif");
} }
} }
...@@ -441,7 +453,7 @@ aspect C_Decoder { ...@@ -441,7 +453,7 @@ aspect C_Decoder {
public void SampleDecl.C_emitDecoder(C_env env) { public void SampleDecl.C_emitDecoder(C_env env) {
env = env.nestStruct("v"); env = env.nestStruct("v");
env.println("static void decode_" + getName() + "("); env.println("static void decode_" + env.prefix + getName() + "(");
env.indent(); env.indent();
env.println("struct labcomm_reader *r,"); env.println("struct labcomm_reader *r,");
env.println("void (*handle)("); env.println("void (*handle)(");
...@@ -640,7 +652,7 @@ aspect C_Decoder { ...@@ -640,7 +652,7 @@ aspect C_Decoder {
env.indent(); env.indent();
env.println("d,"); env.println("d,");
env.println("&labcomm_signature_" + env.prefix + getName() + ","); env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_decoder_function)decode_" + getName() + ","); env.println("(labcomm_decoder_function)decode_" + env.prefix + getName() + ",");
env.println("(labcomm_handler_function)handler,"); env.println("(labcomm_handler_function)handler,");
env.println("context"); env.println("context");
env.unindent(); env.unindent();
...@@ -701,7 +713,7 @@ aspect C_Encoder { ...@@ -701,7 +713,7 @@ aspect C_Encoder {
public void SampleDecl.C_emitEncoder(C_env env) { public void SampleDecl.C_emitEncoder(C_env env) {
env = env.nestStruct("(*v)"); env = env.nestStruct("(*v)");
env.println("static int encode_" + getName() + "("); env.println("static int encode_" + env.prefix + getName() + "(");
env.indent(); env.indent();
env.println("struct labcomm_writer *w,"); env.println("struct labcomm_writer *w,");
env.println(env.prefix + getName() + " *v"); env.println(env.prefix + getName() + " *v");
...@@ -725,7 +737,7 @@ aspect C_Encoder { ...@@ -725,7 +737,7 @@ aspect C_Encoder {
env.indent(); env.indent();
env.println("return labcomm_internal_encode(e, &labcomm_signature_" + env.println("return labcomm_internal_encode(e, &labcomm_signature_" +
env.prefix + getName() + env.prefix + getName() +
", (labcomm_encoder_function)encode_" + getName() + ", (labcomm_encoder_function)encode_" + env.prefix + getName() +
", v);"); ", v);");
env.unindent(); env.unindent();
env.println("}"); env.println("}");
...@@ -820,7 +832,7 @@ aspect C_Encoder { ...@@ -820,7 +832,7 @@ aspect C_Encoder {
env.indent(); env.indent();
env.println("e,"); env.println("e,");
env.println("&labcomm_signature_" + env.prefix + getName() + ","); env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_encoder_function)encode_" + getName()); env.println("(labcomm_encoder_function)encode_" + env.prefix + getName());
env.unindent(); env.unindent();
env.println(");"); env.println(");");
env.unindent(); env.unindent();
...@@ -868,25 +880,18 @@ aspect C_EncoderIoctl { ...@@ -868,25 +880,18 @@ aspect C_EncoderIoctl {
aspect C_Signature { aspect C_Signature {
public void ASTNode.C_emitSignature(C_env env) { public void ASTNode.C_emitSignatureBitsAndForward(C_env env) {
throw new Error(this.getClass().getName() + throw new Error(this.getClass().getName() +
".C_emitSignature(C_env env)" + ".C_emitSignaturBitsAndForwarde(C_env env)" +
" not declared"); " not declared");
} }
public void Program.C_emitSignature(C_env env) { public void Decl.C_emitSignatureBitsAndForward(C_env env) {
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignature(env);
}
} }
public void Decl.C_emitSignature(C_env env) { public void SampleDecl.C_emitSignatureBitsAndForward(C_env env) {
}
public void SampleDecl.C_emitSignature(C_env env) {
env.println("static unsigned char signature_bytes_" + env.println("static unsigned char signature_bytes_" +
getName() + "[] = {"); env.prefix + getName() + "[] = {");
// C_genFlatSignature(env);
SignatureList signature = signature(); SignatureList signature = signature();
for (int i = 0 ; i < signature.size() ; i++) { for (int i = 0 ; i < signature.size() ; i++) {
String comment = signature.getComment(i); String comment = signature.getComment(i);
...@@ -904,97 +909,31 @@ aspect C_Signature { ...@@ -904,97 +909,31 @@ aspect C_Signature {
} }
env.println("};"); env.println("};");
env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" +
env.prefix + getName() + ") = {"); env.prefix + getName() + ");");
env.indent();
env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" +
env.prefix + getName() + ",");
env.println("sizeof(signature_bytes_" + getName() + "),");
env.println("signature_bytes_"+ getName());
env.unindent();
env.println(" };");
} }
public void ASTNode.C_genFlatSignature(C_env env) { public void ASTNode.C_emitSignature(C_env env) {
throw new Error(this.getClass().getName() + throw new Error(this.getClass().getName() +
".C_genFlatSignature(C_env env)" + ".C_emitSignature(C_env env)" +
" not declared"); " not declared");
} }
public void TypeDecl.C_genFlatSignature(C_env env) { public void Decl.C_emitSignature(C_env env) {
getType().C_genFlatSignature(env);
}
public void SampleDecl.C_genFlatSignature(C_env env) {
getType().C_genFlatSignature(env);
}
public void PrimType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, getToken());
env.println("// " + getName());
}
public void UserType.C_genFlatSignature(C_env env) {
lookupType(getName()).C_genFlatSignature(env);
}
public void ArrayType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, LABCOMM_ARRAY);
env.println("// LABCOMM_ARRAY");
C_genFlatSignature(env, getNumExp());
env.println("// # of dimensions");
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_genFlatSignature(env);
env.println("");
}
getType().C_genFlatSignature(env);
}
public void StructType.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, LABCOMM_STRUCT);
env.println("// LABCOMM_STRUCT");
C_genFlatSignature(env, getNumField());
env.println("// # of fields");
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_genFlatSignature(env);
}
}
public void Field.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, getName());
env.println("");
getType().C_genFlatSignature(env);
}
public void IntegerLiteral.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, Integer.parseInt(getValue()));
env.print("// " + getValue());
}
public void VariableSize.C_genFlatSignature(C_env env) {
C_genFlatSignature(env, 0);
env.print("// _");
} }
public void ASTNode.C_genFlatSignature(C_env env, int value) { public void SampleDecl.C_emitSignature(C_env env) {
env.print(" "); env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" +
for (int i = 24 ; i >= 0 ; i -= 8) { env.prefix + getName() + ") = {");
env.print("0x"); env.indent();
String hex = Integer.toHexString((value >> i) & 0xff); env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
if (hex.length() == 1) { env.print("0"); } env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" +
env.print(hex); env.prefix + getName() + ",");
env.print(", "); env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
} env.println("signature_bytes_" + env.prefix + getName());
env.unindent();
env.println(" };");
} }
public void ASTNode.C_genFlatSignature(C_env env, String value) {
C_genFlatSignature(env, value.length());
env.println("");
env.print(" ");
for (int i = 0 ; i < value.length() ; i++) {
env.print("'" + value.charAt(i) +"', ");
}
}
} }
......
...@@ -5,17 +5,20 @@ CC=gcc ...@@ -5,17 +5,20 @@ CC=gcc
CFLAGS=-g -Wall -Werror -O3 -I. -Itest CFLAGS=-g -Wall -Werror -O3 -I. -Itest
LDFLAGS=-L. LDFLAGS=-L.
#LDLIBS_TEST=-Tlabcomm.linkscript -lcunit -llabcomm #LDLIBS_TEST=-Tlabcomm.linkscript -lcunit -llabcomm
LDLIBS_TEST=-lcunit -llabcomm -Tlabcomm.linkscript -lrt LDLIBS_TEST=-llabcomm -Tlabcomm.linkscript -lrt
LDLIBS_TEST_PLAIN_C=-llabcomm_plain_c -lrt
OBJS=labcomm_memory.o \
labcomm_default_error_handler.o \ OBJS_PLAIN_C=labcomm_memory.o \
labcomm_default_memory.o \ labcomm_default_error_handler.o \
labcomm_default_scheduler.o \ labcomm_default_memory.o \
labcomm_time.o labcomm_scheduler.o \ labcomm_default_scheduler.o \
labcomm_encoder.o labcomm_decoder.o \ labcomm_time.o labcomm_scheduler.o \
labcomm.o \ labcomm_encoder.o labcomm_decoder.o \
labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o \ labcomm.o \
labcomm_pthread_scheduler.o \ labcomm_dynamic_buffer_writer.o \
labcomm_fd_reader.o labcomm_fd_writer.o \
labcomm_pthread_scheduler.o
OBJS=$(OBJS_PLAIN_C) \
labcomm_signature_gnu_ld_tricks.o labcomm_signature_gnu_ld_tricks.o
#FIXME: labcomm_mem_reader.o labcomm_mem_writer.o #FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
...@@ -23,7 +26,8 @@ LABCOMM_JAR=../../compiler/labComm.jar ...@@ -23,7 +26,8 @@ LABCOMM_JAR=../../compiler/labComm.jar
LABCOMM=java -jar $(LABCOMM_JAR) LABCOMM=java -jar $(LABCOMM_JAR)
TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \ TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
test_labcomm_pthread_scheduler test_labcomm_pthread_scheduler \
test_signature_plain_c
# #
#FIXME: test_labcomm test_labcomm_errors #FIXME: test_labcomm test_labcomm_errors
TEST_DIR=test TEST_DIR=test
...@@ -47,14 +51,21 @@ endif ...@@ -47,14 +51,21 @@ endif
.PHONY: all run-test clean distclean .PHONY: all run-test clean distclean
all: liblabcomm.a liblabcomm.so.1 all: liblabcomm.a liblabcomm_plain_c.a \
liblabcomm.so.1 liblabcomm_plain_c.so.1
liblabcomm.a: $(OBJS) liblabcomm.a: $(OBJS)
ar -r liblabcomm.a $^ ar -r $@ $^
liblabcomm_plain_c.a: $(OBJS_PLAIN_C)
ar -r $@ $^
liblabcomm.so.1: $(OBJS:%.o=%.pic.o) liblabcomm.so.1: $(OBJS:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
liblabcomm_plain_c.so.1: $(OBJS_PLAIN_C:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
labcomm.o : labcomm.c labcomm.h labcomm_private.h 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 labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h
...@@ -81,6 +92,19 @@ $(TEST_DIR)/%.o: $(TEST_DIR)/%.c ...@@ -81,6 +92,19 @@ $(TEST_DIR)/%.o: $(TEST_DIR)/%.c
$(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a $(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST)
$(TEST_DIR)/test_signature_plain_c_index.o: \
labcomm_signature_plain_c.c \
$(TEST_DIR)/gen/generated_encoding.c \
$(TEST_DIR)/gen/another_encoding.h \
$(TEST_DIR)/gen/another_encoding.c
$(CC) $(CFLAGS) -o $@ -c $< \
-DALL_LABCOMM_FILES=\"test/test_signature_plain_c.h\"
$(TEST_DIR)/test_signature_plain_c: \
$(TEST_DIR)/test_signature_plain_c.o \
$(TEST_DIR)/test_signature_plain_c_index.o
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_TEST_PLAIN_C)
$(TEST_DIR)/gen: $(TEST_DIR)/gen:
mkdir -p $@ mkdir -p $@
...@@ -118,6 +142,8 @@ clean: ...@@ -118,6 +142,8 @@ clean:
distclean: clean distclean: clean
$(RM) liblabcomm.so.1 $(RM) liblabcomm.so.1
$(RM) liblabcomm.a $(RM) liblabcomm.a
$(RM) liblabcomm_plain_c.a
$(RM) liblabcomm_plain_c.so.1
# Extra dependencies # Extra dependencies
$(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h $(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h
...@@ -126,6 +152,8 @@ $(TEST_DIR)/test_labcomm_generated_encoding.o: labcomm_private.h ...@@ -126,6 +152,8 @@ $(TEST_DIR)/test_labcomm_generated_encoding.o: labcomm_private.h
$(TEST_DIR)/test_labcomm_generated_encoding.o: $(TEST_DIR)/gen/generated_encoding.h $(TEST_DIR)/test_labcomm_generated_encoding.o: $(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/test_labcomm: $(TEST_GEN_DIR)/test_sample.o $(TEST_DIR)/test_labcomm: $(TEST_GEN_DIR)/test_sample.o
$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/another_encoding.h
$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/generated_encoding.h
labcomm_fd_reader.o: labcomm_private.h labcomm_fd_reader.o: labcomm_private.h
labcomm_fd_writer.o: labcomm_private.h labcomm_fd_writer.o: labcomm_private.h
labcomm_dynamic_buffer_writer.o: labcomm_private.h labcomm_dynamic_buffer_writer.o: labcomm_private.h
...@@ -64,8 +64,10 @@ ...@@ -64,8 +64,10 @@
/* /*
* *
*/ */
#ifndef LABCOMM_DECLARE_SIGNATURE
#define LABCOMM_DECLARE_SIGNATURE(name) \ #define LABCOMM_DECLARE_SIGNATURE(name) \
struct labcomm_signature __attribute__((section("labcomm"),aligned(1))) name struct labcomm_signature __attribute__((section("labcomm"),aligned(1))) name
#endif
/* /*
* Semi private dynamic memory declarations * Semi private dynamic memory declarations
......
/* /*
labcomm_signature_gnu_ld_tricks.h -- signature handling. labcomm_signature_gnu_ld_tricks.c -- signature handling.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se> Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......
/*
labcomm_signature_plain_c.c -- signature handling.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define LABCOMM_DECLARE_SIGNATURE(name) \
struct labcomm_signature __attribute__((aligned(1))) name
#include <errno.h>
#include "labcomm.h"
#include "labcomm_signature.h"
#include "labcomm_private.h"
/* NB: We need to mimic forward declarations done in generated code */
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1);
#define LABCOMM_GEN_CODE
#include ALL_LABCOMM_FILES
#undef LABCOMM_GEN_CODE
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2);
/* NB: We need to force our sentinels out of bss segment, hence -1 */
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1) = { -1, NULL, NULL, 0, NULL};
#define LABCOMM_GEN_SIGNATURE
#include ALL_LABCOMM_FILES
#undef LABCOMM_GEN_SIGNATURE
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2) = { -1, NULL, NULL, 0, NULL};
int labcomm_signature_local_index(struct labcomm_signature *s)
{
int result = -ENOENT;
struct labcomm_signature *labcomm_first_signature;
struct labcomm_signature *labcomm_last_signature;
if (&labcomm_sentinel_1 < &labcomm_sentinel_2) {
labcomm_first_signature = &labcomm_sentinel_1;
labcomm_last_signature = &labcomm_sentinel_2;
} else {
labcomm_first_signature = &labcomm_sentinel_2;
labcomm_last_signature = &labcomm_sentinel_1;
}
if (labcomm_first_signature <= s && s < labcomm_last_signature) {
result = (int)(s - labcomm_first_signature) + LABCOMM_USER - 1;
}
return result;
}
sample void V;
sample byte B;
#include <stdlib.h>
#include <stdio.h>
#include "test/gen/another_encoding.h"
#include "test/gen/generated_encoding.h"
extern int labcomm_signature_local_index(struct labcomm_signature *s);
static void info(char *name, char *full_name,
struct labcomm_signature *signature) {
printf("%s %s %p -> %d\n", name, full_name, signature,
labcomm_signature_local_index(signature));
if (labcomm_signature_local_index(signature) < 0x40) {
exit(1);
}
};
int main(int argc, char *argv[])
{
#define FUNC(name, full_name) \
extern struct labcomm_signature labcomm_signature_##full_name; \
info( #name, #full_name, &labcomm_signature_##full_name)
LABCOMM_FORALL_SAMPLES_generated_encoding(FUNC, ;);
LABCOMM_FORALL_SAMPLES_another_encoding(FUNC, ;);
return 0;
}
#include "gen/generated_encoding.c"
#include "gen/another_encoding.c"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment