return -1;
}
+int read_progress(char *progress)
+{
+ if (strncmp(progress, "no", MAX_ARG_LEN + 1) == 0)
+ return PROGRESS_NO;
+ if (strncmp(progress, "yes", MAX_ARG_LEN + 1) == 0)
+ return PROGRESS_YES;
+ return -1;
+}
+
int read_pattern(char *pattern)
{
if (strncmp(pattern, "seq", MAX_ARG_LEN + 1) == 0)
void print_stats(struct bench *prefs)
{
- uint64_t remaining;
-
- printf("\n");
- printf("Requests total: %10lu\n", prefs->status->max);
- printf("Requests submitted: %10lu\n", prefs->status->submitted);
- printf("Requests received: %10lu\n", prefs->status->received);
- printf("Requests failed: %10lu\n", prefs->status->failed);
+ printf("\n"
+ "Requests total: %10lu\n"
+ "Requests submitted: %10lu\n"
+ "Requests received: %10lu\n"
+ "Requests failed: %10lu\n",
+ prefs->status->max,
+ prefs->status->submitted,
+ prefs->status->received,
+ prefs->status->failed);
if ((prefs->op == X_READ) && (GET_FLAG(VERIFY, prefs->flags) != VERIFY_NO))
printf("Requests corrupted: %10lu\n", prefs->status->corrupted);
printf("\n");
+}
+
+void print_remaining(struct bench *prefs)
+{
+ uint64_t remaining;
remaining = prefs->status->max - prefs->status->received;
if (remaining)
//TODO: Add std
}
+void print_progress(struct bench *prefs)
+{
+ int lines = 6;
+
+ if ((prefs->op == X_READ) && (GET_FLAG(VERIFY, prefs->flags) != VERIFY_NO))
+ lines++;
+
+ printf("\033[%dA\033[J", lines);
+ print_stats(prefs);
+}
+
/**************************\
* Benchmarking functions *
\**************************/
return 0;
}
+uint64_t calculate_prog_quantum(struct bench *prefs)
+{
+ return round((double)prefs->status->max / 20.0);
+}
+
+
/*
* ***********************************************
* `create_chunk` handles 3 identifiers:
* a) If in-flight requests are less than given iodepth
* b) If we have submitted all of the requests
*/
-#define CAN_SEND_REQUEST(prefs) \
- ((prefs->status->submitted - prefs->status->received < prefs->iodepth) && \
- (prefs->status->submitted < prefs->status->max))
+#define CAN_SEND_REQUEST(__p) \
+ ((__p->status->submitted - __p->status->received < __p->iodepth) && \
+ (__p->status->submitted < __p->status->max) && \
+ !isTerminate())
-#define CAN_VERIFY(prefs) \
- ((GET_FLAG(VERIFY, prefs->flags) != VERIFY_NO) && prefs->op == X_READ)
+#define CAN_VERIFY(__p) \
+ ((GET_FLAG(VERIFY, __p->flags) != VERIFY_NO) && __p->op == X_READ)
+
+#define CAN_PRINT_PROGRESS(__p, __q) \
+ ((GET_FLAG(PROGRESS, __p->flags) == PROGRESS_YES) && \
+ (__p->status->received == __q))
void custom_peer_usage()
{
" --seed | None | Initialize LFSR and target names\n"
" --insanity| sane | Adjust insanity level of benchmark:\n"
" | | [sane|eccentric|manic|paranoid]\n"
+ " --progress| yes | Show progress of requests\n"
"\n"
"Additional information:\n"
" --------------------------------------------\n"
char pattern[MAX_ARG_LEN + 1];
char insanity[MAX_ARG_LEN + 1];
char verify[MAX_ARG_LEN + 1];
+ char progress[MAX_ARG_LEN + 1];
struct xseg *xseg = peer->xseg;
unsigned int xseg_page_size = 1 << xseg->config.page_shift;
long iodepth = -1;
insanity[0] = 0;
verify[0] = 0;
request_cap[0] = 0;
+ progress[0] = 0;
#ifdef MT
for (i = 0; i < nr_threads; i++) {
READ_ARG_ULONG("--seed", seed);
READ_ARG_STRING("--insanity", insanity, MAX_ARG_LEN);
READ_ARG_STRING("--verify", verify, MAX_ARG_LEN);
+ READ_ARG_STRING("--progress", progress, MAX_ARG_LEN);
END_READ_ARGS();
/*****************************\
}
}
- /****************************\
- * Finalize initializations *
- \****************************/
+ /*********************************\
+ * Miscellaneous initializations *
+ \*********************************/
/* The request cap must be enforced only after the LFSR is initialized */
if (request_cap[0]) {
prefs->status->max = rc;
}
+ /* Benchmarking progress printing is on by default */
+ if (!progress[0])
+ strcpy(progress, "yes");
+ r = read_progress(progress);
+ if (r < 0) {
+ XSEGLOG2(&lc, E, "Invalid syntax: --progress %s\n", progress);
+ goto arg_fail;
+ }
+ SET_FLAG(PROGRESS, prefs->flags, r);
+
prefs->peer = peer;
peer->peerd_loop = bench_peerd_loop;
peer->priv = (void *) prefs;
struct bench *prefs = peer->priv;
xport portno_start = peer->portno_start;
xport portno_end = peer->portno_end;
- uint64_t threshold=1000/(1 + portno_end - portno_start);
pid_t pid = syscall(SYS_gettid);
+ uint64_t threshold=1000/(1 + portno_end - portno_start);
+ uint64_t cached_prog_quantum = 0;
+ uint64_t prog_quantum = 0;
int r;
uint64_t loops;
+ if (GET_FLAG(PROGRESS, prefs->flags) == PROGRESS_YES) {
+ prog_quantum = calculate_prog_quantum(prefs);
+ cached_prog_quantum = prog_quantum;
+ print_stats(prefs);
+ }
+
XSEGLOG2(&lc, I, "%s has tid %u.\n",id, pid);
xseg_init_local_signal(xseg, peer->portno_start);
timer_start(prefs, prefs->total_tm);
send_request:
- while (!isTerminate()) {
-#ifdef MT
- if (t->func) {
- XSEGLOG2(&lc, D, "%s executes function\n", id);
- xseg_cancel_wait(xseg, peer->portno_start);
- t->func(t->arg);
- t->func = NULL;
- t->arg = NULL;
- continue;
- }
-#endif
+ while (!(isTerminate() && all_peer_reqs_free(peer))) {
while (CAN_SEND_REQUEST(prefs)) {
xseg_cancel_wait(xseg, peer->portno_start);
XSEGLOG2(&lc, D, "...because %lu < %lu && %lu < %lu\n",
if (loops == 1)
xseg_prepare_wait(xseg, peer->portno_start);
+ if (UNLIKELY(CAN_PRINT_PROGRESS(prefs, prog_quantum))) {
+ prog_quantum += cached_prog_quantum;
+ print_progress(prefs);
+ }
+
if (check_ports(peer)) {
//If an old request has just been acked, the most sensible
//thing to do is to immediately send a new one
//XSEGLOG2(&lc, I, "%s goes to sleep with %u requests pending\n",
// id, xq_count(q));
XSEGLOG2(&lc, I, "%s goes to sleep\n", id);
-#ifdef ST_THREADS
- if (ta){
- st_sleep(0);
- continue;
- }
-#endif
xseg_wait_signal(xseg, 10000000UL);
xseg_cancel_wait(xseg, peer->portno_start);
XSEGLOG2(&lc, I, "%s woke up\n", id);
if (!prefs->total_tm->completed)
timer_stop(prefs, prefs->total_tm, NULL);
- print_stats(prefs);
+ if (GET_FLAG(PROGRESS, prefs->flags) == PROGRESS_YES)
+ print_progress(prefs);
+ else
+ print_stats(prefs);
+
+ print_remaining(prefs);
print_res(prefs, prefs->total_tm, "Total Requests");
return;
}
#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
#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
- * verify
+ * |_||____||____||_|
+ * ^ ^ ^ ^
+ * | | | |
+ * | insanity | pattern
+ * progress verify
+ */
+
+/*
+ * Find position of flag, make it zero, get requested flag value, store it to
+ * this position
*/
-/* Add flag bit according to its position */
#define SET_FLAG(__ftype, __flag, __val) \
- __flag |= __val << __ftype##_FLAG_POS;
+ __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
+
/*
* The benchark ID (IDLEN) is global for the test, calculated once and is a
* string of the following form: {"bench-" + 9-digit number + "\0"}.
uint64_t offset;
};
-
int bench_peerd_loop(void *arg);
void timer_start(struct bench *prefs, struct timer *sample_req);
int read_pattern(char *pattern);
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);
int read_chunk(struct bench *prefs, struct xseg_request *req);
uint64_t determine_next(struct bench *prefs);
uint64_t calculate_offset(struct bench *prefs, uint64_t new);
+uint64_t calculate_prog_quantum(struct bench *prefs);
void create_id(unsigned long seed);