aboutsummaryrefslogtreecommitdiffstats
path: root/thirdparty/apps/testapp/lb/lb.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/apps/testapp/lb/lb.h')
-rw-r--r--thirdparty/apps/testapp/lb/lb.h731
1 files changed, 731 insertions, 0 deletions
diff --git a/thirdparty/apps/testapp/lb/lb.h b/thirdparty/apps/testapp/lb/lb.h
new file mode 100644
index 0000000..b7e4ddb
--- /dev/null
+++ b/thirdparty/apps/testapp/lb/lb.h
@@ -0,0 +1,731 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _LB_H_
+#define _LB_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/eventfd.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <pthread.h>
+#include <sched.h>
+#include <getopt.h>
+#include <execinfo.h>
+#include <linux/futex.h>
+
+#define KB 1000
+#define MB (1000 * KB)
+#define GB (1000 * MB)
+#define TB (1000 * GB)
+
+#define MSOFS (1000)
+#define USOFS (1000 * 1000)
+#define NSOFS (1000 * 1000 * 1000)
+#define NSOFMS (1000 * 1000)
+
+#define NOINLINE __attribute__((noinline))
+#define no_inline __attribute__((noinline))
+
+#ifndef SO_REUSEPORT
+#define SO_REUSEPORT 15
+#endif
+
+#include "api.h"
+
+#define out(fmt, arg...) (void)printf(fmt, ##arg)
+
+#define info(fmt, arg...) (void)printf("%s[I:%d]%s " fmt, CR, __LINE__, CC, ##arg)
+#define wrn(fmt, arg...) (void)printf("%s[W:%d]%s " fmt, FR__, __LINE__, CC, ##arg)
+#define err(fmt, arg...) (void)fprintf(stderr, "%s[E:%d]%s " fmt, BR__, __LINE__, CC, ##arg)
+
+#define WRN(cond, fmt, arg...) do { if (cond) wrn(fmt, ##arg); } while (0)
+
+#define ERR_RETURN(cond, ret, fmt, arg...) do { \
+ if (cond) { \
+ if (fmt) err(fmt, ##arg); \
+ return ret; \
+ } \
+} while(0)
+
+#define ERR_GOTO(cond, TO, fmt, arg...) do { \
+ if (cond) { \
+ if (fmt) err(fmt, ##arg); \
+ goto TO; \
+ } \
+} while (0)
+
+#define DBGOPT "D"
+#define DBGOPT_LONG {"debug", 0, 0, 'D'},
+
+extern int enable_debug;
+
+#define DBG(fmt, arg...) do { \
+ if (enable_debug) \
+ out("[D:%d]%s " fmt, __LINE__, __func__, ##arg); \
+} while (0)
+
+#define T DBG("\n");
+
+#define CNT_OF(a) (sizeof(a) / sizeof(a[0]))
+
+#define OFF_OF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#define CON_OF(ptr, type, member) ({ \
+ const typeof( ((type*)0)->member ) *__mptr = (ptr); \
+ (type*)( (char*)__mptr - OFF_OF(type, member) ); \
+})
+#define NUM_OF(a) (sizeof((a)) / sizeof((a)[0]))
+
+#if 1
+#define TIMEPOINT
+
+#define TP(name) struct timespec _tp_##name; \
+ (void)clock_gettime(CLOCK_MONOTONIC, &_tp_##name)
+#define TO(from, to) do { \
+ struct timespec _t; \
+ LB_SUB_TS(_tp_##to, _tp_##from, _t); \
+ out("@TP>%s:%d:%s %lu.%09lu %s-%s\n", __FILE__, __LINE__, __func__, \
+ _t.tv_sec, _t.tv_nsec, #from, #to); \
+} while (0)
+#define TN(from, to, NUM) do { \
+ static uint64_t _n = 0; \
+ static struct timespec _t = {0}; \
+ _t.tv_nsec += (_tp_##to.tv_nsec - _tp_##from.tv_nsec); \
+ _t.tv_sec += (_tp_##to.tv_sec - _tp_##from.tv_sec); \
+ if (++_n >= NUM) { \
+ uint64_t _nsec = _t.tv_sec * 1000000000ul + _t.tv_nsec; \
+ _nsec /= _n; \
+ out("@TP<%lu>%s:%d:%s %lu.%09lu %s-%s\n", _n, __FILE__, __LINE__, __func__, \
+ _nsec/1000000000ul, _nsec%1000000000ul, #from, #to); \
+ _t.tv_sec = 0; \
+ _t.tv_nsec = 0; \
+ _n = 0; \
+ } \
+} while (0)
+#else
+
+#define TP(name) ((void)0)
+#define TO(from, to) ((void)0)
+#define TN(from, to, NUM) ((void)0)
+
+#endif
+
+#define TQ(name) do { TP(__); TO(name, __); } while (0)
+#define TM(name, NUM) do { TP(__); TN(name, __, NUM); } while (0)
+
+#define TO1(n1,n2) TO(n1,n2)
+#define TO2(n1,n2,n3) do { TO(n1,n2); TO1(n2,n3); } while(0)
+#define TO3(n1,n2,n3...) do { TO(n1,n2); TO2(n2,n3); } while(0)
+#define TO4(n1,n2,n3...) do { TO(n1,n2); TO3(n2,n3); } while(0)
+#define TO5(n1,n2,n3...) do { TO(n1,n2); TO4(n2,n3); } while(0)
+#define TO6(n1,n2,n3...) do { TO(n1,n2); TO5(n2,n3); } while(0)
+
+#define TE(N,n...) do { TP(__); TO##N(n, __);} while (0)
+
+#define tp1 TP(1)
+#define tq1 TQ(1)
+#define tp2 TP(2)
+#define tq2 TQ(2)
+#define tp3 TP(3)
+#define tq3 TQ(3)
+#define tp4 TP(4)
+#define tq4 TQ(4)
+#define tp5 TP(5)
+#define tq5 TQ(5)
+
+#ifndef COLOR_LB_H_
+#define COLOR_LB_H_
+
+struct lb_color
+{
+ const char *clear;
+ const char *high;
+ const char *uline;
+ const char *flash;
+ const char *rev;
+
+ const char *fblack;
+ const char *fr__;
+ const char *f_g_;
+ const char *f__b;
+ const char *frg_;
+ const char *fr_b;
+ const char *f_gb;
+ const char *fwhite;
+
+ const char *bblack;
+ const char *br__;
+ const char *b_g_;
+ const char *b__b;
+ const char *brg_;
+ const char *br_b;
+ const char *b_gb;
+ const char *bwhite;
+};
+
+enum
+{
+ LB_DEF_COLOR = 0,
+ LB_NO_COLOR = 1,
+};
+
+extern const struct lb_color *lb_color;
+extern int lb_color_index;
+void lb_set_color (int index);
+
+#define CC lb_color->clear
+#define CR lb_color->rev
+#define CH lb_color->high
+#define CU lb_color->uline
+#define CF lb_color->flash
+
+#define FBLACK lb_color->fblack
+#define FR__ lb_color->fr__
+#define F_G_ lb_color->f_g_
+#define F__B lb_color->f__b
+#define FRG_ lb_color->frg_
+#define FR_B lb_color->fr_b
+#define F_GB lb_color->f_gb
+#define FWHITE lb_color->fwhite
+
+#define BBLACK lb_color->bblack
+#define BR__ lb_color->br__
+#define B_G_ lb_color->b_g_
+#define B__B lb_color->b__b
+#define BRG_ lb_color->brg_
+#define BR_B lb_color->br_b
+#define B_GB lb_color->b_gb
+#define BWHITE lb_color->bwhite
+
+#endif
+
+#ifndef TIME_LB_H_
+#define TIME_LB_H_
+
+#define LB_RAND(num) ((int) ((random() / (RAND_MAX + 1.0)) * num))
+
+#define LB_TIME(now) (void)clock_gettime(CLOCK_MONOTONIC, &(now))
+#define LB_REALTIME(now) (void)clock_gettime(CLOCK_REALTIME, &(now))
+
+#define LB_SUB_OS(end, begin) ((end).tv_sec - (begin).tv_sec)
+#define LB_SUB_NS(end, begin) (((end).tv_sec - (begin).tv_sec) * NSOFS + (end).tv_nsec - (begin).tv_nsec)
+
+#define LB_SUB_TS(end, begin, out) ({ \
+ if ((end).tv_nsec >= (begin).tv_nsec) { \
+ (out).tv_nsec = (end).tv_nsec - (begin).tv_nsec; \
+ (out).tv_sec = (end).tv_sec - (begin).tv_sec; \
+ } else { \
+ (out).tv_nsec = (end).tv_nsec + NSOFS - (begin).tv_nsec; \
+ (out).tv_sec = (end).tv_sec - (begin).tv_sec - 1; \
+ } \
+})
+
+#define LB_CMP(end, begin) ((end).tv_sec > (begin).tv_sec ? 1 : ( \
+ (end).tv_sec < (begin).tv_sec ? -1 : (end).tv_nsec - (begin).tv_nsec))
+
+#define LB_CMP_SN(end, begin, sec, nsec) ({ \
+ time_t _s = (end).tv_sec - (begin).tv_sec; \
+ (_s > (sec)) || (_s == (sec) && (end).tv_nsec - (begin).tv_nsec >= (nsec)); \
+})
+
+#define LB_CMP_TS(end, begin, ts) LB_CMP_SN((end), (begin), (ts).tv_sec, (ts).tv_nsec)
+#define LB_CMP_S(end, begin, sec) LB_CMP_SN((end), (begin), (sec), 0)
+#define LB_CMP_NS(end, begin, nsec) LB_CMP_SN((end), (begin), 0, (nsec))
+
+#endif /* #ifndef TIME_LB_H_ */
+
+#ifndef MATH_LB_H_
+#define MATH_LB_H_
+
+/* return a * 10^9 / b */
+inline static uint64_t
+lb_gdiv (uint64_t a, uint64_t b)
+{
+ const uint64_t M = 0xFFFFffffFFFFfffful;
+ const uint64_t N = 1000 * 1000 * 1000;
+ const uint64_t P = 1000;
+
+ uint64_t r;
+
+ if (b == 0)
+ b = 1;
+
+ if (a <= M / N)
+ return a * N / b;
+
+ r = a / b;
+
+ a = a % b * P;
+ r = r * P + a / b;
+
+ a = a % b * P;
+ r = r * P + a / b;
+
+ a = a % b * P;
+ r = r * P + a / b;
+
+ return r;
+}
+
+inline static uint64_t
+lb_sdiv (uint64_t a, uint64_t b)
+{
+ if (b)
+ return a / b;
+ return 0;
+}
+
+#endif /* #ifndef MATH_LB_H_ */
+#ifndef RUN_LB_H_
+#define RUN_LB_H_
+
+struct lb_slot
+{
+ struct timespec begin;
+ uint64_t count;
+};
+
+struct lb_run
+{
+ uint32_t index;
+ uint32_t mask;
+ uint32_t rate;
+ uint32_t time;
+ uint64_t total;
+ struct lb_slot slot[0];
+};
+
+/* num:1 << N; time: ns */
+inline static void
+run_init (struct lb_run *run, uint32_t rate, uint32_t num, uint32_t time)
+{
+ int i;
+ struct lb_slot *slot = run->slot;
+ struct timespec begin;
+
+ LB_TIME (begin);
+
+ run->index = 0;
+ run->mask = num - 1;
+ run->rate = rate;
+ run->time = time;
+ run->total = 0;
+
+ for (i = 0; i < num; ++i, ++slot)
+ {
+ slot->begin = begin;
+ slot->count = 0;
+ }
+}
+
+/* return: the number should add for run to now */
+inline static int64_t
+run_test (struct lb_run *run, struct timespec *now)
+{
+ uint64_t time, num;
+ struct lb_slot *slot = run->slot;
+ struct lb_slot *cur = slot + (run->index & run->mask);
+
+ if (LB_CMP_NS (*now, cur->begin, run->time))
+ {
+ cur = slot + ((++run->index) & run->mask);
+ run->total -= cur->count;
+ cur->count = 0;
+ cur->begin = *now;
+ }
+
+ slot += ((run->index + 1) & run->mask);
+ time = LB_SUB_NS (*now, slot->begin);
+ num = time * run->rate;
+
+ if ((num % NSOFS) >= (NSOFS / 2))
+ return num / NSOFS - run->total + 1;
+ return num / NSOFS - run->total;
+}
+
+inline static int
+run_add (struct lb_run *run, int64_t num)
+{
+ run->total += num;
+ run->slot[run->index & run->mask].count += num;
+}
+
+#endif
+
+#ifndef FORMAT_LB_H_
+#define FORMAT_LB_H_
+
+const char *f_in6 (const struct in6_addr *ip6);
+const char *f_in6addr (const struct sockaddr_in6 *addr);
+const char *f_inaddr (const struct sockaddr_in *addr);
+const char *f_uint (uint64_t val);
+int s_uint (char *buf, uint64_t val);
+int r_uint (char *buf, uint64_t val, int size);
+
+#endif
+
+#ifndef PARSE_LB_H_
+#define PARSE_LB_H_
+
+uint64_t p_hex (const char *arg, const char **end);
+uint64_t p_uint (const char *arg, uint64_t max, const char **end);
+inline static long
+p_int (const char *arg, long max, const char **end)
+{
+ return (long) (unsigned long) p_uint (arg, (uint64_t) (unsigned long) max,
+ end);
+}
+
+struct inaddrs
+{
+ uint32_t ip;
+#if 0
+ uint32_t ip_num;
+ uint32_t ip_step;
+#else
+ int ip_num;
+#endif
+ uint16_t port;
+ uint16_t port_num;
+};
+
+uint32_t p_ip (const char **arg);
+int p_addr (const char *str, struct sockaddr_in *addr);
+const char *p_addr_set (const char *arg, struct inaddrs *addr, uint32_t flag);
+int p_addr_list (const char *arg, struct inaddrs *list, int num,
+ uint32_t flag, const char **end);
+int addr_total (const struct inaddrs *list, int num, uint32_t mode);
+int addr_layout (const struct inaddrs *list, int list_num,
+ struct sockaddr_in *addr, int addr_num, uint32_t mode);
+inline static int
+p_addrin_list (const char *arg, struct sockaddr_in **addr, int max,
+ uint32_t flag, const char **end)
+{
+ int num, total;
+ struct inaddrs list[max];
+ struct sockaddr_in *out;
+
+ num = p_addr_list (arg, list, max, flag, end);
+ if (num <= 0)
+ return -1;
+
+ total = addr_total (list, num, flag);
+ if (total > max)
+ return -1;
+
+ out = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in) * total);
+ if (!out)
+ return -1;
+
+ num = addr_layout (list, num, out, total, flag);
+
+ if (num != total)
+ {
+ free (out);
+ return -1;
+ }
+
+ *addr = out;
+ return num;
+}
+
+#define PA_DEFPORT_MASK 0x0000FFFF
+
+#define PA_NO_TO_IP 0x00010000
+#define PA_NO_NUM_IP 0x00020000
+#define PA_MAY_INV_IP 0x00040000
+#define PA_MULTI_ONE 0x00080000
+
+#define PA_NO_TO_PORT 0x00100000
+#define PA_NO_NUM_PORT 0x00200000
+#define PA_NO_PORT 0x00400000
+#define PA_MUST_PORT 0x00800000
+#define PA_DEF_PORT 0x00C00000
+
+#define PA_NO_TO_ALL (PA_NO_TO_IP | PA_NO_TO_PORT)
+#define PA_NO_NUM_ALL (PA_NO_NUM_IP | PA_NO_NUM_PORT)
+#define PA_SINGLE_IP (PA_NO_TO_IP | PA_NO_NUM_IP)
+#define PA_SINGLE_PORT (PA_NO_TO_PORT | PA_NO_NUM_PORT)
+
+#define PAL_NO_SPACE 0x10000000
+#define PAL_WITH_NL 0x20000000
+//#define PAL_SC_SPLIT 0x40000000
+
+#define PAL_CROSS_MASK 0x03000000
+#define PAL_IP_X_PORT 0x00000000
+#define PAL_INC_BOTH 0x01000000
+#define PAL_PORT_X_IP 0x02000000
+
+const char *p_ip6 (const char *pos, struct in6_addr *ip);
+inline static int
+inet6_aton (const char *cp, struct in6_addr *addr)
+{
+ cp = p_ip6 (cp, addr);
+ if (!cp || cp[0] != 0)
+ return 0;
+ return 1;
+}
+
+int p_addr6 (const char *arg, struct sockaddr_in6 *addr);
+
+#endif
+
+#ifndef UNIT_LB_H_
+#define UNIT_LB_H_
+
+enum unit_type
+{
+ UNIT_1,
+
+ UNIT_k,
+ UNIT_m,
+ UNIT_g,
+ UNIT_w,
+
+ UNIT_K,
+ UNIT_M,
+ UNIT_G,
+
+ UNIT_hour,
+ UNIT_min,
+ UNIT_sec,
+
+ UNIT_1n,
+ UNIT_hn,
+ UNIT_mn,
+ UNIT_sn,
+ UNIT_ms,
+ UNIT_us,
+ UNIT_ns,
+
+ UNIT_PC,
+
+ UNIT_NUM,
+
+ UB_1 = 1 << UNIT_1,
+
+ UB_k = 1 << UNIT_k,
+ UB_m = 1 << UNIT_m,
+ UB_g = 1 << UNIT_g,
+ UB_w = 1 << UNIT_w,
+
+ UB_K = 1 << UNIT_K,
+ UB_M = 1 << UNIT_M,
+ UB_G = 1 << UNIT_G,
+
+ UB_hour = 1 << UNIT_hour,
+ UB_min = 1 << UNIT_min,
+ UB_sec = 1 << UNIT_sec,
+
+ UB_hn = 1 << UNIT_hn,
+ UB_mn = 1 << UNIT_mn,
+ UB_sn = 1 << UNIT_sn,
+ UB_1n = 1 << UNIT_1n,
+ UB_ms = 1 << UNIT_ms,
+ UB_us = 1 << UNIT_us,
+ UB_ns = 1 << UNIT_ns,
+
+ UB_PC = 1 << UNIT_PC,
+
+ UB_T1U_MASK = 3 << UNIT_NUM,
+ UB_T1U_ns = 0 << UNIT_NUM,
+ UB_T1U_us = 1 << UNIT_NUM,
+ UB_T1U_ms = 2 << UNIT_NUM,
+ UB_T1U_s = 3 << UNIT_NUM,
+
+ UB_kmgw = UB_k | UB_m | UB_g | UB_w,
+ UB_KMG = UB_K | UB_M | UB_G,
+ UB_1kmgwKMG = UB_1 | UB_kmgw | UB_KMG,
+
+ UB_smun = UB_sn | UB_ms | UB_us | UB_ns,
+ UB_hms1 = UB_hour | UB_min | UB_sec | UB_1,
+
+};
+
+int p_unit (const char **arg, int mask, uint64_t * unit);
+
+inline static uint64_t
+p_value (const char *arg, uint64_t max, int mask, const char **end)
+{
+ uint64_t val = p_uint (arg, max, &arg);
+
+ if (arg)
+ {
+ uint64_t unit;
+ if (p_unit (&arg, mask, &unit) >= 0)
+ {
+ val *= unit;
+ if (val <= max)
+ {
+ if (end)
+ *end = arg;
+ return val;
+ }
+ }
+ }
+
+ if (end)
+ *end = NULL;
+ return 0;
+}
+
+#endif
+
+#ifndef CACHED_OUTPUT_LB_H_
+#define CACHED_OUTPUT_LB_H_
+
+typedef uint16_t cosize_t;
+
+struct cohead
+{
+ cosize_t size;
+ cosize_t free;
+};
+
+#define CO_OUT(head) stdout
+#define CO_INIT(buf) co_init(buf, sizeof(buf))
+
+inline static void
+co_init (char buf[], cosize_t size)
+{
+ struct cohead *head = (struct cohead *) buf;
+ head->size = size - sizeof (struct cohead);
+ head->free = head->size;
+ buf[sizeof (struct cohead)] = 0;
+}
+
+inline static void
+_co_flush (struct cohead *head)
+{
+ char *buf = (char *) (head + 1);
+ (void) fputs (buf, CO_OUT (head));
+ head->free = head->size;
+ *buf = 0;
+}
+
+inline static void
+co_flush (char buf[])
+{
+ struct cohead *head = (struct cohead *) buf;
+ if (head->free != head->size)
+ _co_flush (head);
+}
+
+int co_wr_uint (char buf[], uint64_t val, int wide);
+
+int co_app_ch (char buf[], char ch);
+#define co_ch_if(cond, buf, ch) ( \
+ (!!(cond)) ? co_app_ch((buf), (ch)) : 0)
+
+int co_append (char buf[], cosize_t max, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+#define co_app_if(cond, buf, max, fmt, arg...) ( \
+ (!!(cond)) ? co_append((buf), (max), (fmt), ##arg) : 0)
+#define co_app_fls(buf, max, fmt, arg...) do { \
+ co_append(buf, max, fmt, ##arg); \
+ co_flush(); \
+} while (0)
+
+#endif
+
+#ifndef SYSTEM_LB_H_
+#define SYSTEM_LB_H_
+
+inline static void
+futex_wait (volatile int *addr, int val)
+{
+ while (*addr == val)
+ {
+ (void) syscall (SYS_futex, addr, FUTEX_WAIT, val, NULL, NULL, 0);
+ }
+}
+
+inline static void
+futex_wake (volatile int *addr, int num)
+{
+ (void) syscall (SYS_futex, addr, FUTEX_WAKE, num, NULL, NULL, 0);
+}
+
+pthread_t lb_thread (void *(*proc) (void *), void *arg, const char *fmt, ...);
+
+inline static int
+lb_setcpu (pthread_t thread, int cpu)
+{
+ cpu_set_t set;
+ CPU_ZERO (&set);
+ CPU_SET (cpu, &set);
+ return pthread_setaffinity_np (thread, sizeof (set), &set);
+}
+
+inline static int
+lb_sleep (time_t sec, long nsec)
+{
+const struct timespec timeout = { tv_sec: sec, tv_nsec:nsec };
+ return nanosleep (&timeout, NULL);
+}
+
+void lb_sigsegv_setup ();
+
+#endif /* #ifndef SYSTEM_LB_H_ */
+
+#define FD_CLOSE(fd) do { \
+ if(fd >= 0) { \
+ _close(fd); \
+ fd = -1; \
+ } \
+} while(0)
+
+#define BUF_FREE(p) do { \
+ if (p) { \
+ free(p); \
+ p = NULL; \
+ } \
+} while (0)
+
+#endif
+
+#ifdef KERNEL_SYSCALL_API
+#define KERNEL_SYSCALL_API
+
+#define KAPI(name) extern (typeof name) *k_##name;
+#include "kapi.h"
+#undef API
+
+#endif