X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=genevent-new%2Fgenevent.c;h=a478e03b0c308e3a703f9ad05d689708409f270e;hb=2d097aba294e1ce388f16b54f5b488d0d138abc8;hp=f3768ce7ce378007898c8e242280438c09c836aa;hpb=bd7b8ca6aac5ea77714987798e709620b5f3fc3f;p=lttv.git diff --git a/genevent-new/genevent.c b/genevent-new/genevent.c index f3768ce7..a478e03b 100644 --- a/genevent-new/genevent.c +++ b/genevent-new/genevent.c @@ -1582,13 +1582,251 @@ int print_event_logging_function(char *basename, facility_t *fac, return 0; } -/* print_event_logging_function_user +/* print_event_logging_function_user_generic * Print the logging function of an event for userspace tracing. This is the * core of genevent */ -int print_event_logging_function_user(char *basename, facility_t *fac, +int print_event_logging_function_user_generic(char *basename, facility_t *fac, event_t *event, FILE *fd) { - fprintf(fd, "static inline int trace_%s(\n", basename); + char *attrib; + + fprintf(fd, "#ifndef LTT_TRACE_FAST\n"); + + if(event->no_instrument_function) { + attrib = "__attribute__((no_instrument_function)) "; + } else { + attrib = ""; + } + if(event->param_buffer) { + fprintf(fd, "static inline %sint trace_%s_param_buffer(\n", attrib, basename); + } else { + fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename); + } + int has_argument = 0; + int has_type_fixed = 0; + + if(event->param_buffer) { + if(has_argument) { + fprintf(fd, ","); + fprintf(fd, "\n"); + } + print_tabs(2, fd); + fprintf(fd, "void *buffer"); + has_argument = 1; + fprintf(fd, ","); + fprintf(fd, "\n"); + print_tabs(2, fd); + fprintf(fd, "size_t reserve_size"); + } else { + for(unsigned int j = 0; j < event->fields.position; j++) { + /* For each field, print the function argument */ + field_t *f = (field_t*)event->fields.array[j]; + type_descriptor_t *t = f->type; + if(has_argument) { + fprintf(fd, ","); + fprintf(fd, "\n"); + } + if(print_arg(t, fd, 2, basename, f->name)) return 1; + has_argument = 1; + } + } + if(!has_argument) { + print_tabs(2, fd); + fprintf(fd, "void"); + } + fprintf(fd,")\n"); + fprintf(fd, + "#ifndef LTT_TRACE\n"); + fprintf(fd, "{\n"); + fprintf(fd, "}\n"); + fprintf(fd,"#else\n"); + fprintf(fd, "{\n"); + /* Print the function variables */ + print_tabs(1, fd); + fprintf(fd, "int ret = 0;\n"); + if(event->param_buffer) { + print_tabs(1, fd); + fprintf(fd, "reserve_size = ltt_align(reserve_size, sizeof(void *));\n"); + print_tabs(1, fd); + fprintf(fd, "{\n"); + goto do_syscall; + } + print_tabs(1, fd); + fprintf(fd, "void *buffer = NULL;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n"); + print_tabs(1, fd); + fprintf(fd, "size_t *to_base = &real_to_base;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t real_to = 0;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t *to = &real_to;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t real_len = 0;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t *len = &real_len;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t reserve_size;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t slot_size;\n"); + print_tabs(1, fd); + + if(event->fields.position > 0) { + for(unsigned int i=0;ifields.position;i++){ + /* Search for at least one child with fixed size. It means + * we need local variables.*/ + field_t *field = (field_t*)(event->fields.array[i]); + type_descriptor_t *type = field->type; + has_type_fixed = has_type_local(type); + if(has_type_fixed) break; + } + + if(has_type_fixed) { + fprintf(fd, "size_t align;\n"); + print_tabs(1, fd); + } + + fprintf(fd, "const void *real_from;\n"); + print_tabs(1, fd); + fprintf(fd, "const void **from = &real_from;\n"); + print_tabs(1, fd); + } + + /* Calculate event variable len + event data alignment offset. + * Assume that the padding for alignment starts at a void* + * address. + * This excludes the header size and alignment. */ + + print_tabs(1, fd); + fprintf(fd, "/* For each field, calculate the field size. */\n"); + print_tabs(1, fd); + fprintf(fd, "/* size = *to_base + *to + *len */\n"); + print_tabs(1, fd); + fprintf(fd, "/* Assume that the padding for alignment starts at a\n"); + print_tabs(1, fd); + fprintf(fd, " * sizeof(void *) address. */\n"); + fprintf(fd, "\n"); + + for(unsigned int i=0;ifields.position;i++){ + field_t *field = (field_t*)(event->fields.array[i]); + type_descriptor_t *type = field->type; + /* Set from */ + print_tabs(1, fd); + switch(type->type) { + case SEQUENCE: + case UNION: + case ARRAY: + case STRUCT: + case STRING: + fprintf(fd, "*from = lttng_param_%s;\n", field->name); + break; + default: + fprintf(fd, "*from = <tng_param_%s;\n", field->name); + break; + } + + if(print_type_write(type, + fd, 1, basename, field->name, "lttng_param_", 0)) return 1; + fprintf(fd, "\n"); + } + print_tabs(1, fd); + fprintf(fd, "reserve_size = *to_base + *to + *len;\n"); + + print_tabs(1, fd); + fprintf(fd, "{\n"); + print_tabs(2, fd); + fprintf(fd, "char stack_buffer[reserve_size];\n"); + print_tabs(2, fd); + fprintf(fd, "buffer = stack_buffer;\n"); + fprintf(fd, "\n"); + + + //print_tabs(2, fd); + // for DEBUG only + // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n"); + print_tabs(2, fd); + fprintf(fd, "*to_base = *to = *len = 0;\n"); + fprintf(fd, "\n"); + + /* write data. */ + + for(unsigned int i=0;ifields.position;i++){ + field_t *field = (field_t*)(event->fields.array[i]); + type_descriptor_t *type = field->type; + + /* Set from */ + print_tabs(2, fd); + switch(type->type) { + case SEQUENCE: + case UNION: + case ARRAY: + case STRUCT: + case STRING: + fprintf(fd, "*from = lttng_param_%s;\n", field->name); + break; + default: + fprintf(fd, "*from = <tng_param_%s;\n", field->name); + break; + } + + + if(print_type_write(type, + fd, 2, basename, field->name, "lttng_param_", 0)) return 1; + fprintf(fd, "\n"); + + /* Don't forget to flush pending memcpy */ + print_tabs(2, fd); + fprintf(fd, "/* Flush pending memcpy */\n"); + print_tabs(2, fd); + fprintf(fd, "if(*len != 0) {\n"); + print_tabs(3, fd); + fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n"); + print_tabs(3, fd); + fprintf(fd, "*to += *len;\n"); + //print_tabs(3, fd); + //fprintf(fd, "from += len;\n"); + print_tabs(3, fd); + fprintf(fd, "*len = 0;\n"); + print_tabs(2, fd); + fprintf(fd, "}\n"); + fprintf(fd, "\n"); + } + +do_syscall: + print_tabs(2, fd); + fprintf(fd, "ret = ltt_trace_generic(ltt_facility_%s_%X, event_%s_%s, buffer, reserve_size, LTT_BLOCKING);\n", fac->name, fac->checksum, fac->name, event->name); + + print_tabs(1, fd); + fprintf(fd, "}\n\n"); + + print_tabs(1, fd); + fprintf(fd, "return ret;\n\n"); + + fprintf(fd, "}\n"); + fprintf(fd, + "#endif //LTT_TRACE\n"); + fprintf(fd, "#endif //!LTT_TRACE_FAST\n\n"); + + return 0; +} + +/* print_event_logging_function_user_fast + * Print the logging function of an event for userspace tracing. This is the + * core of genevent */ +int print_event_logging_function_user_fast(char *basename, facility_t *fac, + event_t *event, FILE *fd) +{ + char *attrib; + + fprintf(fd, "#ifdef LTT_TRACE_FAST\n"); + + if(event->no_instrument_function) { + attrib = "__attribute__((no_instrument_function)) "; + } else { + attrib = ""; + } + fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename); + int has_argument = 0; int has_type_fixed = 0; @@ -1616,6 +1854,12 @@ int print_event_logging_function_user(char *basename, facility_t *fac, fprintf(fd, "{\n"); /* Print the function variables */ print_tabs(1, fd); + fprintf(fd, "unsigned int index;\n"); + print_tabs(1, fd); + fprintf(fd, "struct ltt_trace_info *trace = thread_trace_info;\n"); + print_tabs(1, fd); + fprintf(fd, "struct ltt_buf *ltt_buf;\n"); + print_tabs(1, fd); fprintf(fd, "void *buffer = NULL;\n"); print_tabs(1, fd); fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n"); @@ -1634,8 +1878,6 @@ int print_event_logging_function_user(char *basename, facility_t *fac, print_tabs(1, fd); fprintf(fd, "size_t slot_size;\n"); print_tabs(1, fd); - fprintf(fd, "int ret = 0;\n"); - print_tabs(1, fd); if(event->fields.position > 0) { for(unsigned int i=0;ifields.position;i++){ @@ -1657,6 +1899,20 @@ int print_event_logging_function_user(char *basename, facility_t *fac, fprintf(fd, "const void **from = &real_from;\n"); print_tabs(1, fd); } + fprintf(fd, "uint64_t tsc;\n"); + print_tabs(1, fd); + fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n"); + fprintf(fd, "\n"); + + print_tabs(1, fd); + fprintf(fd, "if(!trace) {\n"); + print_tabs(2, fd); + fprintf(fd, "ltt_thread_init();\n"); + print_tabs(2, fd); + fprintf(fd, "trace = thread_trace_info;\n"); + print_tabs(1, fd); + fprintf(fd, "}\n\n"); + fprintf(fd, "\n"); /* Calculate event variable len + event data alignment offset. * Assume that the padding for alignment starts at a void* @@ -1698,15 +1954,46 @@ int print_event_logging_function_user(char *basename, facility_t *fac, print_tabs(1, fd); fprintf(fd, "reserve_size = *to_base + *to + *len;\n"); + print_tabs(1, fd); + fprintf(fd, "trace->nesting++;\n"); + + /* Get facility index */ + + print_tabs(1, fd); + fprintf(fd, + "index = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\ + "\t\t\t\t\t\tevent_%s_%s);\n", + fac->name, fac->checksum, fac->name, event->name); + fprintf(fd,"\n"); + + print_tabs(1, fd); fprintf(fd, "{\n"); + + if(event->per_trace) { + print_tabs(2, fd); + fprintf(fd, "if(dest_trace != trace) continue;\n\n"); + } + print_tabs(2, fd); - fprintf(fd, "char stack_buffer[reserve_size];\n"); + fprintf(fd, "ltt_buf = ltt_get_channel_from_index(trace, index);\n"); print_tabs(2, fd); - fprintf(fd, "buffer = stack_buffer;\n"); - fprintf(fd, "\n"); + /* Relay reserve */ + /* If error, increment event lost counter (done by ltt_reserve_slot) and + * return */ + print_tabs(2, fd); + fprintf(fd, "slot_size = 0;\n"); + print_tabs(2, fd); + fprintf(fd, "buffer = ltt_reserve_slot(trace, ltt_buf,\n"); + print_tabs(3, fd); + fprintf(fd, "reserve_size, &slot_size, &tsc,\n"); + print_tabs(3, fd); + fprintf(fd, "&before_hdr_pad, &after_hdr_pad, &header_size);\n"); + /* If error, return */ + print_tabs(2, fd); + fprintf(fd, "if(!buffer) goto end; /* buffer full */\n\n"); //print_tabs(2, fd); // for DEBUG only // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n"); @@ -1714,6 +2001,18 @@ int print_event_logging_function_user(char *basename, facility_t *fac, fprintf(fd, "*to_base = *to = *len = 0;\n"); fprintf(fd, "\n"); + /* Write event header */ + print_tabs(2, fd); + fprintf(fd, "ltt_write_event_header(trace, ltt_buf, buffer,\n"); + print_tabs(3, fd); + fprintf(fd, "ltt_facility_%s_%X, event_%s_%s,\n", fac->name, fac->checksum, + fac->name, event->name); + print_tabs(3, fd); + fprintf(fd, "reserve_size, before_hdr_pad, tsc);\n"); + print_tabs(2, fd); + fprintf(fd, "*to_base += before_hdr_pad + after_hdr_pad + header_size;\n"); + fprintf(fd, "\n"); + /* write data. */ for(unsigned int i=0;ifields.position;i++){ @@ -1759,22 +2058,33 @@ int print_event_logging_function_user(char *basename, facility_t *fac, } + /* commit */ + // for DEBUG only. + //fprintf(fd, "commit:\n"); /* DEBUG! */ print_tabs(2, fd); - fprintf(fd, "ret = ltt_trace_generic(ltt_facility_%s_%X, event_%s_%s, stack_buffer, sizeof(stack_buffer));\n", fac->name, fac->checksum, fac->name, event->name); - - print_tabs(1, fd); - fprintf(fd, "}\n\n"); + fprintf(fd, "ltt_commit_slot(ltt_buf, buffer, slot_size);\n\n"); + fprintf(fd, "}\n\n"); + + fprintf(fd, "end:\n"); + /* Release locks */ print_tabs(1, fd); - fprintf(fd, "return ret;\n\n"); + fprintf(fd, "trace->nesting--;\n"); + fprintf(fd, "}\n"); fprintf(fd, "#endif //LTT_TRACE\n"); + fprintf(fd, "#endif //LTT_TRACE_FAST\n"); return 0; } + + + + + /* ltt-facility-name.h : main logging header. * log_header */ @@ -1807,7 +2117,7 @@ void print_log_header_head_user(facility_t *fac, FILE *fd) fprintf(fd, "#include \n", fac->name, fac->arch); - fprintf(fd, "#include \n"); + fprintf(fd, "#include \n"); fprintf(fd, "\n"); } @@ -1871,7 +2181,10 @@ int print_log_header_events(facility_t *fac, FILE *fd) if(!fac->user) { if(print_event_logging_function(basename, fac, event, fd)) return 1; } else { - if(print_event_logging_function_user(basename, fac, event, fd)) return 1; + if(print_event_logging_function_user_generic(basename, fac, event, fd)) + return 1; + if(print_event_logging_function_user_fast(basename, fac, event, fd)) + return 1; } fprintf(fd, "\n"); @@ -2025,7 +2338,7 @@ int print_id_header(facility_t *fac) fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname); fprintf(fd, "#ifdef LTT_TRACE\n"); - fprintf(fd,"#include \n\n"); + fprintf(fd,"#include \n\n"); fprintf(fd,"/**** facility handle ****/\n\n"); fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n", @@ -2162,7 +2475,7 @@ int print_loader_header_user(facility_t *fac) fprintf(fd, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n", fac->capname); fprintf(fd, "#define _LTT_FACILITY_LOADER_%s_H_\n\n", fac->capname); - fprintf(fd,"#include \n"); + fprintf(fd,"#include \n"); if(!fac->arch) fprintf(fd,"#include \n\n", fac->name); @@ -2355,7 +2668,7 @@ int print_loader_c_user(facility_t *fac) fprintf(fd, "#define LTT_TRACE\n"); fprintf(fd, "#include \n"); fprintf(fd, "#include \n"); - fprintf(fd, "#include \n"); + fprintf(fd, "#include \n"); if(!fac->arch) fprintf(fd, "#include \"ltt-facility-loader-%s.h\"\n", fac->name); else @@ -2380,13 +2693,17 @@ int print_loader_c_user(facility_t *fac) fprintf(fd, "static void __attribute__((constructor)) __ltt_user_init(void)\n"); fprintf(fd, "{\n"); fprintf(fd, "\tint err;\n"); + fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n"); fprintf(fd, "\tprintf(\"LTT : ltt-facility-%s init in userspace\\n\");\n", fac->name); + fprintf(fd, "#endif //LTT_SHOW_DEBUG\n"); fprintf(fd, "\n"); fprintf(fd, "\terr = ltt_register_generic(<T_FACILITY_SYMBOL, &facility);\n"); fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n"); fprintf(fd, "\t\n"); fprintf(fd, "\tif(err) {\n"); + fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n"); fprintf(fd, "\t\tperror(\"Error in ltt_register_generic\");\n"); + fprintf(fd, "#endif //LTT_SHOW_DEBUG\n"); fprintf(fd, "\t}\n"); fprintf(fd, "}\n"); fprintf(fd, "\n"); @@ -2443,7 +2760,23 @@ facility_t *ltt_facility_open(char * pathname) if(strcmp(token, "<")) in.error(&in,"not a facility file"); token = getName(&in); + if(strcmp(token, "?")) in.error(&in,"not a facility file"); + token = getName(&in); + if(strcmp(token, "xml")) in.error(&in,"not a facility file"); + token = getName(&in); + if(strcmp(token, "version")) in.error(&in,"not a facility file"); + token = getName(&in); + if(strcmp(token, "=")) in.error(&in,"not a facility file"); + token = getQuotedString(&in); + if(strcmp(token, "1.0")) in.error(&in,"not a facility file"); + token = getName(&in); + if(strcmp(token, "?")) in.error(&in,"not a facility file"); + token = getToken(&in); + if(strcmp(token, ">")) in.error(&in,"not a facility file"); + token = getName(&in); + if(strcmp(token, "<")) in.error(&in,"not a facility file"); + token = getName(&in); if(strcmp("facility",token) == 0) { fac = malloc(sizeof(facility_t)); fac->name = NULL;