Merge branch 'release-0.3' into develop
[archipelago] / xseg / peers / user / bench-xseg.h
index 70aadc8..bd2e0b6 100644 (file)
  * 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
@@ -57,13 +133,24 @@ struct bench {
        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
@@ -88,64 +175,50 @@ struct timer {
        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);