put code in the right place for integration into openair

This commit is contained in:
Cedric Roux
2016-04-11 10:20:23 +02:00
parent 9b0f4913e2
commit d37484b5aa
14 changed files with 0 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
CC=gcc
CFLAGS=-Wall -g -pthread -DT_TRACER
#comment those two lines to NOT use shared memory
CFLAGS += -DT_USE_SHARED_MEMORY
LIBS += -lrt
PROG=t
OBJS=main.o T.o
GENIDS=genids
GENIDS_OBJS=genids.o
ALL=$(PROG) $(GENIDS)
all : $(ALL)
$(GENIDS): $(GENIDS_OBJS)
$(CC) $(CFLAGS) -o $(GENIDS) $(GENIDS_OBJS)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt T_IDs.h
main.o: T.h T_IDs.h T_defs.h
clean:
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h
+147
View File
@@ -0,0 +1,147 @@
#include "T.h"
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
int *T_active = T_IDs;
static int T_socket;
/* T_cache
* - the T macro picks up the head of freelist and marks it busy
* - the T sender thread periodically wakes up and sends what's to be sent
*/
volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
int T_busylist_head;
T_cache_t _T_cache[T_CACHE_SIZE];
T_cache_t *T_cache = _T_cache;
static void get_message(int s)
{
char t;
int l;
int id;
if (read(s, &t, 1) != 1) abort();
printf("got mess %d\n", t);
switch (t) {
case 0:
/* toggle all those IDs */
/* optimze? (too much syscalls) */
if (read(s, &l, sizeof(int)) != sizeof(int)) abort();
while (l) {
if (read(s, &id, sizeof(int)) != sizeof(int)) abort();
T_IDs[id] = 1 - T_IDs[id];
l--;
}
break;
}
}
#ifndef T_USE_SHARED_MEMORY
static void *T_send_thread(void *_)
{
while (1) {
usleep(5000);
__sync_synchronize();
while (T_cache[T_busylist_head].busy) {
char *b;
int l;
/* TODO: be sure about those memory barriers - in doubt one is
* put here too
*/
__sync_synchronize();
b = T_cache[T_busylist_head].buffer;
l = T_cache[T_busylist_head].length;
while (l) {
int done = write(T_socket, b, l);
if (done <= 0) {
printf("%s:%d:%s: error sending to socket\n",
__FILE__, __LINE__, __FUNCTION__);
abort();
}
b += done;
l -= done;
}
T_cache[T_busylist_head].busy = 0;
T_busylist_head++;
T_busylist_head &= T_CACHE_SIZE - 1;
}
}
return NULL;
}
#endif /* T_USE_SHARED_MEMORY */
static void *T_receive_thread(void *_)
{
while (1) get_message(T_socket);
return NULL;
}
static void new_thread(void *(*f)(void *), void *data)
{
pthread_t t;
pthread_attr_t att;
if (pthread_attr_init(&att))
{ fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
{ fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
if (pthread_create(&t, &att, f, data))
{ fprintf(stderr, "pthread_create err\n"); exit(1); }
if (pthread_attr_destroy(&att))
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}
void T_connect_to_tracer(char *addr, int port)
{
struct sockaddr_in a;
int s;
#ifdef T_USE_SHARED_MEMORY
int T_shm_fd;
#endif
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr(addr);
if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1)
{ perror("connect"); exit(1); }
/* wait for first message - initial list of active T events */
get_message(s);
T_socket = s;
#ifdef T_USE_SHARED_MEMORY
/* setup shared memory */
T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666);
shm_unlink(T_SHM_FILENAME);
if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); }
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0);
if (T_cache == NULL)
{ perror(T_SHM_FILENAME); abort(); }
close(T_shm_fd);
#endif
#ifndef T_USE_SHARED_MEMORY
new_thread(T_send_thread, NULL);
#endif
new_thread(T_receive_thread, NULL);
}
+544
View File
@@ -0,0 +1,544 @@
#ifndef _T_T_T_
#define _T_T_T_
#if T_TRACER
#include <stdint.h>
#include "T_defs.h"
/* T message IDs */
#include "T_IDs.h"
/* known type - this is where you add new types */
#define T_INT(x) int, (x)
#define T_FLOAT(x) float, (x)
#define T_BUFFER(x, len) buffer, ((T_buffer){addr:(x), length:(len)})
#define T_STRING(x) string, (x)
#define T_PRINTF(...) printf, (__VA_ARGS__)
/* for each known type a T_PUT_XX macro is defined */
#define T_PUT_int(argnum, val) \
do { \
int T_PUT_var = (val); \
T_CHECK_SIZE(sizeof(int), argnum); \
memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(int)); \
T_LOCAL_size += sizeof(int); \
} while (0)
#define T_PUT_float(argnum, val) \
do { \
float T_PUT_var = (val); \
T_CHECK_SIZE(sizeof(float), argnum); \
memcpy(T_LOCAL_buf + T_LOCAL_size, &T_PUT_var, sizeof(float)); \
T_LOCAL_size += sizeof(float); \
} while (0)
#define T_PUT_buffer(argnum, val) \
do { \
T_buffer T_PUT_buffer_var = (val); \
T_PUT_int(argnum, T_PUT_buffer_var.length); \
T_CHECK_SIZE(T_PUT_buffer_var.length, argnum); \
memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_buffer_var.addr, \
T_PUT_buffer_var.length); \
T_LOCAL_size += T_PUT_buffer_var.length; \
} while (0)
#define T_PUT_string(argnum, val) \
do { \
char *T_PUT_var = (val); \
int T_PUT_len = strlen(T_PUT_var) + 1; \
T_CHECK_SIZE(T_PUT_len, argnum); \
memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var, T_PUT_len); \
T_LOCAL_size += T_PUT_len; \
} while (0)
#define T_PUT_printf_deref(...) __VA_ARGS__
#define T_PUT_printf(argnum, x) \
do { \
int T_PUT_len = snprintf(T_LOCAL_buf + T_LOCAL_size, \
T_BUFFER_MAX - T_LOCAL_size, T_PUT_printf_deref x); \
if (T_PUT_len < 0) { \
printf("%s:%d:%s: you can't read this, or can you?", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
if (T_PUT_len >= T_BUFFER_MAX - T_LOCAL_size) { \
printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
abort(); \
} \
T_LOCAL_size += T_PUT_len + 1; \
} while (0)
/* structure type to detect that you pass a known type as first arg of T */
struct T_header;
/* to define message ID */
#define T_ID(x) ((struct T_header *)(uintptr_t)(x))
/* T macro tricks */
#define TN(...) TN_N(__VA_ARGS__,33,32,31,30,29,28,27,26,25,24,23,22,21,\
20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)(__VA_ARGS__)
#define TN_N(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,\
n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n
#define T(...) TN(__VA_ARGS__)
/* type used to send arbitrary buffer data */
typedef struct {
void *addr;
int length;
} T_buffer;
extern volatile int *T_freelist_head;
extern T_cache_t *T_cache;
/* used at header of Tn, allocates buffer */
#define T_LOCAL_DATA \
char *T_LOCAL_buf; \
int T_LOCAL_size = 0; \
int T_LOCAL_slot; \
T_LOCAL_slot = __sync_fetch_and_add(T_freelist_head, 1) \
& (T_CACHE_SIZE - 1); \
(void)__sync_fetch_and_and(T_freelist_head, T_CACHE_SIZE - 1); \
if (T_cache[T_LOCAL_slot].busy) { \
printf("%s:%d:%s: T cache is full - consider increasing its size\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
T_LOCAL_buf = T_cache[T_LOCAL_slot].buffer;
#define T_ACTIVE(x) T_active[(intptr_t)x]
#ifdef T_USE_SHARED_MEMORY
#define T_SEND() \
T_cache[T_LOCAL_slot].length = T_LOCAL_size; \
__sync_synchronize(); \
T_cache[T_LOCAL_slot].busy = 1; \
T_send(T_LOCAL_buf, T_LOCAL_size)
#else /* T_USE_SHARED_MEMORY */
/* when not using shared memory, wait for send to finish */
#define T_SEND() \
T_cache[T_LOCAL_slot].length = T_LOCAL_size; \
__sync_synchronize(); \
T_cache[T_LOCAL_slot].busy = 1; \
T_send(T_LOCAL_buf, T_LOCAL_size); \
while (T_cache[T_LOCAL_slot].busy) usleep(1*1000)
#endif /* T_USE_SHARED_MEMORY */
#define T_CHECK_SIZE(len, argnum) \
if (T_LOCAL_size + (len) > T_BUFFER_MAX) { \
printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
abort(); \
}
#if 0
#define T_PUT(type, var, argnum) \
do { \
if (T_LOCAL_size + sizeof(var) > T_BUFFER_MAX) { \
printf("%s:%d:%s: cannot put argument %d in T macro, not enough space" \
", consider increasing T_BUFFER_MAX (%d)\n", \
__FILE__, __LINE__, __FUNCTION__, argnum, T_BUFFER_MAX); \
abort(); \
} \
memcpy(T_LOCAL_buf + T_LOCAL_size, &var, sizeof(var)); \
T_LOCAL_size += sizeof(var); \
} while (0)
#endif
#if 0
#define T_PROCESS(x, argnum) \
do { \
T_PUT(typeof(x), x, argnum); \
} while (0)
#endif
#if 0
#define T_PROCESS(x, argnum) \
do { \
if (__builtin_types_compatible_p(typeof(x), int)) \
{ T_PUT(int, (intptr_t)(x), argnum); printf("int\n"); } \
else if (__builtin_types_compatible_p(typeof(x), short)) \
{ T_PUT(short, (intptr_t)(x), argnum); printf("short\n"); } \
else if (__builtin_types_compatible_p(typeof(x), float)) \
{ T_PUT(float, (x), argnum); printf("float\n"); } \
else if (__builtin_types_compatible_p(typeof(x), char *)) \
{ T_PUT(char *, (char *)(intptr_t)(x), argnum); printf("char *\n"); } \
else if (__builtin_types_compatible_p(typeof(x), float *)) \
{ T_PUT(float *, (float *)(intptr_t)(x), argnum); printf("float *\n"); } \
else if (__builtin_types_compatible_p(typeof(x), void *)) \
{ T_PUT(void *, (void *)(intptr_t)(x), argnum); printf("void *\n"); } \
else { \
printf("%s:%d:%s: unsupported type for argument %d in T macro\n", \
__FILE__, __LINE__, __FUNCTION__, argnum); \
abort(); \
} \
} while (0)
#endif
#define T_HEADER(x) \
do { \
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
printf("%s:%d:%s: " \
"bad use of T, pass a message ID as first parameter\n", \
__FILE__, __LINE__, __FUNCTION__); \
abort(); \
} \
T_PUT_int(1, (int)(uintptr_t)(x)); \
} while (0)
#define T1(t) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_SEND(); \
} \
} while (0)
#define T3(t,t0,x0) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_SEND(); \
} \
} while (0)
#define T5(t,t0,x0,t1,x1) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_SEND(); \
} \
} while (0)
#define T7(t,t0,x0,t1,x1,t2,x2) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_SEND(); \
} \
} while (0)
#define T9(t,t0,x0,t1,x1,t2,x2,t3,x3) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_SEND(); \
} \
} while (0)
#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_SEND(); \
} \
} while (0)
#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_SEND(); \
} \
} while (0)
#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_SEND(); \
} \
} while (0)
#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_SEND(); \
} \
} while (0)
#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_SEND(); \
} \
} while (0)
#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_SEND(); \
} \
} while (0)
#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_SEND(); \
} \
} while (0)
#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_SEND(); \
} \
} while (0)
#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_SEND(); \
} \
} while (0)
#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_SEND(); \
} \
} while (0)
#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_SEND(); \
} \
} while (0)
#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15) \
do { \
if (T_ACTIVE(t)) { \
T_LOCAL_DATA \
T_HEADER(t); \
T_PUT_##t0(2, x0); \
T_PUT_##t1(3, x1); \
T_PUT_##t2(4, x2); \
T_PUT_##t3(5, x3); \
T_PUT_##t4(6, x4); \
T_PUT_##t5(7, x5); \
T_PUT_##t6(8, x6); \
T_PUT_##t7(9, x7); \
T_PUT_##t8(10, x8); \
T_PUT_##t9(11, x9); \
T_PUT_##t10(12, x10); \
T_PUT_##t11(13, x11); \
T_PUT_##t12(14, x12); \
T_PUT_##t13(15, x13); \
T_PUT_##t14(16, x14); \
T_PUT_##t15(17, x15); \
T_SEND(); \
} \
} while (0)
#define T_CALL_ERROR \
do { \
printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \
__FILE__, __LINE__, __FUNCTION__); \
} while (0)
#define T2(...) T_CALL_ERROR
#define T4(...) T_CALL_ERROR
#define T6(...) T_CALL_ERROR
#define T8(...) T_CALL_ERROR
#define T10(...) T_CALL_ERROR
#define T12(...) T_CALL_ERROR
#define T14(...) T_CALL_ERROR
#define T16(...) T_CALL_ERROR
#define T18(...) T_CALL_ERROR
#define T20(...) T_CALL_ERROR
#define T22(...) T_CALL_ERROR
#define T24(...) T_CALL_ERROR
#define T26(...) T_CALL_ERROR
#define T28(...) T_CALL_ERROR
#define T30(...) T_CALL_ERROR
#define T32(...) T_CALL_ERROR
#ifndef T_USE_SHARED_MEMORY
#include <stdio.h>
static inline void T_send(char *buf, int size)
{
int i;
return;
printf("sending %d bytes", size);
for (i = 0; i < size; i++)
printf("%s%2.2x", i?" ":"\n", (unsigned char)buf[i]);
printf("\n");
}
#else /* T_USE_SHARED_MEMORY */
#define T_send(...) /**/
#endif /* T_USE_SHARED_MEMORY */
extern int *T_active;
void T_connect_to_tracer(char *addr, int port);
#else /* T_TRACER */
/* if T_TRACER is not defined or is 0, the T is deactivated */
#define T(...) /**/
#endif /* T_TRACER */
#endif /* _T_T_T_ */
+18
View File
@@ -0,0 +1,18 @@
#ifndef _T_defs_H_
#define _T_defs_H_
/* maximum size of a message - increase if needed */
#define T_BUFFER_MAX (1024*64)
/* size of the local cache for messages (must be pow(2,something)) */
#define T_CACHE_SIZE (8192 * 2)
typedef struct {
volatile int busy;
char buffer[T_BUFFER_MAX];
int length;
} T_cache_t;
#define T_SHM_FILENAME "/T_shm_segment"
#endif /* _T_defs_H_ */
+430
View File
@@ -0,0 +1,430 @@
#PHY logs
ID = ENB_INPUT_SIGNAL
DESC = eNodeB received signal in the time domain for a duration of 1ms
GROUP = PHY:GRAPHIC:HEAVY
FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata
ID = ENB_UL_CHANNEL_ESTIMATE
DESC = eNodeB channel estimation in the time domain
GROUP = PHY:GRAPHIC:HEAVY
FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t
ID = PUSCH_IQ
DESC = eNodeB PUSCH received IQ data
GROUP = PHY:GRAPHIC:HEAVY
FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : buffer,pusch_comp
ID = PUCCH_1AB_IQ
DESC = eNodeB PUCCH received IQ data
GROUP = PHY:GRAPHIC:HEAVY
FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q
ID = PUCCH_1_ENERGY
DESC = eNodeB PUCCH 1 energy and threshold
GROUP = PHY:GRAPHIC:HEAVY
FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold
#legacy logs
ID = LEGACY_MAC_INFO
DESC = MAC legacy logs - info level
GROUP = MAC:INFO:LEGACY
ID = LEGACY_MAC_ERROR
DESC = MAC legacy logs - error level
GROUP = MAC:ERROR:LEGACY
ID = LEGACY_MAC_WARNING
DESC = MAC legacy logs - warning level
GROUP = MAC:WARNING:LEGACY
ID = LEGACY_MAC_DEBUG
DESC = MAC legacy logs - debug level
GROUP = MAC:DEBUG:LEGACY
ID = LEGACY_MAC_TRACE
DESC = MAC legacy logs - trace level
GROUP = MAC:TRACE:LEGACY
ID = LEGACY_PHY_INFO
DESC = PHY legacy logs - info level
GROUP = PHY:INFO:LEGACY
ID = LEGACY_PHY_ERROR
DESC = PHY legacy logs - error level
GROUP = PHY:ERROR:LEGACY
ID = LEGACY_PHY_WARNING
DESC = PHY legacy logs - warning level
GROUP = PHY:WARNING:LEGACY
ID = LEGACY_PHY_DEBUG
DESC = PHY legacy logs - debug level
GROUP = PHY:DEBUG:LEGACY
ID = LEGACY_PHY_TRACE
DESC = PHY legacy logs - trace level
GROUP = PHY:TRACE:LEGACY
ID = LEGACY_S1AP_INFO
DESC = S1AP legacy logs - info level
GROUP = S1AP:INFO:LEGACY
ID = LEGACY_S1AP_ERROR
DESC = S1AP legacy logs - error level
GROUP = S1AP:ERROR:LEGACY
ID = LEGACY_S1AP_WARNING
DESC = S1AP legacy logs - warning level
GROUP = S1AP:WARNING:LEGACY
ID = LEGACY_S1AP_DEBUG
DESC = S1AP legacy logs - debug level
GROUP = S1AP:DEBUG:LEGACY
ID = LEGACY_S1AP_TRACE
DESC = S1AP legacy logs - trace level
GROUP = S1AP:TRACE:LEGACY
ID = LEGACY_X2AP_INFO
DESC = X2AP legacy logs - info level
GROUP = X2AP:INFO:LEGACY
ID = LEGACY_X2AP_ERROR
DESC = X2AP legacy logs - error level
GROUP = X2AP:ERROR:LEGACY
ID = LEGACY_X2AP_WARNING
DESC = X2AP legacy logs - warning level
GROUP = X2AP:WARNING:LEGACY
ID = LEGACY_X2AP_DEBUG
DESC = X2AP legacy logs - debug level
GROUP = X2AP:DEBUG:LEGACY
ID = LEGACY_X2AP_TRACE
DESC = X2AP legacy logs - trace level
GROUP = X2AP:TRACE:LEGACY
ID = LEGACY_RRC_INFO
DESC = RRC legacy logs - info level
GROUP = RRC:INFO:LEGACY
ID = LEGACY_RRC_ERROR
DESC = RRC legacy logs - error level
GROUP = RRC:ERROR:LEGACY
ID = LEGACY_RRC_WARNING
DESC = RRC legacy logs - warning level
GROUP = RRC:WARNING:LEGACY
ID = LEGACY_RRC_DEBUG
DESC = RRC legacy logs - debug level
GROUP = RRC:DEBUG:LEGACY
ID = LEGACY_RRC_TRACE
DESC = RRC legacy logs - trace level
GROUP = RRC:TRACE:LEGACY
ID = LEGACY_RLC_INFO
DESC = RLC legacy logs - info level
GROUP = RLC:INFO:LEGACY
ID = LEGACY_RLC_ERROR
DESC = RLC legacy logs - error level
GROUP = RLC:ERROR:LEGACY
ID = LEGACY_RLC_WARNING
DESC = RLC legacy logs - warning level
GROUP = RLC:WARNING:LEGACY
ID = LEGACY_RLC_DEBUG
DESC = RLC legacy logs - debug level
GROUP = RLC:DEBUG:LEGACY
ID = LEGACY_RLC_TRACE
DESC = RLC legacy logs - trace level
GROUP = RLC:TRACE:LEGACY
ID = LEGACY_PDCP_INFO
DESC = PDCP legacy logs - info level
GROUP = PDCP:INFO:LEGACY
ID = LEGACY_PDCP_ERROR
DESC = PDCP legacy logs - error level
GROUP = PDCP:ERROR:LEGACY
ID = LEGACY_PDCP_WARNING
DESC = PDCP legacy logs - warning level
GROUP = PDCP:WARNING:LEGACY
ID = LEGACY_PDCP_DEBUG
DESC = PDCP legacy logs - debug level
GROUP = PDCP:DEBUG:LEGACY
ID = LEGACY_PDCP_TRACE
DESC = PDCP legacy logs - trace level
GROUP = PDCP:TRACE:LEGACY
ID = LEGACY_ENB_APP_INFO
DESC = ENB_APP legacy logs - info level
GROUP = ENB_APP:INFO:LEGACY
ID = LEGACY_ENB_APP_ERROR
DESC = ENB_APP legacy logs - error level
GROUP = ENB_APP:ERROR:LEGACY
ID = LEGACY_ENB_APP_WARNING
DESC = ENB_APP legacy logs - warning level
GROUP = ENB_APP:WARNING:LEGACY
ID = LEGACY_ENB_APP_DEBUG
DESC = ENB_APP legacy logs - debug level
GROUP = ENB_APP:DEBUG:LEGACY
ID = LEGACY_ENB_APP_TRACE
DESC = ENB_APP legacy logs - trace level
GROUP = ENB_APP:TRACE:LEGACY
ID = LEGACY_SCTP_INFO
DESC = SCTP legacy logs - info level
GROUP = SCTP:INFO:LEGACY
ID = LEGACY_SCTP_ERROR
DESC = SCTP legacy logs - error level
GROUP = SCTP:ERROR:LEGACY
ID = LEGACY_SCTP_WARNING
DESC = SCTP legacy logs - warning level
GROUP = SCTP:WARNING:LEGACY
ID = LEGACY_SCTP_DEBUG
DESC = SCTP legacy logs - debug level
GROUP = SCTP:DEBUG:LEGACY
ID = LEGACY_SCTP_TRACE
DESC = SCTP legacy logs - trace level
GROUP = SCTP:TRACE:LEGACY
ID = LEGACY_UDP__INFO
DESC = UDP_ legacy logs - info level
GROUP = UDP_:INFO:LEGACY
ID = LEGACY_UDP__ERROR
DESC = UDP_ legacy logs - error level
GROUP = UDP_:ERROR:LEGACY
ID = LEGACY_UDP__WARNING
DESC = UDP_ legacy logs - warning level
GROUP = UDP_:WARNING:LEGACY
ID = LEGACY_UDP__DEBUG
DESC = UDP_ legacy logs - debug level
GROUP = UDP_:DEBUG:LEGACY
ID = LEGACY_UDP__TRACE
DESC = UDP_ legacy logs - trace level
GROUP = UDP_:TRACE:LEGACY
ID = LEGACY_NAS_INFO
DESC = NAS legacy logs - info level
GROUP = NAS:INFO:LEGACY
ID = LEGACY_NAS_ERROR
DESC = NAS legacy logs - error level
GROUP = NAS:ERROR:LEGACY
ID = LEGACY_NAS_WARNING
DESC = NAS legacy logs - warning level
GROUP = NAS:WARNING:LEGACY
ID = LEGACY_NAS_DEBUG
DESC = NAS legacy logs - debug level
GROUP = NAS:DEBUG:LEGACY
ID = LEGACY_NAS_TRACE
DESC = NAS legacy logs - trace level
GROUP = NAS:TRACE:LEGACY
ID = LEGACY_HW_INFO
DESC = HW legacy logs - info level
GROUP = HW:INFO:LEGACY
ID = LEGACY_HW_ERROR
DESC = HW legacy logs - error level
GROUP = HW:ERROR:LEGACY
ID = LEGACY_HW_WARNING
DESC = HW legacy logs - warning level
GROUP = HW:WARNING:LEGACY
ID = LEGACY_HW_DEBUG
DESC = HW legacy logs - debug level
GROUP = HW:DEBUG:LEGACY
ID = LEGACY_HW_TRACE
DESC = HW legacy logs - trace level
GROUP = HW:TRACE:LEGACY
ID = LEGACY_EMU_INFO
DESC = EMU legacy logs - info level
GROUP = EMU:INFO:LEGACY
ID = LEGACY_EMU_ERROR
DESC = EMU legacy logs - error level
GROUP = EMU:ERROR:LEGACY
ID = LEGACY_EMU_WARNING
DESC = EMU legacy logs - warning level
GROUP = EMU:WARNING:LEGACY
ID = LEGACY_EMU_DEBUG
DESC = EMU legacy logs - debug level
GROUP = EMU:DEBUG:LEGACY
ID = LEGACY_EMU_TRACE
DESC = EMU legacy logs - trace level
GROUP = EMU:TRACE:LEGACY
ID = LEGACY_OTG_INFO
DESC = OTG legacy logs - info level
GROUP = OTG:INFO:LEGACY
ID = LEGACY_OTG_ERROR
DESC = OTG legacy logs - error level
GROUP = OTG:ERROR:LEGACY
ID = LEGACY_OTG_WARNING
DESC = OTG legacy logs - warning level
GROUP = OTG:WARNING:LEGACY
ID = LEGACY_OTG_DEBUG
DESC = OTG legacy logs - debug level
GROUP = OTG:DEBUG:LEGACY
ID = LEGACY_OTG_TRACE
DESC = OTG legacy logs - trace level
GROUP = OTG:TRACE:LEGACY
ID = LEGACY_OCG_INFO
DESC = OCG legacy logs - info level
GROUP = OCG:INFO:LEGACY
ID = LEGACY_OCG_ERROR
DESC = OCG legacy logs - error level
GROUP = OCG:ERROR:LEGACY
ID = LEGACY_OCG_WARNING
DESC = OCG legacy logs - warning level
GROUP = OCG:WARNING:LEGACY
ID = LEGACY_OCG_DEBUG
DESC = OCG legacy logs - debug level
GROUP = OCG:DEBUG:LEGACY
ID = LEGACY_OCG_TRACE
DESC = OCG legacy logs - trace level
GROUP = OCG:TRACE:LEGACY
ID = LEGACY_OCM_INFO
DESC = OCM legacy logs - info level
GROUP = OCM:INFO:LEGACY
ID = LEGACY_OCM_ERROR
DESC = OCM legacy logs - error level
GROUP = OCM:ERROR:LEGACY
ID = LEGACY_OCM_WARNING
DESC = OCM legacy logs - warning level
GROUP = OCM:WARNING:LEGACY
ID = LEGACY_OCM_DEBUG
DESC = OCM legacy logs - debug level
GROUP = OCM:DEBUG:LEGACY
ID = LEGACY_OCM_TRACE
DESC = OCM legacy logs - trace level
GROUP = OCM:TRACE:LEGACY
ID = LEGACY_OIP_INFO
DESC = OIP legacy logs - info level
GROUP = OIP:INFO:LEGACY
ID = LEGACY_OIP_ERROR
DESC = OIP legacy logs - error level
GROUP = OIP:ERROR:LEGACY
ID = LEGACY_OIP_WARNING
DESC = OIP legacy logs - warning level
GROUP = OIP:WARNING:LEGACY
ID = LEGACY_OIP_DEBUG
DESC = OIP legacy logs - debug level
GROUP = OIP:DEBUG:LEGACY
ID = LEGACY_OIP_TRACE
DESC = OIP legacy logs - trace level
GROUP = OIP:TRACE:LEGACY
ID = LEGACY_OMG_INFO
DESC = OMG legacy logs - info level
GROUP = OMG:INFO:LEGACY
ID = LEGACY_OMG_ERROR
DESC = OMG legacy logs - error level
GROUP = OMG:ERROR:LEGACY
ID = LEGACY_OMG_WARNING
DESC = OMG legacy logs - warning level
GROUP = OMG:WARNING:LEGACY
ID = LEGACY_OMG_DEBUG
DESC = OMG legacy logs - debug level
GROUP = OMG:DEBUG:LEGACY
ID = LEGACY_OMG_TRACE
DESC = OMG legacy logs - trace level
GROUP = OMG:TRACE:LEGACY
ID = LEGACY_OPT_INFO
DESC = OPT legacy logs - info level
GROUP = OPT:INFO:LEGACY
ID = LEGACY_OPT_ERROR
DESC = OPT legacy logs - error level
GROUP = OPT:ERROR:LEGACY
ID = LEGACY_OPT_WARNING
DESC = OPT legacy logs - warning level
GROUP = OPT:WARNING:LEGACY
ID = LEGACY_OPT_DEBUG
DESC = OPT legacy logs - debug level
GROUP = OPT:DEBUG:LEGACY
ID = LEGACY_OPT_TRACE
DESC = OPT legacy logs - trace level
GROUP = OPT:TRACE:LEGACY
ID = LEGACY_GTPU_INFO
DESC = GTPU legacy logs - info level
GROUP = GTPU:INFO:LEGACY
ID = LEGACY_GTPU_ERROR
DESC = GTPU legacy logs - error level
GROUP = GTPU:ERROR:LEGACY
ID = LEGACY_GTPU_WARNING
DESC = GTPU legacy logs - warning level
GROUP = GTPU:WARNING:LEGACY
ID = LEGACY_GTPU_DEBUG
DESC = GTPU legacy logs - debug level
GROUP = GTPU:DEBUG:LEGACY
ID = LEGACY_GTPU_TRACE
DESC = GTPU legacy logs - trace level
GROUP = GTPU:TRACE:LEGACY
ID = LEGACY_TMR_INFO
DESC = TMR legacy logs - info level
GROUP = TMR:INFO:LEGACY
ID = LEGACY_TMR_ERROR
DESC = TMR legacy logs - error level
GROUP = TMR:ERROR:LEGACY
ID = LEGACY_TMR_WARNING
DESC = TMR legacy logs - warning level
GROUP = TMR:WARNING:LEGACY
ID = LEGACY_TMR_DEBUG
DESC = TMR legacy logs - debug level
GROUP = TMR:DEBUG:LEGACY
ID = LEGACY_TMR_TRACE
DESC = TMR legacy logs - trace level
GROUP = TMR:TRACE:LEGACY
ID = LEGACY_OSA_INFO
DESC = OSA legacy logs - info level
GROUP = OSA:INFO:LEGACY
ID = LEGACY_OSA_ERROR
DESC = OSA legacy logs - error level
GROUP = OSA:ERROR:LEGACY
ID = LEGACY_OSA_WARNING
DESC = OSA legacy logs - warning level
GROUP = OSA:WARNING:LEGACY
ID = LEGACY_OSA_DEBUG
DESC = OSA legacy logs - debug level
GROUP = OSA:DEBUG:LEGACY
ID = LEGACY_OSA_TRACE
DESC = OSA legacy logs - trace level
GROUP = OSA:TRACE:LEGACY
# this is a bad hack but I won't fix (function util_print_hex_octets
# in openairinterface5g/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c
# does funky things with the LOG_x macros but we work on the C pre-processor
# level and this funkyness is not easily dealable with, so be it...)
ID = LEGACY_component_INFO
DESC = component legacy logs - info level
GROUP = component:INFO:LEGACY
ID = LEGACY_component_ERROR
DESC = component legacy logs - error level
GROUP = component:ERROR:LEGACY
ID = LEGACY_component_WARNING
DESC = component legacy logs - warning level
GROUP = component:WARNING:LEGACY
ID = LEGACY_component_DEBUG
DESC = component legacy logs - debug level
GROUP = component:DEBUG:LEGACY
ID = LEGACY_component_TRACE
DESC = component legacy logs - trace level
GROUP = component:TRACE:LEGACY
ID = LEGACY_componentP_INFO
DESC = componentP legacy logs - info level
GROUP = componentP:INFO:LEGACY
ID = LEGACY_componentP_ERROR
DESC = componentP legacy logs - error level
GROUP = componentP:ERROR:LEGACY
ID = LEGACY_componentP_WARNING
DESC = componentP legacy logs - warning level
GROUP = componentP:WARNING:LEGACY
ID = LEGACY_componentP_DEBUG
DESC = componentP legacy logs - debug level
GROUP = componentP:DEBUG:LEGACY
ID = LEGACY_componentP_TRACE
DESC = componentP legacy logs - trace level
GROUP = componentP:TRACE:LEGACY
#needed?
ID = LEGACY_CLI_INFO
DESC = CLI legacy logs - info level
GROUP = CLI:INFO:LEGACY
ID = LEGACY_CLI_ERROR
DESC = CLI legacy logs - error level
GROUP = CLI:ERROR:LEGACY
ID = LEGACY_CLI_WARNING
DESC = CLI legacy logs - warning level
GROUP = CLI:WARNING:LEGACY
ID = LEGACY_CLI_DEBUG
DESC = CLI legacy logs - debug level
GROUP = CLI:DEBUG:LEGACY
ID = LEGACY_CLI_TRACE
DESC = CLI legacy logs - trace level
GROUP = CLI:TRACE:LEGACY
#for debug/test - not used
ID = first
ID = buf_test
+25
View File
@@ -0,0 +1,25 @@
#include <stdio.h>
void print(int n)
{
int i;
printf("#define T%d(t", n);
for(i=0; i<(n-1)/2; i++) printf(",t%d,x%d", i, i);
printf(") \\\n");
printf(" do { \\\n");
printf(" if (T_ACTIVE(t)) { \\\n");
printf(" T_LOCAL_DATA \\\n");
printf(" T_HEADER(t); \\\n");
for(i=0; i<(n-1)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i);
printf(" T_SEND(); \\\n");
printf(" } \\\n");
printf(" } while (0)\n");
printf("\n");
}
int main(void)
{
int i;
for (i = 11; i <= 33; i+=2) print(i);
return 0;
}
+155
View File
@@ -0,0 +1,155 @@
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char **unique_ids;
int unique_ids_size;
int unique_ids_maxsize;
int cmp(const void *p1, const void *p2)
{
return strcmp(*(char * const *)p1, *(char * const *)p2);
}
/* return 1 if s was not already known, 0 if it was */
int new_unique_id(char *s)
{
if (unique_ids_size)
if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) {
printf("FATAL: ID %s is not unique\n", s);
return 0;
}
if (unique_ids_size == unique_ids_maxsize) {
unique_ids_maxsize += 256;
unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *));
if (unique_ids == NULL) { printf("out of memory\n"); abort(); }
}
unique_ids[unique_ids_size] = strdup(s);
if (unique_ids[unique_ids_size] == NULL)
{ printf("out of memory\n"); abort(); }
unique_ids_size++;
qsort(unique_ids, unique_ids_size, sizeof(char *), cmp);
return 1;
}
char *bufname;
int bufname_size;
int bufname_maxsize;
void putname(int c)
{
if (bufname_size == bufname_maxsize) {
bufname_maxsize += 256;
bufname = realloc(bufname, bufname_maxsize);
if (bufname == NULL) { printf("memory allocation error\n"); exit(1); }
}
bufname[bufname_size] = c;
bufname_size++;
}
char *bufvalue;
int bufvalue_size;
int bufvalue_maxsize;
void putvalue(int c)
{
if (bufvalue_size == bufvalue_maxsize) {
bufvalue_maxsize += 256;
bufvalue = realloc(bufvalue, bufvalue_maxsize);
if (bufvalue == NULL) { printf("memory allocation error\n"); exit(1); }
}
bufvalue[bufvalue_size] = c;
bufvalue_size++;
}
void smash_spaces(FILE *f)
{
int c;
while (1) {
c = fgetc(f);
if (isspace(c)) continue;
if (c == ' ') continue;
if (c == '\t') continue;
if (c == '\n') continue;
if (c == 10 || c == 13) continue;
if (c == '#') {
while (1) {
c = fgetc(f);
if (c == '\n' || c == EOF) break;
}
continue;
}
break;
}
if (c != EOF) ungetc(c, f);
}
void get_line(FILE *f, char **name, char **value)
{
int c;
bufname_size = 0;
bufvalue_size = 0;
*name = NULL;
*value = NULL;
smash_spaces(f);
c = fgetc(f);
while (!(c == '=' || isspace(c) || c == EOF)) { putname(c); c = fgetc(f); }
if (c == EOF) return;
putname(0);
while (!(c == EOF || c == '=')) c = fgetc(f);
if (c == EOF) return;
smash_spaces(f);
c = fgetc(f);
while (!(c == 10 || c == 13 || c == EOF)) { putvalue(c); c = fgetc(f); }
putvalue(0);
if (bufname_size <= 1) return;
if (bufvalue_size <= 1) return;
*name = bufname;
*value = bufvalue;
}
int main(int n, char **v)
{
FILE *in;
FILE *out;
char *name;
char *value;
char *in_name;
char *out_name;
if (n != 3) { printf("gimme <source> <dest>\n"); exit(1); }
n = 0;
in_name = v[1];
out_name = v[2];
in = fopen(in_name, "r"); if (in == NULL) { perror(in_name); exit(1); }
out = fopen(out_name, "w"); if (out == NULL) { perror(out_name); exit(1); }
fprintf(out, "/* generated file, do not edit by hand */\n\n");
while (1) {
get_line(in, &name, &value);
if (name == NULL) break;
printf("name '%s' value '%s'\n", name, value);
if (isspace(value[strlen(value)-1])) {
printf("bad value '%s' (no space at the end please!)\n", value);
unlink(out_name);
exit(1);
}
if (!strcmp(name, "ID")) {
if (!new_unique_id(value)) { unlink(out_name); exit(1); }
fprintf(out, "#define T_%s T_ID(%d)\n", value, n);
n++;
}
}
fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n);
fclose(in);
fclose(out);
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#include "T.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
T_connect_to_tracer("127.0.0.1", 2020);
printf("after connect\n");
while (1) {
char *buf = "hello world %s!\n";
//T(T_first, T_PRINTF("hello world %s!\n", "yo"));
T(T_buf_test, T_BUFFER("hello world %s!\n", strlen(buf)+1));
usleep(1);
}
while (1) pause();
return 0;
}
+24
View File
@@ -0,0 +1,24 @@
CC=gcc
CFLAGS=-Wall -g -pthread -DT_TRACER
#CFLAGS += -O3 -ffast-math -fomit-frame-pointer
LIBS=-lX11 -lm
#comment those two lines to NOT use shared memory
CFLAGS += -DT_USE_SHARED_MEMORY
LIBS += -lrt
PROG=tracer
OBJS=main.o plot.o database.o forward.o
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
main.o: ../T_IDs.h ../T_defs.h
clean:
rm -f *.o $(PROG) core
+325
View File
@@ -0,0 +1,325 @@
#include "defs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
typedef struct {
char *name;
char *desc;
char **groups;
int size;
int id;
} id;
typedef struct {
char *name;
char **ids;
int size;
} group;
typedef struct {
char *name;
id *i;
int isize;
group *g;
int gsize;
} database;
typedef struct {
char *data;
int size;
int maxsize;
} buffer;
typedef struct {
buffer name;
buffer value;
} parser;
void put(buffer *b, int c)
{
if (b->size == b->maxsize) {
b->maxsize += 256;
b->data = realloc(b->data, b->maxsize);
if (b->data == NULL) { printf("memory allocation error\n"); exit(1); }
}
b->data[b->size] = c;
b->size++;
}
void smash_spaces(FILE *f)
{
int c;
while (1) {
c = fgetc(f);
if (isspace(c)) continue;
if (c == ' ') continue;
if (c == '\t') continue;
if (c == '\n') continue;
if (c == 10 || c == 13) continue;
if (c == '#') {
while (1) {
c = fgetc(f);
if (c == '\n' || c == EOF) break;
}
continue;
}
break;
}
if (c != EOF) ungetc(c, f);
}
void get_line(parser *p, FILE *f, char **name, char **value)
{
int c;
p->name.size = 0;
p->value.size = 0;
*name = NULL;
*value = NULL;
smash_spaces(f);
c = fgetc(f);
while (!(c == '=' || isspace(c) || c == EOF))
{ put(&p->name, c); c = fgetc(f); }
if (c == EOF) return;
put(&p->name, 0);
while (!(c == EOF || c == '=')) c = fgetc(f);
if (c == EOF) return;
smash_spaces(f);
c = fgetc(f);
while (!(c == 10 || c == 13 || c == EOF))
{ put(&p->value, c); c = fgetc(f); }
put(&p->value, 0);
if (p->name.size <= 1) return;
if (p->value.size <= 1) return;
*name = p->name.data;
*value = p->value.data;
}
int group_cmp(const void *_p1, const void *_p2)
{
const group *p1 = _p1;
const group *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int id_cmp(const void *_p1, const void *_p2)
{
const id *p1 = _p1;
const id *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int string_cmp(const void *_p1, const void *_p2)
{
char * const *p1 = _p1;
char * const *p2 = _p2;
return strcmp(*p1, *p2);
}
id *add_id(database *r, char *idname, int i)
{
if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL)
{ printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); }
if ((r->isize & 1023) == 0) {
r->i = realloc(r->i, (r->isize + 1024) * sizeof(id));
if (r->i == NULL) { printf("out of memory\n"); exit(1); }
}
r->i[r->isize].name = strdup(idname);
if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); }
r->i[r->isize].desc = NULL;
r->i[r->isize].groups = NULL;
r->i[r->isize].size = 0;
r->i[r->isize].id = i;
r->isize++;
qsort(r->i, r->isize, sizeof(id), id_cmp);
return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp);
}
group *get_group(database *r, char *group_name)
{
group *ret;
ret = bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
if (ret != NULL) return ret;
if ((r->gsize & 1023) == 0) {
r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group));
if (r->g == NULL) abort();
}
r->g[r->gsize].name = strdup(group_name);
if (r->g[r->gsize].name == NULL) abort();
r->g[r->gsize].ids = NULL;
r->g[r->gsize].size = 0;
r->gsize++;
qsort(r->g, r->gsize, sizeof(group), group_cmp);
return bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
}
void group_add_id(group *g, char *id)
{
if ((g->size & 1023) == 0) {
g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *));
if (g->ids == NULL) abort();
}
g->ids[g->size] = id;
g->size++;
}
void id_add_group(id *i, char *group)
{
char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp);
if (g != NULL) return;
if ((i->size & 1023) == 0) {
i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *));
if (i->groups == NULL) abort();
}
i->groups[i->size] = group;
i->size++;
qsort(i->groups, i->size, sizeof(char *), string_cmp);
}
void add_groups(database *r, id *i, char *groups)
{
group *g;
if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);}
while (1) {
char *start = groups;
char *end = start;
while (!isspace(*end) && *end != ':' && *end != 0) end++;
if (end == start) {
printf("bad group line: groups are seperated by ':'\n");
abort();
}
if (*end == 0) end = NULL; else *end = 0;
g = get_group(r, start);
group_add_id(g, i->name);
id_add_group(i, g->name);
if (end == NULL) break;
end++;
while ((isspace(*end) || *end == ':') && *end != 0) end++;
if (*end == 0) break;
groups = end;
}
}
void add_desc(id *i, char *desc)
{
if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);}
i->desc = strdup(desc); if (i->desc == NULL) abort();
}
void *parse_database(char *filename)
{
FILE *in;
parser p;
database *r;
char *name, *value;
id *last_id = NULL;
int i;
r = calloc(1, sizeof(*r)); if (r == NULL) abort();
memset(&p, 0, sizeof(p));
r->name = strdup(filename); if (r->name == NULL) abort();
in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); }
i = 0;
while (1) {
get_line(&p, in, &name, &value);
if (name == NULL) break;
//printf("%s %s\n", name, value);
if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; }
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
if (!strcmp(name, "DESC")) add_desc(last_id, value);
}
fclose(in);
free(p.name.data);
free(p.value.data);
return r;
}
void dump_database(void *_d)
{
database *d = _d;
int i;
printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize);
for (i = 0; i < d->isize; i++) {
int j;
printf("ID %s [%s] [in %d group%s]\n",
d->i[i].name, d->i[i].desc ? d->i[i].desc : "",
d->i[i].size, d->i[i].size > 1 ? "s" : "");
for (j = 0; j < d->i[i].size; j++)
printf(" in GROUP: %s\n", d->i[i].groups[j]);
}
for (i = 0; i < d->gsize; i++) {
int j;
printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size);
for (j = 0; j < d->g[i].size; j++)
printf(" contains ID: %s\n", d->g[i].ids[j]);
}
}
void list_ids(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name);
}
void list_groups(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name);
}
static int onoff_id(database *d, char *name, int *a, int onoff)
{
id *i;
i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp);
if (i == NULL) return 0;
a[i->id] = onoff;
printf("turning %s %s\n", onoff ? "ON" : "OFF", name);
return 1;
}
static int onoff_group(database *d, char *name, int *a, int onoff)
{
group *g;
int i;
g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp);
if (g == NULL) return 0;
for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff);
return 1;
}
void on_off(void *_d, char *item, int *a, int onoff)
{
int done;
database *d = _d;
int i;
if (item == NULL) {
for (i = 0; i < d->isize; i++) a[i] = onoff;
printf("turning %s all traces\n", onoff ? "ON" : "OFF");
return;
}
done = onoff_group(d, item, a, onoff);
done += onoff_id(d, item, a, onoff);
if (done == 0) {
printf("ERROR: ID/group '%s' not found in database\n", item);
exit(1);
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef _TRACER_DEFS_H_
#define _TRACER_DEFS_H_
/* types of plots */
#define PLOT_VS_TIME 0
#define PLOT_IQ_POINTS 1
#define PLOT_MINMAX 2
void new_thread(void *(*f)(void *), void *data);
/* ... is { int count; int type; char *color; } for 'nplots' plots */
void *make_plot(int width, int height, char *title, int nplots, ...);
void plot_set(void *plot, float *data, int len, int pos, int pp);
void iq_plot_set(void *plot, short *data, int len, int pos, int pp);
void iq_plot_set_sized(void *_plot, short *data, int len, int pp);
void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp);
void iq_plot_add_energy_point_loop(void *_plot, int e, int pp);
/* returns an opaque pointer - truly a 'database *', see t_data.c */
void *parse_database(char *filename);
void dump_database(void *database);
void list_ids(void *database);
void list_groups(void *database);
void on_off(void *d, char *item, int *a, int onoff);
void *forwarder(char *ip, int port);
void forward(void *forwarder, char *buf, int size);
void forward_start_client(void *forwarder, int socket);
#endif /* _TRACER_DEFS_H_ */
+159
View File
@@ -0,0 +1,159 @@
#include "defs.h"
#include <stdlib.h>
#include <stdio.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
typedef struct databuf {
char *d;
int l;
struct databuf *next;
} databuf;
typedef struct {
int s;
int sc;
pthread_mutex_t lock;
pthread_mutex_t datalock;
pthread_cond_t datacond;
databuf * volatile head, *tail;
} forward_data;
static void *data_sender(void *_f)
{
forward_data *f = _f;
databuf *cur;
char *buf, *b;
int size;
wait:
if (pthread_mutex_lock(&f->datalock)) abort();
while (f->head == NULL)
if (pthread_cond_wait(&f->datacond, &f->datalock)) abort();
cur = f->head;
buf = cur->d;
size = cur->l;
f->head = cur->next;
if (f->head == NULL) f->tail = NULL;
if (pthread_mutex_unlock(&f->datalock)) abort();
free(cur);
goto process;
process:
if (pthread_mutex_lock(&f->lock)) abort();
b = buf;
while (size) {
int l = write(f->s, b, size);
if (l <= 0) { printf("forward error\n"); exit(1); }
size -= l;
b += l;
}
if (pthread_mutex_unlock(&f->lock)) abort();
free(buf);
goto wait;
}
static void do_forward(forward_data *f, int from, int to, int lock)
{
int l, len;
char *b;
char buf[1024];
while (1) {
len = read(from, buf, 1024);
if (len <= 0) break;
b = buf;
if (lock) if (pthread_mutex_lock(&f->lock)) abort();
while (len) {
l = write(to, b, len);
if (l <= 0) break;
len -= l;
b += l;
}
if (lock) if (pthread_mutex_unlock(&f->lock)) abort();
}
}
static void *forward_s_to_sc(void *_f)
{
forward_data *f = _f;
do_forward(f, f->s, f->sc, 0);
return NULL;
}
static void *forward_sc_to_s(void *_f)
{
#if 0
forward_data *f = _f;
do_forward(f, f->sc, f->s, 1);
printf("INFO: forwarder exits\n");
#endif
return NULL;
}
void forward_start_client(void *_f, int s)
{
forward_data *f = _f;
f->sc = s;
new_thread(forward_s_to_sc, f);
new_thread(forward_sc_to_s, f);
}
void *forwarder(char *ip, int port)
{
forward_data *f;
struct sockaddr_in a;
f = malloc(sizeof(*f)); if (f == NULL) abort();
pthread_mutex_init(&f->lock, NULL);
pthread_mutex_init(&f->datalock, NULL);
pthread_cond_init(&f->datacond, NULL);
f->sc = -1;
f->head = f->tail = NULL;
f->s = socket(AF_INET, SOCK_STREAM, 0);
if (f->s == -1) { perror("socket"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr(ip);
if (connect(f->s, (struct sockaddr *)&a, sizeof(a)) == -1)
{ perror("connect"); exit(1); }
new_thread(data_sender, f);
return f;
}
void forward(void *_forwarder, char *buf, int size)
{
forward_data *f = _forwarder;
databuf *new;
new = malloc(sizeof(*new)); if (new == NULL) abort();
if (pthread_mutex_lock(&f->datalock)) abort();
new->d = malloc(size); if (new->d == NULL) abort();
memcpy(new->d, buf, size);
new->l = size;
new->next = NULL;
if (f->head == NULL) f->head = new;
if (f->tail != NULL) f->tail->next = new;
f->tail = new;
if (pthread_cond_signal(&f->datacond)) abort();
if (pthread_mutex_unlock(&f->datalock)) abort();
}
+582
View File
@@ -0,0 +1,582 @@
#include <stdio.h>
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include <pthread.h>
#include "defs.h"
#define T_ID(x) x
#include "../T_IDs.h"
#include "../T_defs.h"
#define BLUE "#0c0c72"
#define RED "#d72828"
void *ul_plot;
void *chest_plot;
void *pusch_iq_plot;
void *pucch_iq_plot;
void *pucch_plot;
#ifdef T_USE_SHARED_MEMORY
T_cache_t *T_cache;
int T_busylist_head;
int T_pos;
static inline int GET(int s, void *out, int count)
{
if (count == 1) {
*(char *)out = T_cache[T_busylist_head].buffer[T_pos];
T_pos++;
return 1;
}
memcpy(out, T_cache[T_busylist_head].buffer + T_pos, count);
T_pos += count;
return count;
}
#else /* T_USE_SHARED_MEMORY */
#define GET fullread
int fullread(int fd, void *_buf, int count)
{
char *buf = _buf;
int ret = 0;
int l;
while (count) {
l = read(fd, buf, count);
if (l <= 0) { printf("read socket problem\n"); abort(); }
count -= l;
buf += l;
ret += l;
}
return ret;
}
#endif /* T_USE_SHARED_MEMORY */
int get_connection(char *addr, int port)
{
struct sockaddr_in a;
socklen_t alen;
int s, t;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
t = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
{ perror("setsockopt"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr(addr);
if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
if (listen(s, 5)) { perror("bind"); exit(1); }
alen = sizeof(a);
t = accept(s, (struct sockaddr *)&a, &alen);
if (t == -1) { perror("accept"); exit(1); }
close(s);
return t;
}
void get_string(int s, char *out)
{
while (1) {
if (GET(s, out, 1) != 1) abort();
if (*out == 0) break;
out++;
}
}
void get_message(int s)
{
#define S(x, y) do { \
char str[T_BUFFER_MAX]; \
get_string(s, str); \
printf("["x"]["y"] %s", str); \
} while (0)
int m;
#ifdef T_USE_SHARED_MEMORY
T_pos = 0;
#endif
if (GET(s, &m, sizeof(int)) != sizeof(int)) abort();
switch (m) {
case T_first: {
char str[T_BUFFER_MAX];
get_string(s, str);
printf("%s", str);
break;
}
case T_LEGACY_MAC_INFO: S("MAC", "INFO"); break;
case T_LEGACY_MAC_ERROR: S("MAC", "ERROR"); break;
case T_LEGACY_MAC_WARNING: S("MAC", "WARNING"); break;
case T_LEGACY_MAC_DEBUG: S("MAC", "DEBUG"); break;
case T_LEGACY_MAC_TRACE: S("MAC", "TRACE"); break;
case T_LEGACY_PHY_INFO: S("PHY", "INFO"); break;
case T_LEGACY_PHY_ERROR: S("PHY", "ERROR"); break;
case T_LEGACY_PHY_WARNING: S("PHY", "WARNING"); break;
case T_LEGACY_PHY_DEBUG: S("PHY", "DEBUG"); break;
case T_LEGACY_PHY_TRACE: S("PHY", "TRACE"); break;
case T_LEGACY_S1AP_INFO: S("S1AP", "INFO"); break;
case T_LEGACY_S1AP_ERROR: S("S1AP", "ERROR"); break;
case T_LEGACY_S1AP_WARNING: S("S1AP", "WARNING"); break;
case T_LEGACY_S1AP_DEBUG: S("S1AP", "DEBUG"); break;
case T_LEGACY_S1AP_TRACE: S("S1AP", "TRACE"); break;
case T_LEGACY_RRC_INFO: S("RRC", "INFO"); break;
case T_LEGACY_RRC_ERROR: S("RRC", "ERROR"); break;
case T_LEGACY_RRC_WARNING: S("RRC", "WARNING"); break;
case T_LEGACY_RRC_DEBUG: S("RRC", "DEBUG"); break;
case T_LEGACY_RRC_TRACE: S("RRC", "TRACE"); break;
case T_LEGACY_RLC_INFO: S("RLC", "INFO"); break;
case T_LEGACY_RLC_ERROR: S("RLC", "ERROR"); break;
case T_LEGACY_RLC_WARNING: S("RLC", "WARNING"); break;
case T_LEGACY_RLC_DEBUG: S("RLC", "DEBUG"); break;
case T_LEGACY_RLC_TRACE: S("RLC", "TRACE"); break;
case T_LEGACY_PDCP_INFO: S("PDCP", "INFO"); break;
case T_LEGACY_PDCP_ERROR: S("PDCP", "ERROR"); break;
case T_LEGACY_PDCP_WARNING: S("PDCP", "WARNING"); break;
case T_LEGACY_PDCP_DEBUG: S("PDCP", "DEBUG"); break;
case T_LEGACY_PDCP_TRACE: S("PDCP", "TRACE"); break;
case T_LEGACY_ENB_APP_INFO: S("ENB_APP", "INFO"); break;
case T_LEGACY_ENB_APP_ERROR: S("ENB_APP", "ERROR"); break;
case T_LEGACY_ENB_APP_WARNING: S("ENB_APP", "WARNING"); break;
case T_LEGACY_ENB_APP_DEBUG: S("ENB_APP", "DEBUG"); break;
case T_LEGACY_ENB_APP_TRACE: S("ENB_APP", "TRACE"); break;
case T_LEGACY_SCTP_INFO: S("SCTP", "INFO"); break;
case T_LEGACY_SCTP_ERROR: S("SCTP", "ERROR"); break;
case T_LEGACY_SCTP_WARNING: S("SCTP", "WARNING"); break;
case T_LEGACY_SCTP_DEBUG: S("SCTP", "DEBUG"); break;
case T_LEGACY_SCTP_TRACE: S("SCTP", "TRACE"); break;
case T_LEGACY_UDP__INFO: S("UDP", "INFO"); break;
case T_LEGACY_UDP__ERROR: S("UDP", "ERROR"); break;
case T_LEGACY_UDP__WARNING: S("UDP", "WARNING"); break;
case T_LEGACY_UDP__DEBUG: S("UDP", "DEBUG"); break;
case T_LEGACY_UDP__TRACE: S("UDP", "TRACE"); break;
case T_LEGACY_NAS_INFO: S("NAS", "INFO"); break;
case T_LEGACY_NAS_ERROR: S("NAS", "ERROR"); break;
case T_LEGACY_NAS_WARNING: S("NAS", "WARNING"); break;
case T_LEGACY_NAS_DEBUG: S("NAS", "DEBUG"); break;
case T_LEGACY_NAS_TRACE: S("NAS", "TRACE"); break;
case T_LEGACY_HW_INFO: S("HW", "INFO"); break;
case T_LEGACY_HW_ERROR: S("HW", "ERROR"); break;
case T_LEGACY_HW_WARNING: S("HW", "WARNING"); break;
case T_LEGACY_HW_DEBUG: S("HW", "DEBUG"); break;
case T_LEGACY_HW_TRACE: S("HW", "TRACE"); break;
case T_LEGACY_EMU_INFO: S("EMU", "INFO"); break;
case T_LEGACY_EMU_ERROR: S("EMU", "ERROR"); break;
case T_LEGACY_EMU_WARNING: S("EMU", "WARNING"); break;
case T_LEGACY_EMU_DEBUG: S("EMU", "DEBUG"); break;
case T_LEGACY_EMU_TRACE: S("EMU", "TRACE"); break;
case T_LEGACY_OTG_INFO: S("OTG", "INFO"); break;
case T_LEGACY_OTG_ERROR: S("OTG", "ERROR"); break;
case T_LEGACY_OTG_WARNING: S("OTG", "WARNING"); break;
case T_LEGACY_OTG_DEBUG: S("OTG", "DEBUG"); break;
case T_LEGACY_OTG_TRACE: S("OTG", "TRACE"); break;
case T_LEGACY_OCG_INFO: S("OCG", "INFO"); break;
case T_LEGACY_OCG_ERROR: S("OCG", "ERROR"); break;
case T_LEGACY_OCG_WARNING: S("OCG", "WARNING"); break;
case T_LEGACY_OCG_DEBUG: S("OCG", "DEBUG"); break;
case T_LEGACY_OCG_TRACE: S("OCG", "TRACE"); break;
case T_LEGACY_OCM_INFO: S("OCM", "INFO"); break;
case T_LEGACY_OCM_ERROR: S("OCM", "ERROR"); break;
case T_LEGACY_OCM_WARNING: S("OCM", "WARNING"); break;
case T_LEGACY_OCM_DEBUG: S("OCM", "DEBUG"); break;
case T_LEGACY_OCM_TRACE: S("OCM", "TRACE"); break;
case T_LEGACY_OMG_INFO: S("OMG", "INFO"); break;
case T_LEGACY_OMG_ERROR: S("OMG", "ERROR"); break;
case T_LEGACY_OMG_WARNING: S("OMG", "WARNING"); break;
case T_LEGACY_OMG_DEBUG: S("OMG", "DEBUG"); break;
case T_LEGACY_OMG_TRACE: S("OMG", "TRACE"); break;
case T_LEGACY_OIP_INFO: S("OIP", "INFO"); break;
case T_LEGACY_OIP_ERROR: S("OIP", "ERROR"); break;
case T_LEGACY_OIP_WARNING: S("OIP", "WARNING"); break;
case T_LEGACY_OIP_DEBUG: S("OIP", "DEBUG"); break;
case T_LEGACY_OIP_TRACE: S("OIP", "TRACE"); break;
case T_LEGACY_GTPU_INFO: S("GTPU", "INFO"); break;
case T_LEGACY_GTPU_ERROR: S("GTPU", "ERROR"); break;
case T_LEGACY_GTPU_WARNING: S("GTPU", "WARNING"); break;
case T_LEGACY_GTPU_DEBUG: S("GTPU", "DEBUG"); break;
case T_LEGACY_GTPU_TRACE: S("GTPU", "TRACE"); break;
case T_LEGACY_TMR_INFO: S("TMR", "INFO"); break;
case T_LEGACY_TMR_ERROR: S("TMR", "ERROR"); break;
case T_LEGACY_TMR_WARNING: S("TMR", "WARNING"); break;
case T_LEGACY_TMR_DEBUG: S("TMR", "DEBUG"); break;
case T_LEGACY_TMR_TRACE: S("TMR", "TRACE"); break;
case T_LEGACY_OSA_INFO: S("OSA", "INFO"); break;
case T_LEGACY_OSA_ERROR: S("OSA", "ERROR"); break;
case T_LEGACY_OSA_WARNING: S("OSA", "WARNING"); break;
case T_LEGACY_OSA_DEBUG: S("OSA", "DEBUG"); break;
case T_LEGACY_OSA_TRACE: S("OSA", "TRACE"); break;
case T_LEGACY_component_INFO: S("XXX", "INFO"); break;
case T_LEGACY_component_ERROR: S("XXX", "ERROR"); break;
case T_LEGACY_component_WARNING: S("XXX", "WARNING"); break;
case T_LEGACY_component_DEBUG: S("XXX", "DEBUG"); break;
case T_LEGACY_component_TRACE: S("XXX", "TRACE"); break;
case T_LEGACY_componentP_INFO: S("XXX", "INFO"); break;
case T_LEGACY_componentP_ERROR: S("XXX", "ERROR"); break;
case T_LEGACY_componentP_WARNING: S("XXX", "WARNING"); break;
case T_LEGACY_componentP_DEBUG: S("XXX", "DEBUG"); break;
case T_LEGACY_componentP_TRACE: S("XXX", "TRACE"); break;
case T_LEGACY_CLI_INFO: S("CLI", "INFO"); break;
case T_LEGACY_CLI_ERROR: S("CLI", "ERROR"); break;
case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break;
case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break;
case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break;
case T_ENB_INPUT_SIGNAL: {
unsigned char buf[T_BUFFER_MAX];
int size;
int eNB, frame, subframe, antenna;
GET(s, &eNB, sizeof(int));
GET(s, &frame, sizeof(int));
GET(s, &subframe, sizeof(int));
GET(s, &antenna, sizeof(int));
GET(s, &size, sizeof(int));
GET(s, buf, size);
#if 0
printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna "
"%d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "
"%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2],
buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],
buf[11],buf[12],buf[13],buf[14],buf[15]);
#endif
if (size != 4 * 7680)
{printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed "
"(received %d bytes = %d samples)\n", size, size/4);abort();}
if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0);
break;
}
case T_ENB_UL_CHANNEL_ESTIMATE: {
unsigned char buf[T_BUFFER_MAX];
int size;
int eNB, UE, frame, subframe, antenna;
GET(s, &eNB, sizeof(int));
GET(s, &UE, sizeof(int));
GET(s, &frame, sizeof(int));
GET(s, &subframe, sizeof(int));
GET(s, &antenna, sizeof(int));
GET(s, &size, sizeof(int));
GET(s, buf, size);
if (size != 512*4)
{printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n");
abort();}
if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0, 0);
break;
}
case T_PUSCH_IQ: {
unsigned char buf[T_BUFFER_MAX];
int size;
int eNB, UE, frame, subframe, nb_rb;
GET(s, &eNB, sizeof(int));
GET(s, &UE, sizeof(int));
GET(s, &frame, sizeof(int));
GET(s, &subframe, sizeof(int));
GET(s, &nb_rb, sizeof(int));
GET(s, &size, sizeof(int));
GET(s, buf, size);
if (size != 12*25*14*4)
{printf("bad T_PUSCH_IQ, we want 25 RBs and 14 symbols/TTI\n");
abort();}
if (pusch_iq_plot) {
uint32_t *src, *dst;
int i, l;
dst = (uint32_t*)buf;
for (l = 0; l < 14; l++) {
src = (uint32_t*)buf + l * 12 * 25;
for (i = 0; i < nb_rb*12; i++) *dst++ = *src++;
}
iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14, 0);
}
break;
}
case T_PUCCH_1AB_IQ: {
int eNB, UE, frame, subframe, I, Q;
GET(s, &eNB, sizeof(int));
GET(s, &UE, sizeof(int));
GET(s, &frame, sizeof(int));
GET(s, &subframe, sizeof(int));
GET(s, &I, sizeof(int));
GET(s, &Q, sizeof(int));
if (pucch_iq_plot) iq_plot_add_iq_point_loop(pucch_iq_plot,I*10,Q*10, 0);
break;
}
case T_PUCCH_1_ENERGY: {
int eNB, UE, frame, subframe, e, t;
GET(s, &eNB, sizeof(int));
GET(s, &UE, sizeof(int));
GET(s, &frame, sizeof(int));
GET(s, &subframe, sizeof(int));
GET(s, &e, sizeof(int));
GET(s, &t, sizeof(int));
//printf("t %d e %d\n", t, (int)(10*log10(e)));
if (pucch_plot) {
iq_plot_add_energy_point_loop(pucch_plot, t, 0);
iq_plot_add_energy_point_loop(pucch_plot, 10*log10(e), 1);
}
break;
}
case T_buf_test: {
unsigned char buf[T_BUFFER_MAX];
int size;
GET(s, &size, sizeof(int));
GET(s, buf, size);
printf("got buffer size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x"
" %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],
buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]);
break;
}
default: printf("unkown message type %d\n", m); abort();
}
#ifdef T_USE_SHARED_MEMORY
T_cache[T_busylist_head].busy = 0;
T_busylist_head++;
T_busylist_head &= T_CACHE_SIZE - 1;
#endif
}
#ifdef T_USE_SHARED_MEMORY
void wait_message(void)
{
while (T_cache[T_busylist_head].busy == 0) usleep(1000);
}
void init_shm(void)
{
int i;
int s = shm_open(T_SHM_FILENAME, O_RDWR | O_CREAT /*| O_SYNC*/, 0666);
if (s == -1) { perror(T_SHM_FILENAME); abort(); }
if (ftruncate(s, T_CACHE_SIZE * sizeof(T_cache_t)))
{ perror(T_SHM_FILENAME); abort(); }
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, s, 0);
if (T_cache == NULL)
{ perror(T_SHM_FILENAME); abort(); }
close(s);
/* let's garbage the memory to catch some potential problems
* (think multiprocessor sync issues, barriers, etc.)
*/
memset(T_cache, 0x55, T_CACHE_SIZE * sizeof(T_cache_t));
for (i = 0; i < T_CACHE_SIZE; i++) T_cache[i].busy = 0;
}
#endif /* T_USE_SHARED_MEMORY */
void new_thread(void *(*f)(void *), void *data)
{
pthread_t t;
pthread_attr_t att;
if (pthread_attr_init(&att))
{ fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
{ fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
if (pthread_attr_setstacksize(&att, 10000000))
{ fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); }
if (pthread_create(&t, &att, f, data))
{ fprintf(stderr, "pthread_create err\n"); exit(1); }
if (pthread_attr_destroy(&att))
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}
void usage(void)
{
printf(
"common options:\n"
" -d <database file> this option is mandatory\n"
" -li print IDs in the database\n"
" -lg print GROUPs in the database\n"
" -dump dump the database\n"
" -x run with XFORMS (revisited)\n"
" -on <GROUP or ID> turn log ON for given GROUP or ID\n"
" -off <GROUP or ID> turn log OFF for given GROUP or ID\n"
" -ON turn all logs ON\n"
" -OFF turn all logs OFF\n"
"note: you may pass several -on/-off/-ON/-OFF, they will be processed in order\n"
" by default, all is off\n"
"\n"
"remote mode options: in this mode you run a local tracer and a remote one\n"
" -r <port> remote side (use given port)\n"
" -l <IP address> <port> local side (forwards packets to remote IP:port)\n"
);
exit(1);
}
int main(int n, char **v)
{
char *database_filename = NULL;
void *database;
int s;
int l;
char t;
int i;
int do_list_ids = 0;
int do_list_groups = 0;
int do_dump_database = 0;
int do_xforms = 0;
char **on_off_name;
int *on_off_action;
int on_off_n = 0;
int is_on[T_NUMBER_OF_IDS];
int remote_local = 0;
int remote_remote = 0;
char *remote_ip = NULL;
int remote_port = -1;
int port = 2020;
#ifdef T_USE_SHARED_MEMORY
void *f;
#endif
memset(is_on, 0, sizeof(is_on));
on_off_name = malloc(n * sizeof(char *)); if (on_off_name == NULL) abort();
on_off_action = malloc(n * sizeof(int)); if (on_off_action == NULL) abort();
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-d"))
{ if (i > n-2) usage(); database_filename = v[++i]; continue; }
if (!strcmp(v[i], "-li")) { do_list_ids = 1; continue; }
if (!strcmp(v[i], "-lg")) { do_list_groups = 1; continue; }
if (!strcmp(v[i], "-dump")) { do_dump_database = 1; continue; }
if (!strcmp(v[i], "-x")) { do_xforms = 1; continue; }
if (!strcmp(v[i], "-on")) { if (i > n-2) usage();
on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=1; continue; }
if (!strcmp(v[i], "-off")) { if (i > n-2) usage();
on_off_name[on_off_n]=v[++i]; on_off_action[on_off_n++]=0; continue; }
if (!strcmp(v[i], "-ON"))
{ on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=1; continue; }
if (!strcmp(v[i], "-OFF"))
{ on_off_name[on_off_n]=NULL; on_off_action[on_off_n++]=0; continue; }
if (!strcmp(v[i], "-r")) { if (i > n-2) usage(); remote_remote = 1;
port = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-l")) { if (i > n-3) usage(); remote_local = 1;
remote_ip = v[++i]; remote_port = atoi(v[++i]); continue; }
printf("ERROR: unknown option %s\n", v[i]);
usage();
}
#ifndef T_USE_SHARED_MEMORY
/* gcc shut up */
(void)remote_port;
(void)remote_ip;
#endif
#ifdef T_USE_SHARED_MEMORY
if (remote_remote) {
printf("ERROR: remote 'remote side' does not run with shared memory\n");
printf("recompile without T_USE_SHARED_MEMORY (edit Makefile)\n");
exit(1);
}
#endif
if (remote_remote) {
/* TODO: setup 'secure' connection with remote part */
}
#ifndef T_USE_SHARED_MEMORY
if (remote_local) {
printf("ERROR: remote 'local side' does not run without shared memory\n");
printf("recompile with T_USE_SHARED_MEMORY (edit Makefile)\n");
exit(1);
}
#endif
#ifdef T_USE_SHARED_MEMORY
if (remote_local) f = forwarder(remote_ip, remote_port);
#endif
if (remote_local) goto no_database;
if (database_filename == NULL) {
printf("ERROR: provide a database file (-d)\n");
exit(1);
}
database = parse_database(database_filename);
if (do_list_ids + do_list_groups + do_dump_database > 1) usage();
if (do_list_ids) { list_ids(database); return 0; }
if (do_list_groups) { list_groups(database); return 0; }
if (do_dump_database) { dump_database(database); return 0; }
for (i = 0; i < on_off_n; i++)
on_off(database, on_off_name[i], is_on, on_off_action[i]);
no_database:
if (do_xforms) {
ul_plot = make_plot(512, 100, "UL Input Signal", 1,
7680*10, PLOT_VS_TIME, BLUE);
chest_plot = make_plot(512, 100, "UL Channel Estimate UE 0", 1,
512, PLOT_VS_TIME, BLUE);
pusch_iq_plot = make_plot(100, 100, "PUSCH IQ", 1,
12*25*14, PLOT_IQ_POINTS, BLUE);
pucch_iq_plot = make_plot(100, 100, "PUCCH IQ", 1,
1000, PLOT_IQ_POINTS, BLUE);
pucch_plot = make_plot(512, 100, "PUCCH 1 energy (SR)", 2,
/* threshold */
10240, PLOT_MINMAX, RED,
/* pucch 1 */
10240, PLOT_MINMAX, BLUE);
}
#ifdef T_USE_SHARED_MEMORY
init_shm();
#endif
s = get_connection("127.0.0.1", port);
if (remote_local) {
#ifdef T_USE_SHARED_MEMORY
forward_start_client(f, s);
#endif
goto no_init_message;
}
/* send the first message - activate all traces */
t = 0;
if (write(s, &t, 1) != 1) abort();
l = 0;
for (i = 0; i < T_NUMBER_OF_IDS; i++) if (is_on[i]) l++;
if (write(s, &l, sizeof(int)) != sizeof(int)) abort();
for (l = 0; l < T_NUMBER_OF_IDS; l++)
if (is_on[l])
if (write(s, &l, sizeof(int)) != sizeof(int)) abort();
no_init_message:
/* read messages */
while (1) {
#ifdef T_USE_SHARED_MEMORY
wait_message();
__sync_synchronize();
#endif
#ifdef T_USE_SHARED_MEMORY
if (remote_local) {
forward(f, T_cache[T_busylist_head].buffer,
T_cache[T_busylist_head].length);
T_cache[T_busylist_head].busy = 0;
T_busylist_head++;
T_busylist_head &= T_CACHE_SIZE - 1;
continue;
}
#endif
get_message(s);
}
return 0;
}
+291
View File
@@ -0,0 +1,291 @@
#include "defs.h"
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <sys/select.h>
#include <stdarg.h>
typedef struct {
float *buf;
short *iqbuf;
int count;
int type;
volatile int iq_count; /* for ULSCH IQ data */
int iq_insert_pos;
GC g;
} data;
typedef struct {
Display *d;
Window w;
Pixmap px;
GC bg;
int width;
int height;
pthread_mutex_t lock;
float zoom;
int timer_pipe[2];
data *p; /* list of plots */
int nplots;
} plot;
static void *timer_thread(void *_p)
{
plot *p = _p;
char c;
while (1) {
/* more or less 10Hz */
usleep(100*1000);
c = 1;
if (write(p->timer_pipe[1], &c, 1) != 1) abort();
}
return NULL;
}
static void *plot_thread(void *_p)
{
float v;
float *s;
int i, j;
plot *p = _p;
int redraw = 0;
int replot = 0;
fd_set rset;
int xfd = ConnectionNumber(p->d);
int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0];
int pp;
while (1) {
while (XPending(p->d)) {
XEvent e;
XNextEvent(p->d, &e);
switch (e.type) {
case ButtonPress:
/* button 4: zoom out */
if (e.xbutton.button == 4) { p->zoom = p->zoom * 1.25; replot = 1; }
/* button 5: zoom in */
if (e.xbutton.button == 5) { p->zoom = p->zoom * 0.8; replot = 1; }
printf("zoom: %f\n", p->zoom);
break;
case Expose: redraw = 1; break;
}
}
if (replot == 1) {
replot = 0;
redraw = 1;
if (pthread_mutex_lock(&p->lock)) abort();
XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height);
for (pp = 0; pp < p->nplots; pp++) {
if (p->p[pp].type == PLOT_MINMAX) {
s = p->p[pp].buf;
for (i = 0; i < 512; i++) {
int min = *s;
int max = *s;
for (j = 0; j < p->p[pp].count/512; j++, s++) {
if (*s < min) min = *s;
if (*s > max) max = *s;
}
XDrawLine(p->d, p->px, p->p[pp].g, i, 100-min, i, 100-max);
}
} else if (p->p[pp].type == PLOT_VS_TIME) {
for (i = 0; i < p->p[pp].count; i++)
p->p[pp].buf[i] =
10*log10(1.0+(float)(p->p[pp].iqbuf[2*i]*p->p[pp].iqbuf[2*i]+
p->p[pp].iqbuf[2*i+1]*p->p[pp].iqbuf[2*i+1]));
s = p->p[pp].buf;
for (i = 0; i < 512; i++) {
v = 0;
for (j = 0; j < p->p[pp].count/512; j++, s++) v += *s;
v /= p->p[pp].count/512;
XDrawLine(p->d, p->px, p->p[pp].g, i, 100, i, 100-v);
}
} else if (p->p[pp].type == PLOT_IQ_POINTS) {
XPoint pts[p->p[pp].iq_count];
int count = p->p[pp].iq_count;
for (i = 0; i < count; i++) {
pts[i].x = p->p[pp].iqbuf[2*i]*p->zoom/20+50;
pts[i].y = -p->p[pp].iqbuf[2*i+1]*p->zoom/20+50;
}
XDrawPoints(p->d, p->px, p->p[pp].g, pts, count, CoordModeOrigin);
}
}
if (pthread_mutex_unlock(&p->lock)) abort();
}
if (redraw) {
redraw = 0;
XCopyArea(p->d, p->px, p->w, DefaultGC(p->d, DefaultScreen(p->d)),
0, 0, p->width, p->height, 0, 0);
}
XFlush(p->d);
FD_ZERO(&rset);
FD_SET(p->timer_pipe[0], &rset);
FD_SET(xfd, &rset);
if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort();
if (FD_ISSET(p->timer_pipe[0], &rset)) {
char b[512];
if (read(p->timer_pipe[0], b, 512) <= 0) abort();
replot = 1;
}
}
return NULL;
}
void *make_plot(int width, int height, char *title, int nplots, ...)
{
plot *p;
Display *d;
Window w;
Pixmap pm;
int i;
va_list ap;
XGCValues gcv;
p = malloc(sizeof(*p)); if (p == NULL) abort();
d = XOpenDisplay(0); if (d == NULL) abort();
w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height,
0, WhitePixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d)));
XSelectInput(d, w, ExposureMask | ButtonPressMask);
XMapWindow(d, w);
{
XSetWindowAttributes att;
att.backing_store = Always;
XChangeWindowAttributes(d, w, CWBackingStore, &att);
}
XStoreName(d, w, title);
p->bg = XCreateGC(d, w, 0, NULL);
XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->bg);
gcv.foreground = WhitePixel(d, DefaultScreen(d));
XChangeGC(d, p->bg, GCForeground, &gcv);
pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d)));
p->width = width;
p->height = height;
p->p = malloc(nplots * sizeof(data)); if (p->p == NULL) abort();
va_start(ap, nplots);
for (i = 0; i < nplots; i++) {
int count;
int type;
char *color;
XColor rcol, scol;
count = va_arg(ap, int);
type = va_arg(ap, int);
color = va_arg(ap, char *);
p->p[i].g = XCreateGC(d, w, 0, NULL);
XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->p[i].g);
if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)),
color, &scol, &rcol)) {
gcv.foreground = scol.pixel;
XChangeGC(d, p->p[i].g, GCForeground, &gcv);
} else {
printf("could not allocate color '%s'\n", color);
abort();
}
if (type == PLOT_VS_TIME) {
p->p[i].buf = malloc(sizeof(float) * count);
if (p->p[i].buf == NULL) abort();
p->p[i].iqbuf = malloc(sizeof(short) * count * 2);
if(p->p[i].iqbuf==NULL)abort();
} else if (type == PLOT_MINMAX) {
p->p[i].buf = malloc(sizeof(float) * count);
if (p->p[i].buf == NULL) abort();
p->p[i].iqbuf = NULL;
} else {
p->p[i].buf = NULL;
p->p[i].iqbuf = malloc(sizeof(short) * count * 2);
if(p->p[i].iqbuf==NULL)abort();
}
p->p[i].count = count;
p->p[i].type = type;
p->p[i].iq_count = 0;
p->p[i].iq_insert_pos = 0;
}
va_end(ap);
p->d = d;
p->w = w;
p->px = pm;
p->zoom = 1;
p->nplots = nplots;
pthread_mutex_init(&p->lock, NULL);
if (pipe(p->timer_pipe)) abort();
new_thread(plot_thread, p);
new_thread(timer_thread, p);
return p;
}
void plot_set(void *_plot, float *data, int len, int pos, int pp)
{
plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->p[pp].buf + pos, data, len * sizeof(float));
if (pthread_mutex_unlock(&p->lock)) abort();
}
void iq_plot_set(void *_plot, short *data, int count, int pos, int pp)
{
plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->p[pp].iqbuf + pos * 2, data, count * 2 * sizeof(short));
if (pthread_mutex_unlock(&p->lock)) abort();
}
void iq_plot_set_sized(void *_plot, short *data, int count, int pp)
{
plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->p[pp].iqbuf, data, count * 2 * sizeof(short));
p->p[pp].iq_count = count;
if (pthread_mutex_unlock(&p->lock)) abort();
}
void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp)
{
plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort();
p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2] = i;
p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2+1] = q;
if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++;
p->p[pp].iq_insert_pos++;
if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0;
if (pthread_mutex_unlock(&p->lock)) abort();
}
void iq_plot_add_energy_point_loop(void *_plot, int e, int pp)
{
plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort();
p->p[pp].buf[p->p[pp].iq_insert_pos] = e;
if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++;
p->p[pp].iq_insert_pos++;
if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0;
if (pthread_mutex_unlock(&p->lock)) abort();
}