* or implied, of GRNET S.A.
*/
+#include <bench-lfsr.h>
+
+
+#ifdef __GNUC__
+#define LIKELY(x) __builtin_expect(!!(x),1)
+#define UNLIKELY(x) __builtin_expect(!!(x),0)
+#else
+#define LIKELY(x) (x)
+#define UNLIKELY(x) (x)
+#endif
+
+/*
+ * If CLOCK_MONOTONIC_RAW is not defined in our system, use CLOCK_MONOTONIC
+ * instead. CLOCK_MONOTONIC_RAW is preferred since we are guaranteed that the
+ * clock won't skew.
+ */
+#ifdef CLOCK_MONOTONIC_RAW
+#define CLOCK_BENCH CLOCK_MONOTONIC_RAW
+#else
+#define CLOCK_BENCH CLOCK_MONOTONIC
+#endif
+
+
#define MAX_ARG_LEN 10
-//It's "bench-uint32_t" which means 16 characters at most
-#define TARGETLEN = 16
-#define TM_SANE 0
-#define TM_ECCENTRIC 1
-#define TM_MANIC 2
-#define TM_PARANOID 3
+/*
+ * Pattern type occupies 1st flag bit.
+ * If 1, it's sequential, if 0, it's random.
+ */
+#define PATTERN_FLAG_POS 0
+#define PATTERN_BITMASK 1
+#define PATTERN_SEQ 0
+#define PATTERN_RAND 1
+
+/*
+ * Verify mode occupies 2nd and 3rd flag bit.
+ * If 01, it uses metadata for verification, if 11 it writes pseudorandom nums
+ * in chunk's memory range and if 00, it's off.
+ */
+#define VERIFY_FLAG_POS 1
+#define VERIFY_BITMASK 3 /* i.e. "11" in binary form */
+#define VERIFY_NO 0
+#define VERIFY_META 1
+#define VERIFY_FULL 2
+
+/* Timer insanity occupies 4th and 5th flag bit */
+#define INSANITY_FLAG_POS 3
+#define INSANITY_BITMASK 3 /* i.e. "11" in binary form */
+#define INSANITY_SANE 0
+#define INSANITY_ECCENTRIC 1
+#define INSANITY_MANIC 2
+#define INSANITY_PARANOID 3
+
+/* Progress bar option occupies 6th flag bit */
+#define PROGRESS_FLAG_POS 5
+#define PROGRESS_BITMASK 1 /* i.e. "11" in binary form */
+#define PROGRESS_NO 0
+#define PROGRESS_YES 1
+
+/*
+ * Current bench flags representation:
+ * 64 7 6 5 4 3 2 1 : bits
+ * ...0 0 0 0 0 0 0
+ * |_||____||____||_|
+ * ^ ^ ^ ^
+ * | | | |
+ * | insanity | pattern
+ * progress verify
+ */
+
+/*
+ * Find position of flag, make it zero, get requested flag value, store it to
+ * this position
+ */
+#define SET_FLAG(__ftype, __flag, __val) \
+ __flag = (__flag & ~(__ftype##_BITMASK << __ftype##_FLAG_POS)) | \
+ (__val << __ftype##_FLAG_POS);
+
+/* Apply bitmask to flags, shift result to the right to get correct value */
+#define GET_FLAG(__ftype, __flag) \
+ (__flag & (__ftype##_BITMASK << __ftype##_FLAG_POS)) >> __ftype##_FLAG_POS
/*
- * Pattern type occupies first flag bit.
- * If 1, it's synchronous, if 0, it's random.
+ * The benchark ID (IDLEN) is global for the test, calculated once and is a
+ * string of the following form: {"bench-" + 9-digit number + "\0"}.
+ * The target string (TARGETLEN) is per object, concatenated with the string
+ * above and is of the following form: {"-" +16-digit number}.
*/
-#define PATTERN_FLAG 0
-#define IO_SYNC 0
-#define IO_RAND 1
+#define IDLEN 15
+#define TARGETLEN (IDLEN + 1 + 16)
+extern char global_id[IDLEN + 1];
struct bench {
+ uint64_t to; //Total number of objects (not for read/write)
uint64_t ts; //Total I/O size
uint64_t os; //Object size
uint64_t bs; //Block size
xport dst_port;
xport src_port;
uint32_t op; //xseg operation
- uint8_t flags;
+ uint64_t flags;
+ struct peerd *peer;
+ struct req_status *status;
+ struct bench_lfsr *lfsr;
struct timer *total_tm; //Total time for benchmark
struct timer *get_tm; //Time for xseg_get_request
struct timer *sub_tm; //Time for xseg_submit_request
struct timer *rec_tm; //Time for xseg_receive_request
};
+struct req_status {
+ uint64_t max; /* Max requests for benchmark */
+ uint64_t submitted;
+ uint64_t received;
+ uint64_t corrupted; /* Requests that did not pass verification */
+ uint64_t failed;
+};
+
/*
* Custom timespec. Made to calculate variance, where we need the square of a
* timespec struct. This struct should be more than enough to hold the square
struct timespec sum;
struct timespec2 sum_sq;
struct timespec start_time;
- uint32_t completed;
- unsigned int insanity;
+ uint64_t completed;
+ int insanity;
};
struct tm_result {
- unsigned long s;
- unsigned long ms;
- unsigned long us;
- unsigned long ns;
+ unsigned int s;
+ unsigned int ms;
+ unsigned int us;
+ unsigned int ns;
};
struct signature {
- //target's name
- //οffset
- //hash of data (heavy)
+ uint64_t id;
+ uint64_t object;
+ uint64_t offset;
};
+struct bw {
+ double val;
+ char unit[5];
+};
-int custom_peerd_loop(void *arg);
+int bench_peerd_loop(void *arg);
-void timer_start(struct timer *sample_req);
-void timer_stop(struct timer *sample_tm, struct timespec *start);
+void timer_start(struct bench *prefs, struct timer *sample_req);
+void timer_stop(struct bench *prefs, struct timer *sample_tm,
+ struct timespec *start);
int init_timer(struct timer **tm, int insanity);
uint64_t str2num(char *str);
int read_op(char *op);
int read_pattern(char *pattern);
-void print_res(struct tm_result res, char *type);
-void separate_by_order(struct timespec src, struct tm_result *res);
+int read_insanity(char *insanity);
+int read_verify(char *insanity);
+int read_progress(char *progress);
+void print_res(struct bench *prefs, struct timer *tm, char *type);
+void print_stats(struct bench *prefs);
+void print_progress(struct bench *prefs);
+void print_remaining(struct bench *prefs);
void create_target(struct bench *prefs, struct xseg_request *req,
uint64_t new);
-void create_chunk(struct bench *prefs, struct xseg_request *req,
- uint64_t new);
+void create_chunk(struct bench *prefs, struct xseg_request *req, uint64_t new);
+int read_chunk(struct bench *prefs, struct xseg_request *req);
uint64_t determine_next(struct bench *prefs);
-
-/**************\
- * LFSR stuff *
-\**************/
-
-struct lfsr {
- uint8_t length;
- uint64_t limit;
- uint64_t state;
- uint64_t xnormask;
-};
-
-int lfsr_init(struct lfsr *lfsr, uint64_t size, uint64_t seed);
-
-/*
- * This loop generates each time a new pseudo-random number. However, if it's
- * bigger than what we want, we discard it and generate the next one.
- */
-static inline uint64_t lfsr_next(struct lfsr *lfsr)
-{
- do {
- lfsr->state = (lfsr->state >> 1) ^
- (((lfsr->state & 1UL) - 1UL) & lfsr->xnormask);
- } while (lfsr->state > lfsr->limit);
-
- return lfsr->state;
-}
+uint64_t calculate_offset(struct bench *prefs, uint64_t new);
+uint64_t calculate_prog_quantum(struct bench *prefs);
+void create_id(unsigned long seed);