Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
openairinterface5G
Commits
1e20abdd
Commit
1e20abdd
authored
Mar 14, 2016
by
Cédric Roux
Browse files
Initial commit of the T!
parents
Changes
10
Hide whitespace changes
Inline
Side-by-side
Makefile
0 → 100644
View file @
1e20abdd
CC
=
gcc
CFLAGS
=
-Wall
-g
-pthread
#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
clean
:
rm
-f
*
.o
$(PROG)
$(GENIDS)
core T_IDs.h
T.c
0 → 100644
View file @
1e20abdd
#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
);
while
(
T_cache
[
T_busylist_head
].
busy
)
{
char
*
b
=
T_cache
[
T_busylist_head
].
buffer
;
int
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
,
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
);
}
T.h
0 → 100644
View file @
1e20abdd
#ifndef _T_T_T_
#define _T_T_T_
#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_var = (val); \
T_CHECK_SIZE(T_PUT_var.length, argnum); \
memcpy(T_LOCAL_buf + T_LOCAL_size, T_PUT_var.addr, T_PUT_var.length); \
T_LOCAL_size += T_PUT_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]
#define T_SEND() \
T_cache[T_LOCAL_slot].busy = 1; \
T_cache[T_LOCAL_slot].length = T_LOCAL_size; \
T_send(T_LOCAL_buf, T_LOCAL_size)
#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) \
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 T13(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 T15(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 T17(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 T19(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 T21(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 T23(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 T25(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 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) \
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 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) \
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 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) \
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 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) \
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 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
;