diff options
Diffstat (limited to 'thirdparty/apps/testapp/lb/lb.h')
-rw-r--r-- | thirdparty/apps/testapp/lb/lb.h | 731 |
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 |