Commit 11d9a98c authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

GUI working with new tracing

Some optimizations and some bugfixes and less leaking
parent 142d7994
../../controller/controller/block_setpoint_generator.h
\ No newline at end of file
......@@ -11,7 +11,7 @@ libs: libtrace.la
libs_install: libtrace.la_install
bins: trace_dump trace_dumpdiff trace_fft trace_view trace_list
bins: trace_dump trace_dumpdiff trace_view trace_list
${CURDIR}/../lib:
@mkdir ${CURDIR}/../lib
......
......@@ -22,28 +22,34 @@
#include <trace/trace.h>
#include <trace_def.h>
#include <tcp_connect.h>
#include <log/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/ioctl.h>
static bool timespec_older(struct timespec *t1, struct timespec *t2)
{
if (t1->tv_sec > t2->tv_sec)
return true;
if (t1->tv_sec < t2->tv_sec)
return true;
if (t1->tv_sec > t2->tv_sec)
return false;
if (t1->tv_nsec > t2->tv_nsec)
if (t1->tv_nsec < t2->tv_nsec)
return true;
return false;
}
static void timespec_normalize(struct timespec *t)
{
t->tv_sec += t->tv_nsec / 1000000000;
t->tv_nsec ^= 1000000000;
long newsec = t->tv_nsec / 1000000000;
t->tv_sec += newsec;
t->tv_nsec -= newsec * 1000000000;
}
static void timespec_add(struct timespec *dst, struct timespec *add)
......@@ -61,48 +67,110 @@ void trace_initialize(struct trace *trace, size_t buffer)
trace->fd = -1;
}
void trace_packet_initialize(struct trace_pkt *pkt)
int trace_name_set(struct trace *trace, char *name)
{
memset(pkt, 0, sizeof(struct trace_pkt));
struct trace_pkt *pkt;
if (trace->name)
free(trace->name);
trace->name = strdup(name);
pkt = trace_packet_new();
trace_packet_name_set(pkt, name);
trace_packet_write(trace, pkt);
trace_packet_put(pkt);
return 0;
}
void trace_autorecover(struct trace *trace, bool value)
{
trace->recover = value;
}
void trace_packet_put(struct trace_pkt *pkt)
void trace_packet_initialize(struct trace_pkt *pkt)
{
free(pkt->data);
free(pkt);
memset(pkt, 0, sizeof(struct trace_pkt));
}
#define PACKET_BUFLEN 256
#define PACKET_POOL_CHUNK 16
static struct trace_pkt **packet_pool;
static int packet_pool_size = 0;
static int packet_pool_cur = 0;
struct trace_pkt *trace_packet_new(void)
{
struct trace_pkt *pkt;
if (packet_pool_cur) {
pkt = packet_pool[packet_pool_cur-1];
packet_pool_cur--;
return pkt;
}
pkt = calloc(1, sizeof(struct trace_pkt));
pkt->data = malloc(PACKET_BUFLEN);
pkt->buflen = PACKET_BUFLEN;
return pkt;
}
int trace_packet_resize(struct trace_pkt *pkt, size_t len)
{
if (len <= pkt->buflen)
return 0;
pkt->data = realloc(pkt->data, len);
pkt->buflen = len;
return 0;
}
void trace_packet_put(struct trace_pkt *pkt)
{
if (pkt->buflen > PACKET_BUFLEN) {
free(pkt->data);
free(pkt);
return;
}
if (packet_pool_cur >= packet_pool_size) {
packet_pool_size += PACKET_POOL_CHUNK;
packet_pool = realloc(packet_pool,
sizeof(struct trace_pkt *) * packet_pool_size);
}
packet_pool[packet_pool_cur] = pkt;
pkt->len = 0;
packet_pool_cur++;
}
int trace_packet_list_add(struct trace_pkt *pkt,
char *name, enum trace_value_type type, char *unit)
{
size_t entry_size = strlen(name)+1 + 1 + strlen(unit)+1;
char *entry;
unsigned char *entry;
if (!pkt->len) {
trace_packet_resize(pkt, 1);
pkt->len = 1;
pkt->data = realloc(pkt->data, 1);
pkt->data[0] = TRACE_PTYPE_LIST;
}
pkt->data = realloc(pkt->data, pkt->len + entry_size);
trace_packet_resize(pkt, pkt->len + entry_size);
entry = pkt->data + pkt->len;
strcpy(entry, name);
strcpy((char *)entry, name);
entry += strlen(name) + 1;
*entry = type;
entry++;
strcpy(entry, unit);
strcpy((char *)entry, unit);
pkt->len += entry_size;
......@@ -112,7 +180,13 @@ int trace_packet_list_add(struct trace_pkt *pkt,
int trace_packet_value_add(struct trace_pkt *pkt, struct trace_value *value, enum trace_value_type type)
{
size_t entry_size;
char *entry;
struct {
uint16_t u16;
} __packed *entry16;
struct {
uint32_t u32;
} __packed *entry32;
unsigned char *entry;
switch (type) {
case TRACE_VALUE_TYPE_BOOL:
......@@ -133,12 +207,12 @@ int trace_packet_value_add(struct trace_pkt *pkt, struct trace_value *value, enu
}
if (!pkt->len) {
trace_packet_resize(pkt, 1);
pkt->len = 1;
pkt->data = realloc(pkt->data, 1);
pkt->data[0] = TRACE_PTYPE_DATA;
}
pkt->data = realloc(pkt->data, pkt->len + entry_size);
trace_packet_resize(pkt, pkt->len + entry_size);
entry = pkt->data + pkt->len;
switch (type) {
......@@ -149,9 +223,9 @@ int trace_packet_value_add(struct trace_pkt *pkt, struct trace_value *value, enu
break;
case TRACE_VALUE_TYPE_SINT16:
case TRACE_VALUE_TYPE_UINT16: {
uint16_t *entry16 = (void *)entry;
entry16 = (void *)entry;
*entry16 = htobe16(value->value.u16);
entry16->u16 = htobe16(value->value.u16);
break;
}
......@@ -159,9 +233,9 @@ int trace_packet_value_add(struct trace_pkt *pkt, struct trace_value *value, enu
case TRACE_VALUE_TYPE_SINT32:
case TRACE_VALUE_TYPE_FLOAT:
default: {
uint32_t *entry32 = (void *)entry;
entry32 = (void *)entry;
*entry32 = htobe32(value->value.u32);
entry32->u32 = htobe32(value->value.u32);
break;
}
......@@ -180,7 +254,7 @@ int trace_packet_interval_set(struct trace_pkt *pkt,
if (pkt->len < sizeof(struct trace_ptype_interval) + sizeof(struct trace_header)) {
pkt->len = sizeof(struct trace_ptype_interval) + sizeof(struct trace_header);
pkt->data = realloc(pkt->data, pkt->len);
trace_packet_resize(pkt, pkt->len);
pkt->data[0] = TRACE_PTYPE_INTERVAL;
}
pinterval = (struct trace_ptype_interval *)&pkt->data[1];
......@@ -199,7 +273,7 @@ int trace_packet_timestamp_set(struct trace_pkt *pkt,
if (pkt->len < sizeof(struct trace_ptype_timestamp) + sizeof(struct trace_header)) {
pkt->len = sizeof(struct trace_ptype_timestamp) + sizeof(struct trace_header);
pkt->data = realloc(pkt->data, pkt->len);
trace_packet_resize(pkt, pkt->len);
pkt->data[0] = TRACE_PTYPE_TIMESTAMP;
}
ptimestamp = (struct trace_ptype_timestamp *)&pkt->data[1];
......@@ -214,10 +288,10 @@ int trace_packet_name_set(struct trace_pkt *pkt, char *name)
{
if (pkt->len < sizeof(struct trace_header) + strlen(name) + 1) {
pkt->len = strlen(name) + 1 + sizeof(struct trace_header);
pkt->data = realloc(pkt->data, pkt->len);
trace_packet_resize(pkt, pkt->len);
pkt->data[0] = TRACE_PTYPE_NAME;
}
strcpy(pkt->data + 1, name);
strcpy((char *)pkt->data + 1, name);
return 0;
}
......@@ -228,7 +302,7 @@ int trace_packet_type_set(struct trace_pkt *pkt, enum trace_value_type type)
if (pkt->len < sizeof(struct trace_header) + sizeof(struct trace_ptype_value_type)) {
pkt->len = sizeof(struct trace_header) + sizeof(struct trace_ptype_value_type);
pkt->data = realloc(pkt->data, pkt->len);
trace_packet_resize(pkt, pkt->len);
pkt->data[0] = TRACE_PTYPE_VALUE_TYPE;
}
vt = (void *)pkt->data + sizeof(struct trace_header);
......@@ -240,6 +314,34 @@ int trace_packet_type_set(struct trace_pkt *pkt, enum trace_value_type type)
void trace_fd_set(struct trace *trace, fd_set *set, int *high)
{
if (trace->fd < 0) {
if (!trace->recover)
return;
if (trace->recovertime >= time(NULL))
return;
trace->recovertime = time(NULL);
log_send(LOG_T_DEBUG, "Attempt to recover trace");
trace->fd = tcp_connect(trace->host, trace->port);
if (trace->fd >= 0) {
struct trace_pkt *pkt;
ioctl(trace->fd, FIONBIO, &(int){1});
if (trace->name) {
pkt = trace_packet_new();
trace_packet_name_set(pkt, trace->name);
trace_packet_write(trace, pkt);
trace_packet_put(pkt);
}
}
if (trace->fd < 0) {
log_send(LOG_T_DEBUG, "Failed to recover");
return;
}
}
FD_SET(trace->fd, set);
if (trace->fd > *high)
......@@ -253,6 +355,8 @@ int trace_handle(struct trace *trace, fd_set *set)
struct trace_pkt *pkt;
pkt = trace_packet_get(trace);
if (!pkt)
break;
switch (pkt->data[0]) {
case TRACE_PTYPE_INTERVAL: {
struct trace_ptype_interval *pinterval;
......@@ -271,7 +375,7 @@ int trace_handle(struct trace *trace, fd_set *set)
}
case TRACE_PTYPE_TIMESTAMP: {
struct trace_ptype_timestamp *ptimestamp;
ptimestamp = (void*)pkt->data + 1;
trace->timestamp.tv_sec = be64toh(ptimestamp->sec);
......@@ -283,7 +387,7 @@ int trace_handle(struct trace *trace, fd_set *set)
break;
}
case TRACE_PTYPE_LIST: {
char *listentry;
unsigned char *listentry;
size_t pos = 1;
while (pos < pkt->len) {
......@@ -293,9 +397,9 @@ int trace_handle(struct trace *trace, fd_set *set)
listentry = pkt->data + pos;
name = listentry;
name = (char *)listentry;
type = listentry[strlen(name) + 1];
unit = listentry+strlen(name) + 2;
unit = (char *)listentry+strlen(name) + 2;
if (trace->handler_list_entry) {
trace->handler_list_entry(trace,
......@@ -314,6 +418,7 @@ int trace_handle(struct trace *trace, fd_set *set)
type = vt->type;
trace->type = type;
trace->type_set = type;
if (trace->handler_type) {
trace->handler_type(trace, type);
}
......@@ -325,6 +430,7 @@ int trace_handle(struct trace *trace, fd_set *set)
name = (void*)pkt->data + 1;
trace->name_set = true;
trace->name = strdup(name);
if (trace->handler_name) {
trace->handler_name(trace, name);
......@@ -341,21 +447,22 @@ int trace_handle(struct trace *trace, fd_set *set)
case TRACE_VALUE_TYPE_FLOAT:
case TRACE_VALUE_TYPE_UINT32:
case TRACE_VALUE_TYPE_SINT32:
trace->value.value.u32 = be32toh(v->u32);
trace->value.value.u32 = be32toh(v->u.u32);
pos+=4;
break;
case TRACE_VALUE_TYPE_UINT16:
case TRACE_VALUE_TYPE_SINT16:
trace->value.value.u16 = be32toh(v->u16);
trace->value.value.u16 = be32toh(v->u.u16);
pos+=2;
break;
case TRACE_VALUE_TYPE_BOOL:
case TRACE_VALUE_TYPE_UINT8:
case TRACE_VALUE_TYPE_SINT8:
trace->value.value.u8 = v->u8;
trace->value.value.u8 = v->u.u8;
pos++;
break;
}
if (timespec_older(&trace->value.t, &trace->timestamp)) {
trace->value.t = trace->timestamp;
} else {
......@@ -370,9 +477,10 @@ int trace_handle(struct trace *trace, fd_set *set)
}
trace_packet_put(pkt);
}
return 0;
}
return 0;
return 1;
}
enum trace_state trace_state_get(struct trace *trace)
......@@ -383,8 +491,6 @@ enum trace_state trace_state_get(struct trace *trace)
if (trace->list_received)
return TRACE_STATE_READY;
printf("connected\n");
return TRACE_STATE_CONNECTED;
}
......
......@@ -96,8 +96,13 @@ struct trace {
struct timespec timestamp;
struct timespec interval;
char *name;
bool name_set;
bool list_received;
bool recover;
bool type_set;
time_t recovertime;
struct trace_value value;
......@@ -119,14 +124,18 @@ struct trace {
struct trace_pkt {
enum trace_ptype type;
char *data;
unsigned char *data;
size_t len;
size_t buflen;
};
struct trace *trace_alloc(void);
struct trace *trace_open(char *host, int port);
void trace_initialize(struct trace *trace, size_t buffer);
void trace_initialize_fd(struct trace *trace, int fd);
int trace_name_set(struct trace *trace, char *name);
void trace_autorecover(struct trace *trace, bool value);
void trace_close(struct trace *trace);
void trace_free(struct trace *trace);
int trace_fd_get(struct trace *trace);
......@@ -140,6 +149,7 @@ void trace_packet_initialize(struct trace_pkt *pkt);
int trace_packet_write(struct trace *trace, struct trace_pkt *pkt);
struct trace_pkt *trace_packet_new(void);
int trace_packet_resize(struct trace_pkt *pkt, size_t len);
int trace_packet_list_add(struct trace_pkt *list_pkt,
char *name, enum trace_value_type type, char *unit);
......
......@@ -35,11 +35,22 @@ static void handler_interval(struct trace *trace,
struct timespec *interval, enum trace_interval_type type)
{
memcpy(&t_int, interval, sizeof(struct timespec));
printf("interval: %ld.%09ld\n", interval->tv_sec, interval->tv_nsec);
}
int cnt =0;
static void handler_timestamp(struct trace *trace,
struct timespec *t)
{
printf("timestamp: %ld.%09ld, cnt=%d\n", t->tv_sec, t->tv_nsec, cnt);
cnt = 0;
}
static void handler_value(struct trace *trace,
struct trace_value *value)
{
cnt++;
switch (trace->type) {
case TRACE_VALUE_TYPE_FLOAT:
printf("%ld.%09ld %e\n",
......@@ -82,21 +93,23 @@ int main(int argc, char **argv)
struct trace_pkt *pkt;
int interval = 1;
if (argc < 2) {
if (argc < 4) {
printf("Usage:\n\n");
printf("%s [trace] <interval>\n", argv[0]);
printf("%s [host] [port] [trace] <interval>\n", argv[0]);
return 0;
}
tracename = argv[1];
tracename = argv[3];
trace = trace_open("localhost", 20000);
trace = trace_open(argv[1], atoi(argv[2]));
if (argc >= 3) {
interval = atoi(argv[2]);
if (argc >= 5) {
interval = atoi(argv[4]);
}
trace->handler_interval = handler_interval;
trace->handler_value = handler_value;
trace->handler_timestamp = handler_timestamp;
while (trace_state_get(trace) == TRACE_STATE_CONNECTED) {
fd_set fdrx;
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007, 2008, 2011
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007, 2008, 2011, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2007, 2008, 2011
This program is free software: you can redistribute it and/or modify
......@@ -26,48 +26,141 @@
#include <string.h>
#include <math.h>
#include "trace.h"
#include <trace/trace.h>
struct timespec t_int;
char *tracename;
void handle_val(struct traceval *trc)
static void handler_interval(struct trace *trace,
struct timespec *interval, enum trace_interval_type type)
{
float val = trace_val(trc);
static float lastval = -1337.0;
if (lastval == val)
return;
printf("%f %e\n",
(double)trace_seconds(trc) +
(double)trace_sample(trc) * trace_period(trc),
val);
lastval = val;
memcpy(&t_int, interval, sizeof(struct timespec));
printf("interval: %ld.%09ld\n", interval->tv_sec, interval->tv_nsec);
}
int cnt =0;
int main(int argc, char **argv)
static void handler_value(struct trace *trace,
struct trace_value *value)
{
struct traceval *trc;
static struct trace_value prev;
trc = trace_create();
if (!trc)
return 1;
trace_handler_add(trc, handle_val);
if (cnt || memcmp(&prev.value, &value->value, sizeof(prev.value))) {
return;
}
prev.value = value->value;
cnt = 1;
if (argc < 2) {
switch (trace->type) {
case TRACE_VALUE_TYPE_FLOAT:
printf("%ld.%09ld %e\n",
value->t.tv_sec, value->t.tv_nsec, value->value.f);
break;
case TRACE_VALUE_TYPE_BOOL:
printf("%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.b);
break;
case TRACE_VALUE_TYPE_UINT8:
printf("%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u8);
break;
case TRACE_VALUE_TYPE_UINT16:
printf("%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u16);
break;
case TRACE_VALUE_TYPE_UINT32:
printf("%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u32);
break;
case TRACE_VALUE_TYPE_SINT8:
printf("%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s8);
break;
case TRACE_VALUE_TYPE_SINT16:
printf("%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s16);
break;
case TRACE_VALUE_TYPE_SINT32:
printf("%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s32);
break;
}
}
int main(int argc, char **argv)
{
struct trace *trace;
struct trace_pkt *pkt;
int interval = 1;
if (argc < 4) {
printf("Usage:\n\n");
printf("%s [trace]\n", argv[0]);
printf("%s [host] [port] [trace] <interval>\n", argv[0]);
return 0;
}
tracename = argv[3];
trace = trace_open(argv[1], atoi(argv[2]));
if (argc >= 5) {
interval = atoi(argv[4]);
}
trace->handler_interval = handler_interval;
trace->handler_value = handler_value;
if (trace_init("localhost", 10000, argv[1], trc)) {
return 1;
while (trace_state_get(trace) == TRACE_STATE_CONNECTED) {
fd_set fdrx;
int high = 0;
FD_ZERO(&fdrx);
trace_fd_set(trace, &fdrx, &high);
select(high + 1, &fdrx, NULL, NULL, NULL);