From bc6668cd04209d34c04b84139fdfb353166e3335 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Thu, 31 Mar 2011 16:34:01 -0500 Subject: Initial code for trace api. --- src/usr/example/example.C | 6 ++++- src/usr/makefile | 2 +- src/usr/trace/TraceBuffer.C | 53 ++++++++++++++++++++++++++++++++++++++++++++ src/usr/trace/TraceBuffer.H | 51 ++++++++++++++++++++++++++++++++++++++++++ src/usr/trace/makefile | 6 +++++ src/usr/trace/trace.C | 54 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 src/usr/trace/TraceBuffer.C create mode 100644 src/usr/trace/TraceBuffer.H create mode 100644 src/usr/trace/makefile create mode 100644 src/usr/trace/trace.C (limited to 'src/usr') diff --git a/src/usr/example/example.C b/src/usr/example/example.C index 97c8d5cbb..6aa188f3c 100644 --- a/src/usr/example/example.C +++ b/src/usr/example/example.C @@ -4,11 +4,15 @@ #include #include -static mutex_t value = mutex_create(); +//static mutex_t value = mutex_create(); + +trace_desc_t g_exampleTrace; +TRAC_INIT(&g_exampleTrace, "EXAMPLE", 4096); extern "C" void _start(void*) { printk("Executing example module.\n"); + TRACFCOMP(g_exampleTrace, "Executing example module: %d", task_gettid()); task_end(); } diff --git a/src/usr/makefile b/src/usr/makefile index b734fab3b..321934359 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -1,6 +1,6 @@ ROOTPATH = ../.. OBJS = module_init.o -SUBDIRS = example.d +SUBDIRS = example.d trace.d include ${ROOTPATH}/config.mk diff --git a/src/usr/trace/TraceBuffer.C b/src/usr/trace/TraceBuffer.C new file mode 100644 index 000000000..c10afcfa3 --- /dev/null +++ b/src/usr/trace/TraceBuffer.C @@ -0,0 +1,53 @@ +#include +#include "TraceBuffer.H" + +TracePage* TracePage::setNext(TracePage* new_next) +{ + return __sync_val_compare_and_swap(&this->next, NULL, new_next); +} + +traceEntry* TracePage::claimEntry(size_t size) +{ + size_t position = __sync_fetch_and_add(&this->size, size); + if (position > (PAGE_SIZE - sizeof(TracePage))) + { + return NULL; + } + else + { + return (traceEntry*)&((uint8_t*)this)[sizeof(TracePage) + position]; + } +} + +traceEntry* TraceBuffer::claimEntry(size_t size) +{ + traceEntry* result = NULL; + TracePage* page = last; + + while (result == NULL) + { + result = page->claimEntry(size); + + if (NULL == result) + { + if (NULL != page->getNext()) + { + __sync_bool_compare_and_swap(&this->last, + page, page->getNext()); + page = page->getNext(); + } + else + { + TracePage* new_page = new (malloc(PAGE_SIZE)) TracePage(); + TracePage* prev = page; + + while(prev != NULL) + { + prev = prev->setNext(new_page); + } + } + } + } + + return result; +} diff --git a/src/usr/trace/TraceBuffer.H b/src/usr/trace/TraceBuffer.H new file mode 100644 index 000000000..4ac416eac --- /dev/null +++ b/src/usr/trace/TraceBuffer.H @@ -0,0 +1,51 @@ +#ifndef __TRACE_TRACEBUFFER_H +#define __TRACE_TRACEBUFFER_H + +#include +#include +#include +#include +#include + +struct traceEntry +{ + uint64_t component; + tid_t tid; + uint16_t length; + uint32_t hash; + uint64_t timestamp; + uint32_t line; + uint64_t values[0]; +}; + + +class TracePage +{ + public: + TracePage() : next(NULL), size(0) {}; + + TracePage* setNext(TracePage*); + TracePage* getNext() { return next; }; + traceEntry* claimEntry(size_t size); + + private: + TracePage* volatile next; + uint64_t size; +}; + +class TraceBuffer +{ + public: + TraceBuffer() + { + first = last = new (malloc(PAGE_SIZE)) TracePage(); + } + + traceEntry* claimEntry(size_t size); + + private: + TracePage* first; + TracePage* volatile last; +}; + +#endif diff --git a/src/usr/trace/makefile b/src/usr/trace/makefile new file mode 100644 index 000000000..a527fd792 --- /dev/null +++ b/src/usr/trace/makefile @@ -0,0 +1,6 @@ +ROOTPATH = ../../.. +MODULE = trace + +OBJS = trace.o TraceBuffer.o + +include ${ROOTPATH}/config.mk diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C new file mode 100644 index 000000000..aa0fa90c6 --- /dev/null +++ b/src/usr/trace/trace.C @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include "TraceBuffer.H" + +int32_t trace_adal_init_buffer(trace_desc_t * td, const char* comp, + const size_t size ) +{ + // For now, just store the component name. + td = (trace_desc_t*) comp; + return 0; +} + +int32_t trace_adal_write_all(const trace_desc_t td, + const enum trace_hash_val hash, + const char * fmt, + const uint32_t line, + const int32_t type, ...) +{ + // This code is incorrect for determining formatting but will work for now. + size_t size = 0; + const char* _fmt = fmt; + while ('\0' != *_fmt) + { + if ('%' == *_fmt) + size++; + _fmt++; + } + + traceEntry* entry = + Singleton::instance().claimEntry(sizeof(traceEntry) + + sizeof(uint64_t) * size); + + entry->component = (uint64_t) td; + entry->tid = task_gettid(); + entry->length = sizeof(uint64_t) * size; + entry->hash = hash; + entry->timestamp = getTB(); + entry->line = line; + + uint64_t* data = &entry->values[0]; + + va_list args; + va_start(args, type); + for (size_t i = 0; i < size; i++) + { + *data = va_arg(args, uint64_t); + data++; + } + va_end(args); + return 0; +} -- cgit v1.2.1