Fix flag handling of struct bench
[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 #define MAX_ARG_LEN 10
36
37 #define TM_SANE 0
38 #define TM_ECCENTRIC 1
39 #define TM_MANIC 2
40 #define TM_PARANOID 3
41
42 /*
43  * Pattern type occupies first flag bit.
44  * If 1, it's synchronous, if 0, it's random.
45  */
46 #define PATTERN_FLAG 0
47 #define IO_SEQ 0 << PATTERN_FLAG
48 #define IO_RAND 1 << PATTERN_FLAG
49
50 /*
51  * FIXME: The following are variables and definitions used to name objects and
52  * seed the lfsr. They can be handled more elegantly (e.g. be a member of a
53  * struct.)
54  */
55 #define IDLEN 15
56 #define TARGETLEN (IDLEN + 17)
57 extern char global_id[IDLEN];
58 extern uint64_t global_seed;
59
60 struct bench {
61         uint64_t to; //Total number of objects (not for read/write)
62         uint64_t ts; //Total I/O size
63         uint64_t os; //Object size
64         uint64_t bs; //Block size
65         uint64_t max_requests; //Max number of requests for a benchmark
66         uint32_t iodepth; //Num of in-flight xseg reqs
67         int insanity;
68         xport dst_port;
69         xport src_port;
70         uint32_t op;    //xseg operation
71         uint8_t flags;
72         struct peerd *peer;
73         struct lfsr *lfsr;
74         struct timer *total_tm; //Total time for benchmark
75         struct timer *get_tm;   //Time for xseg_get_request
76         struct timer *sub_tm;   //Time for xseg_submit_request
77         struct timer *rec_tm;   //Time for xseg_receive_request
78 };
79
80 /*
81  * Custom timespec. Made to calculate variance, where we need the square of a
82  * timespec struct. This struct should be more than enough to hold the square
83  * of the biggest timespec.
84  */
85 struct timespec2 {
86         unsigned long tv_sec2;
87         uint64_t tv_nsec2;
88 };
89
90 /*
91  * struct timer fields
92  * ====================
93  * completed: number of completed requests
94  * start_time: submission time of a request
95  * sum: the sum of elapsed times of every completed request
96  * sum_sq: the sum of the squares of elapsed times
97  * insanity: benchmarking level, higher means that the request associated with
98  *           this timer is more trivial.
99  */
100 struct timer {
101         struct timespec sum;
102         struct timespec2 sum_sq;
103         struct timespec start_time;
104         uint32_t completed;
105         unsigned int insanity;
106 };
107
108 struct tm_result {
109         unsigned long s;
110         unsigned long ms;
111         unsigned long us;
112         unsigned long ns;
113 };
114
115 /* FILLME
116 struct signature {
117         //target's name
118         //οffset
119         //hash of data (heavy)
120 };
121 */
122
123
124 int custom_peerd_loop(void *arg);
125
126 void timer_start(struct bench *prefs, struct timer *sample_req);
127 void timer_stop(struct bench *prefs, struct timer *sample_tm,
128                 struct timespec *start);
129 int init_timer(struct timer **tm, int insanity);
130 uint64_t str2num(char *str);
131 int read_op(char *op);
132 int read_pattern(char *pattern);
133 void print_res(struct tm_result res, char *type);
134 void separate_by_order(struct timespec src, struct tm_result *res);
135 void create_target(struct bench *prefs, struct xseg_request *req,
136                 uint64_t new);
137 void create_chunk(struct bench *prefs, struct xseg_request *req,
138                 uint64_t new);
139 uint64_t determine_next(struct bench *prefs);
140 void create_id();
141 int read_insanity(char *insanity);
142
143 /**************\
144  * LFSR stuff *
145 \**************/
146
147 struct lfsr {
148         uint8_t length;
149         uint64_t limit;
150         uint64_t state;
151         uint64_t xnormask;
152 };
153
154 int lfsr_init(struct lfsr *lfsr, uint64_t size, uint64_t seed);
155
156 /*
157  * This loop generates each time a new pseudo-random number. However, if it's
158  * bigger than what we want, we discard it and generate the next one.
159  */
160 static inline uint64_t lfsr_next(struct lfsr *lfsr)
161 {
162         do {
163                 lfsr->state = (lfsr->state >> 1) ^
164                         (((lfsr->state & 1UL) - 1UL) & lfsr->xnormask);
165         } while (lfsr->state > lfsr->limit);
166
167         return lfsr->state;
168 }
169