aboutsummaryrefslogtreecommitdiffstats
path: root/thirdparty/apps/testapp/cps/cps.h
blob: 9b949f3f9dc37f5bf2fad6a5f2b1504ed72a862d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
*
* 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 _CPS_H_
#define _CPS_H_

#define CPS_FRAG_NUM 64
#define CPS_FRAG_NS (20 * 1000 * 1000)  /* 20 ms */
#define CPS_FRAG_LOOP (CPS_FRAG_NS * CPS_FRAG_NUM)      /* 1.28 s */

#define CPS_TIMER_MS 100
#define CPS_DELAY_MS 5

#define CPS_MAX_FD (16 * 1024 * 1024)   /* 10M */
#define CPS_CONN_MAX (256 * 1024)

#define CPS_EPSIZE (1 * 1000)   /* =1k */
#define CPS_EPWAIT_MS 200       /* ms */

#define CPS_THREAD_MAX 128
#define CPS_SERVER_MAX 32
#define CPS_CLIENT_MAX 256
#define CPS_CLIENT_IAS_MAX 32

#define CPS_PORT_DEF 58166
#define CPS_EVNUM_DEF 256
#define CPS_EVNUM_MAX 1024
#define CPS_TIME_DEF 300
#define CPS_TIME_MAX (60 * 60 * 24 * 7) /* 604800s = 1 week */
#define CPS_RATE_DEF 10000      /* 1w */
#define CPS_RATE_MAX (100 * 1000 * 1000)        /* 100m */
#define CPS_REQ_DEF 1
#define CPS_RES_DEF 1
#define CPS_DATA_MAX 4096
#define CPS_INTERVAL_DEF 10     /* s */
#define CPS_INTERVAL_MAX 3600   /* s */

#define CPS_ERR_NUM 256

#define CPS_CONN_SID (-1)
#define CPS_EV_DATA(sid, fd) (((uint64_t)(uint32_t)(sid) << 32) | (uint64_t)(uint32_t)(fd))
#define CPS_EV_FD(u64) ((int)(uint32_t)(u64))
#define CPS_EV_SID(u64) ((int)(uint32_t)((u64) >> 32))

enum
{
  CPS_LOOP_BOTH = 0,
  CPS_LOOP_CF,
  CPS_LOOP_SF,
};

enum
{
  CPS_ERROR = -2,
  CPS_EXIT = -1,

  CPS_INIT = 0,

  CPS_RUNNING = 1,
  CPS_CLOSING = 2,
};

enum
{
  CPS_CNT_CONN_MAX,
  CPS_CNT_CONN_NUM,

  CPS_CNT_GTFD,
  CPS_CNT_SOCKET_ERR,
  CPS_CNT_BIND_ERR,
  CPS_CNT_ACCEPT_ERR,
  CPS_CNT_CONNECT_ERR,
  CPS_CNT_REUSEADDR_ERR,
  CPS_CNT_NODELAY_ERR,
  CPS_CNT_NONBLOCK_ERR,
  CPS_CNT_SEND_ERR,
  CPS_CNT_RECV_ERR,
  CPS_CNT_EPOLL_ERR,
  CPS_CNT_ERR_EVENT,
  CPS_CNT_FD_ERR,

  CPS_CNT_NUM
};

#define CPS_CNT_ITEM(thread, id) (cps.curr[(thread)->index].cnt[(id)])

#define CPS_CNT_INC(thread, id) (++CPS_CNT_ITEM((thread), (id)))
#define CPS_CNT_INC_E(thread, id, e) do { \
	struct cps_stat *_stat = cps.curr + (thread)->index; \
	++_stat->cnt[(id)]; \
	if ((e) >= CPS_ERR_NUM) ++_stat->err[0];\
	else ++_stat->err[(e)]; \
} while(0)

enum
{
  CPS_REC_INIT,

  CPS_REC_CONN,
  CPS_REC_CONN_TIME,

  CPS_REC_RECV,
  CPS_REC_RECV_TIME,

  CPS_REC_SEND,
  CPS_REC_SEND_TIME,

  CPS_REC_FAIL,

  CPS_REC_NUM
};

#define CPS_REC_INC(thread, id) (++cps.curr[(thread)->index].rec[(id)])

#define CPS_REC_TIMED_INC(thread, id, last) do { \
	struct timespec _time; \
	struct cps_stat *_stat = cps.curr + (thread)->index; \
	LB_TIME(_time); \
	_stat->rec[(id)]++; \
	_stat->rec[(id) + 1] += LB_SUB_NS(_time, (last)); \
	(last) = _time; \
} while (0)

struct cps_conn
{
  union
  {
    int size;
    int sid;
  };
  int next;
  int *prev;
  struct timespec last;

  struct timespec create_time;
};

struct cps_stat
{
  uint64_t cnt[CPS_CNT_NUM];
  uint64_t rec[CPS_REC_NUM];
  uint64_t err[CPS_ERR_NUM];
};

struct cps_thread
{
  int epfd;
  int index;
  int core;
  int loop;

  int server;
  int conn;
  int conn_num;

  int server_num;
  int client_num;
  int c_addr_num;

  uint64_t rate;
  pthread_t tid;

  struct sockaddr_in s_addr[CPS_SERVER_MAX];
  struct inaddrs c_addr[CPS_CLIENT_MAX];
  struct epoll_event event[CPS_EVNUM_MAX];
};

struct cps_var
{
  int run_state;
  int CPU_NUM;

  int verbose;
  int more;
  int client;
  int evnum;

  int req_len;
  int res_len;

  int test_time;
  int interval;

  int active_thread;
  int thread_num;
  int server_num;
  int client_num;

  uint64_t rate;

  struct cps_stat *curr;
  struct cps_stat *next;

  struct cps_conn *conn;
  struct cps_thread *thread[CPS_THREAD_MAX];

  struct cps_stat records[2][CPS_THREAD_MAX];
};

extern struct cps_var cps;

inline static struct cps_conn *
CPS_CONN (int fd)
{
  return cps.conn + fd;
}

inline static void
cps_add_server (struct cps_thread *thread, int fd, int sid)
{
  struct cps_conn *conn = CPS_CONN (fd);

  conn->sid = sid;
  conn->next = thread->server;
  conn->prev = &thread->server;
  LB_TIME (conn->last);
  if (thread->server >= 0)
    CPS_CONN (thread->server)->prev = &conn->next;
  thread->server = fd;
}

inline static void
cps_add_conn (struct cps_thread *thread, int fd, int size,
              struct timespec *begin)
{
  struct cps_conn *conn = CPS_CONN (fd);

  conn->size = size;
  conn->last = *begin;
  conn->next = thread->conn;
  conn->prev = &thread->conn;
  if (thread->conn >= 0)
    CPS_CONN (thread->conn)->prev = &conn->next;
  thread->conn = fd;

  if (++thread->conn_num > CPS_CNT_ITEM (thread, CPS_CNT_CONN_MAX))
    CPS_CNT_ITEM (thread, CPS_CNT_CONN_MAX) = thread->conn_num;
  CPS_REC_TIMED_INC (thread, CPS_REC_CONN, conn->last);
}

inline static void
cps_rem_conn (struct cps_thread *thread, int fd, struct cps_conn *conn)
{
  --thread->conn_num;

  *conn->prev = conn->next;
  if (conn->next >= 0)
    CPS_CONN (conn->next)->prev = conn->prev;
}

inline static struct cps_thread *
cps_new_thread ()
{
  struct cps_thread *thread = calloc (1, sizeof (struct cps_thread));

  if (thread)
    {
      thread->index = cps.thread_num;
      thread->epfd = -1;
      thread->core = -1;
      thread->conn = -1;
      thread->server = -1;

      cps.thread[cps.thread_num++] = thread;
    }

  return thread;
}

#endif /* #ifndef _CPS_H_ */