Split peer request queues.
[archipelago] / xseg / peers / user / bench-xseg.h
1 /*
2  * Copyright 2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include <bench-lfsr.h>
36
37 #define MAX_ARG_LEN 10
38
39 /*
40  * Pattern type occupies 1st flag bit.
41  * If 1, it's sequential, if 0, it's random.
42  */
43 #define PATTERN_FLAG_POS 0
44 #define PATTERN_BITMASK 1
45 #define PATTERN_SEQ 0
46 #define PATTERN_RAND 1
47
48 /*
49  * Verify mode occupies 2nd and 3rd flag bit.
50  * If 01, it uses metadata for verification, if 11 it writes pseudorandom nums
51  * in chunk's memory range and if 00, it's off.
52  */
53 #define VERIFY_FLAG_POS 1
54 #define VERIFY_BITMASK 3        /* i.e. "11" in binary form */
55 #define VERIFY_NO 0
56 #define VERIFY_META 1
57 #define VERIFY_FULL 2
58
59 /* Timer insanity occupies 4th and 5th flag bit */
60 #define INSANITY_FLAG_POS 3
61 #define INSANITY_BITMASK 3      /* i.e. "11" in binary form */
62 #define INSANITY_SANE 0
63 #define INSANITY_ECCENTRIC 1
64 #define INSANITY_MANIC 2
65 #define INSANITY_PARANOID 3
66
67
68 /*
69  * Current bench flags representation:
70  * 64 7  6  5  4  3  2  1 : bits
71  * ...0  0  0  0  0  0  0
72  *         |____||____||_|
73  *                        ^         ^   ^
74  *                        |             |   |
75  *                 insanity     | pattern
76  *                               verify
77  */
78 /* Add flag bit according to its position */
79 #define SET_FLAG(__ftype, __flag, __val)        \
80         __flag |= __val << __ftype##_FLAG_POS;
81
82 /* Apply bitmask to flags, shift result to the right to get correct value */
83 #define GET_FLAG(__ftype, __flag)                       \
84         (__flag & (__ftype##_BITMASK << __ftype##_FLAG_POS)) >> __ftype##_FLAG_POS
85 /*
86  * The benchark ID (IDLEN) is global for the test, calculated once and is a
87  * string of the following form: {"bench-" + 9-digit number + "\0"}.
88  * The target string (TARGETLEN) is per object, concatenated with the string
89  * above and is of the following form: {"-" +16-digit number + "\0"}.
90  */
91 #define IDLEN 16
92 #define TARGETLEN (IDLEN + 17)
93 extern char global_id[IDLEN];
94
95 struct bench {
96         uint64_t to; //Total number of objects (not for read/write)
97         uint64_t ts; //Total I/O size
98         uint64_t os; //Object size
99         uint64_t bs; //Block size
100         uint32_t iodepth; //Num of in-flight xseg reqs
101         xport dst_port;
102         xport src_port;
103         uint32_t op;    //xseg operation
104         uint64_t flags;
105         struct peerd *peer;
106         struct req_status *status;
107         struct bench_lfsr *lfsr;
108         struct timer *total_tm; //Total time for benchmark
109         struct timer *get_tm;   //Time for xseg_get_request
110         struct timer *sub_tm;   //Time for xseg_submit_request
111         struct timer *rec_tm;   //Time for xseg_receive_request
112 };
113
114 struct req_status {
115         uint64_t max;           /* Max requests for benchmark */
116         uint64_t submitted;
117         uint64_t received;
118         uint64_t corrupted;     /* Requests that did not pass verification */
119         uint64_t failed;
120 };
121
122 /*
123  * Custom timespec. Made to calculate variance, where we need the square of a
124  * timespec struct. This struct should be more than enough to hold the square
125  * of the biggest timespec.
126  */
127 struct timespec2 {
128         unsigned long tv_sec2;
129         uint64_t tv_nsec2;
130 };
131
132 /*
133  * struct timer fields
134  * ====================
135  * completed: number of completed requests
136  * start_time: submission time of a request
137  * sum: the sum of elapsed times of every completed request
138  * sum_sq: the sum of the squares of elapsed times
139  * insanity: benchmarking level, higher means that the request associated with
140  *           this timer is more trivial.
141  */
142 struct timer {
143         struct timespec sum;
144         struct timespec2 sum_sq;
145         struct timespec start_time;
146         uint64_t completed;
147         int insanity;
148 };
149
150 struct tm_result {
151         unsigned int s;
152         unsigned int ms;
153         unsigned int us;
154         unsigned int ns;
155 };
156
157 struct signature {
158         uint64_t id;
159         uint64_t object;
160         uint64_t offset;
161 };
162
163
164 int bench_peerd_loop(void *arg);
165
166 void timer_start(struct bench *prefs, struct timer *sample_req);
167 void timer_stop(struct bench *prefs, struct timer *sample_tm,
168                 struct timespec *start);
169 int init_timer(struct timer **tm, int insanity);
170 uint64_t str2num(char *str);
171 int read_op(char *op);
172 int read_pattern(char *pattern);
173 int read_insanity(char *insanity);
174 int read_verify(char *insanity);
175 void print_res(struct bench *prefs, struct timer *tm, char *type);
176 void print_stats(struct bench *prefs);
177 void create_target(struct bench *prefs, struct xseg_request *req,
178                 uint64_t new);
179 void create_chunk(struct bench *prefs, struct xseg_request *req, uint64_t new);
180 int read_chunk(struct bench *prefs, struct xseg_request *req);
181 uint64_t determine_next(struct bench *prefs);
182 uint64_t calculate_offset(struct bench *prefs, uint64_t new);
183 void create_id(unsigned long seed);
184